欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

flex_string.hpp

Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
HPP
第 1 页 / 共 5 页
字号:
        flex_string_details::pod_copy(s, s + sz, end());        pData_->pEnd_ += sz;    }        template <class InputIterator>    void append(InputIterator b, InputIterator e)    {        // @@@ todo: optimize this depending on iterator type        for (; b != e; ++b)        {            *this += *b;        }    }    void resize(size_type newSize, E fill)    {        const int delta = int(newSize - size());        if (delta == 0) return;        if (delta > 0)        {            if (newSize > capacity())             {                reserve(newSize);            }            E* e = &*end();            flex_string_details::pod_fill(e, e + delta, fill);        }        pData_->pEnd_ = pData_->buffer_ + newSize;    }    void swap(SimpleStringStorage& rhs)    {        std::swap(pData_, rhs.pData_);    }        const E* c_str() const    {        if (pData_ != &emptyString_) *pData_->pEnd_ = E();        return pData_->buffer_;     }    const E* data() const    { return pData_->buffer_; }        A get_allocator() const    { return A(); }};template <typename E, class A>const typename SimpleStringStorage<E, A>::DataSimpleStringStorage<E, A>::emptyString_ = typename SimpleStringStorage<E, A>::Data();//{ //  const_cast<E*>(SimpleStringStorage<E, A>::emptyString_.buffer_), //  const_cast<E*>(SimpleStringStorage<E, A>::emptyString_.buffer_), //  { E() }//};////////////////////////////////////////////////////////////////////////////////// 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)    {        BOOST_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)        {//             typedef std::less_equal<const E*> le_type;//             BOOST_ASSERT(!(le_type()(begin(), &*b) && le_type()(&*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; }};////////////////////////////////////////////////////////////////////////////////// class template VectorStringStorage// Uses std::vector// Takes advantage of the Empty Base Optimization if available////////////////////////////////////////////////////////////////////////////////template <typename E, class A = std::allocator<E> >class VectorStringStorage : protected std::vector<E, A>{    typedef std::vector<E, A> base;public: // protected:    typedef E value_type;    typedef typename base::iterator iterator;    typedef typename base::const_iterator const_iterator;    typedef A allocator_type;    typedef typename A::size_type size_type;        VectorStringStorage(const VectorStringStorage& s) : base(s)    { }        VectorStringStorage(const A& a) : base(1, E(), a)    { }        VectorStringStorage(const E* s, size_type len, const A& a)    : base(a)    {        base::reserve(len + 1);        base::insert(base::end(), s, s + len);        // Terminating zero        base::insert(base::end(), E());    }    VectorStringStorage(size_type len, E c, const A& a)    : base(len + 1, c, a)    {        // Terminating zero        base::back() = E();    }        VectorStringStorage& operator=(const VectorStringStorage& rhs)    {        base& v = *this;        v = rhs;        return *this;    }       iterator begin()    { return base::begin(); }        const_iterator begin() const    { return base::begin(); }        iterator end()    { return base::end() - 1; }        const_iterator end() const    { return base::end() - 1; }        size_type size() const    { return base::size() - 1; }    size_type max_size() const    { return base::max_size() - 1; }    size_type capacity() const    { return base::capacity() - 1; }    void reserve(size_type res_arg)    {         BOOST_ASSERT(res_arg < max_size());        base::reserve(res_arg + 1);     }        void append(const E* s, size_type sz)    {        // Check for aliasing because std::vector doesn't do it.        static std::less_equal<const E*> le;        if (!base::empty())        {            const E* start = &base::front();            if (le(start, s) && le(s, start + size()))            {                // aliased                const size_type offset = s - start;                reserve(size() + sz);                s = &base::front() + offset;            }        }        base::insert(end(), s, s + sz);    }        template <class InputIterator>    void append(InputIterator b, InputIterator e)    {        base::insert(end(), b, e);    }    void resize(size_type n, E c)    {        base::reserve(n + 1);        base::back() = c;        base::resize(n + 1, c);        base::back() = E();    }    void swap(VectorStringStorage& rhs)    { base::swap(rhs); }        const E* c_str() const    { return &*begin(); }    const E* data() const    { return &*begin(); }        A get_allocator() const    { return base::get_allocator(); }};////////////////////////////////////////////////////////////////////////////////// class template SmallStringOpt// Builds the small string optimization over any other storage////////////////////////////////////////////////////////////////////////////////template <class Storage, unsigned int threshold,     typename Align = typename Storage::value_type*>class SmallStringOpt{public:    typedef typename Storage::value_type value_type;    typedef value_type* iterator;    typedef const value_type* const_iterator;    typedef typename Storage::allocator_type allocator_type;    typedef typename allocator_type::size_type size_type;    private:  enum { temp1 = threshold * sizeof(value_type) > sizeof(Storage)         ? threshold  * sizeof(value_type)         : sizeof(Storage) };        enum { temp2 = temp1 > sizeof(Align) ? temp1 : sizeof(Align) };public:    enum { maxSmallString =     (temp2 + sizeof(value_type) - 1) / sizeof(value_type) };    private:    enum { magic = maxSmallString + 1 };        union    {        mutable value_type buf_[maxSmallString + 1];        Align align_;    };        Storage& GetStorage()    {        BOOST_ASSERT(buf_[maxSmallString] == magic);        Storage* p = reinterpret_cast<Storage*>(&buf_[0]);        return *p;    }        const Storage& GetStorage() const    {        BOOST_ASSERT(buf_[maxSmallString] == magic);        const Storage *p = reinterpret_cast<const Storage*>(&buf_[0]);        return *p;    }        bool Small() const    {        return buf_[maxSmallString] != magic;    }        public:  SmallStringOpt(const SmallStringOpt& s)    {        if (s.Small())        {            flex_string_details::pod_copy(                s.buf_,                 s.buf_ + s.size(),                 buf_);        }        else        {            new(buf_) Storage(s.GetStorage());        }        buf_[maxSmallString] = s.buf_[maxSmallString];    }        SmallStringOpt(const allocator_type&)    {        buf_[maxSmallString] = maxSmallString;    }        SmallStringOpt(const value_type* s, size_type len, const allocator_type& a)    {        if (len <= maxSmallString)        {            flex_string_details::pod_copy(s, s + len, buf_);            buf_[maxSmallString] = value_type(maxSmallString - len);        }        else        {            new(buf_) Storage(s, len, a);            buf_[maxSmallString] = magic;        }    }

⌨️ 快捷键说明

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