⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 allocatorstringstorage.h

📁 < Modern C++ Design>>即<<C++设计新思维>>源码.
💻 H
字号:
////////////////////////////////////////////////////////////////////////////////// flex_string// Copyright (c) 2001 by Andrei Alexandrescu// Permission to use, copy, modify, distribute and sell this software for any//     purpose is hereby granted without fee, provided that the above copyright//     notice appear in all copies and that both that copyright notice and this//     permission notice appear in supporting documentation.// The author makes no representations about the//     suitability of this software for any purpose. It is provided "as is"//     without express or implied warranty.////////////////////////////////////////////////////////////////////////////////#ifndef ALLOCATOR_STRING_STORAGE_INC_#define ALLOCATOR_STRING_STORAGE_INC_// $Id: allocatorstringstorage.h 754 2006-10-17 19:59:11Z syntheticpp $/* This is the template for a storage policy////////////////////////////////////////////////////////////////////////////////template <typename E, class A = @>class StoragePolicy{    typedef E value_type;    typedef @ iterator;    typedef @ const_iterator;    typedef A allocator_type;    typedef @ size_type;        StoragePolicy(const StoragePolicy& s);    StoragePolicy(const A&);    StoragePolicy(const E* s, size_type len, const A&);    StoragePolicy(size_type len, E c, const A&);    ~StoragePolicy();    iterator begin();    const_iterator begin() const;    iterator end();    const_iterator end() const;        size_type size() const;    size_type max_size() const;    size_type capacity() const;    void reserve(size_type res_arg);    template <class ForwardIterator>    void append(ForwardIterator b, ForwardIterator e);    void resize(size_type newSize, E fill);    void swap(StoragePolicy& rhs);        const E* c_str() const;    const E* data() const;        A get_allocator() const;};////////////////////////////////////////////////////////////////////////////////*/#include <memory>#include <algorithm>#include <functional>#include <cassert>#include <limits>#include <stdexcept>#include "flex_string_details.h"#include "simplestringstorage.h"////////////////////////////////////////////////////////////////////////////////// class template AllocatorStringStorage// Allocates with your allocator// Takes advantage of the Empty Base Optimization if available////////////////////////////////////////////////////////////////////////////////template <typename E, class A = std::allocator<E> >class AllocatorStringStorage : public A{    typedef typename A::size_type size_type;    typedef typename SimpleStringStorage<E, A>::Data Data;    void* Alloc(size_type sz, const void* p = 0)    {        return A::allocate(1 + (sz - 1) / sizeof(E),             static_cast<const char*>(p));    }    void* Realloc(void* p, size_type oldSz, size_type newSz)    {        void* r = Alloc(newSz);        flex_string_details::pod_copy(p, p + Min(oldSz, newSz), r);        Free(p, oldSz);        return r;    }    void Free(void* p, size_type sz)    {        A::deallocate(static_cast<E*>(p), sz);    }    Data* pData_;    void Init(size_type size, size_type cap)    {        assert(size <= cap);        if (cap == 0)        {            pData_ = const_cast<Data*>(                &SimpleStringStorage<E, A>::emptyString_);        }        else        {            pData_ = static_cast<Data*>(Alloc(                cap * sizeof(E) + sizeof(Data)));            pData_->pEnd_ = pData_->buffer_ + size;            pData_->pEndOfMem_ = pData_->buffer_ + cap;        }    }    public:    typedef E value_type;    typedef A allocator_type;    typedef typename A::pointer iterator;    typedef typename A::const_pointer const_iterator;    AllocatorStringStorage()     : A(), pData_(0)    {    }    AllocatorStringStorage(const AllocatorStringStorage& rhs)     : A(rhs.get_allocator())    {        const size_type sz = rhs.size();        Init(sz, sz);        if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());    }        AllocatorStringStorage(const AllocatorStringStorage& s,         flex_string_details::Shallow)     : A(s.get_allocator())    {        pData_ = s.pData_;    }        AllocatorStringStorage(const A& a) : A(a)    {         pData_ = const_cast<Data*>(            &SimpleStringStorage<E, A>::emptyString_);    }        AllocatorStringStorage(const E* s, size_type len, const A& a)    : A(a)    {        Init(len, len);                flex_string_details::pod_copy(s, s + len, begin());    }    AllocatorStringStorage(size_type len, E c, const A& a)    : A(a)    {        Init(len, len);        flex_string_details::pod_fill(&*begin(), &*end(), c);    }        AllocatorStringStorage& operator=(const AllocatorStringStorage& rhs)    {        const size_type sz = rhs.size();        reserve(sz);        flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());        pData_->pEnd_ = &*begin() + rhs.size();        return *this;    }        ~AllocatorStringStorage()    {        if (capacity())        {            Free(pData_,                 sizeof(Data) + capacity() * sizeof(E));        }    }            iterator begin()    { return pData_->buffer_; }        const_iterator begin() const    { return pData_->buffer_; }        iterator end()    { return pData_->pEnd_; }        const_iterator end() const    { return pData_->pEnd_; }        size_type size() const    { return size_type(end() - begin()); }    size_type max_size() const    { return A::max_size(); }    size_type capacity() const    { return size_type(pData_->pEndOfMem_ - pData_->buffer_); }    void resize(size_type n, E c)    {        reserve(n);        iterator newEnd = begin() + n;        iterator oldEnd = end();        if (newEnd > oldEnd)         {            // Copy the characters            flex_string_details::pod_fill(oldEnd, newEnd, c);        }        if (capacity()) pData_->pEnd_ = newEnd;    }    void reserve(size_type res_arg)    {        if (res_arg <= capacity())        {            // @@@ shrink to fit here             return;        }                A& myAlloc = *this;        AllocatorStringStorage newStr(myAlloc);        newStr.Init(size(), res_arg);                flex_string_details::pod_copy(begin(), end(), newStr.begin());                swap(newStr);    }    template <class ForwardIterator>    void append(ForwardIterator b, ForwardIterator e)    {        const size_type             sz = std::distance(b, e),            neededCapacity = size() + sz;        if (capacity() < neededCapacity)        {            static std::less_equal<const E*> le;            (void) le;            assert(!(le(begin(), &*b) && le(&*b, end())));            reserve(neededCapacity);        }        std::copy(b, e, end());        pData_->pEnd_ += sz;    }        void swap(AllocatorStringStorage& rhs)    {        // @@@ The following line is commented due to a bug in MSVC        //std::swap(lhsAlloc, rhsAlloc);        std::swap(pData_, rhs.pData_);    }        const E* c_str() const    {         if (pData_ != &SimpleStringStorage<E, A>::emptyString_)         {            *pData_->pEnd_ = E();        }        return &*begin();     }    const E* data() const    { return &*begin(); }        A get_allocator() const    { return *this; }};#endif // ALLOCATOR_STRING_STORAGE_INC_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -