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

📄 flex_string_shell.h

📁 < Modern C++ Design>>即<<C++设计新思维>>源码.
💻 H
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////// 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 FLEX_STRING_SHELL_INC_#define FLEX_STRING_SHELL_INC_// $Id: flex_string_shell.h 754 2006-10-17 19:59:11Z syntheticpp $///////////////////////////////////////////////////////////////////////////////// class template flex_string// This file does not include any storage policy headers///////////////////////////////////////////////////////////////////////////////#include <memory>#include <algorithm>#include <functional>#include <cassert>#include <limits>#include <stdexcept>#include "flex_string_details.h"#include <string>// Forward declaration for default storage policytemplate <typename E, class A> class AllocatorStringStorage;template <class T> class mallocator{public:    typedef T                 value_type;    typedef value_type*       pointer;    typedef const value_type* const_pointer;    typedef value_type&       reference;    typedef const value_type& const_reference;    typedef std::size_t       size_type;    //typedef unsigned int      size_type;    //typedef std::ptrdiff_t    difference_type;    typedef int               difference_type;    template <class U>     struct rebind { typedef mallocator<U> other; };    mallocator() {}    mallocator(const mallocator&) {}    //template <class U>     //mallocator(const mallocator<U>&) {}    ~mallocator() {}    pointer address(reference x) const { return &x; }    const_pointer address(const_reference x) const     {         return x;    }    pointer allocate(size_type n, const_pointer = 0)     {        using namespace std;        void* p = malloc(n * sizeof(T));        if (!p) throw bad_alloc();        return static_cast<pointer>(p);    }    void deallocate(pointer p, size_type)     {         using namespace std;        free(p);     }    size_type max_size() const     {         return static_cast<size_type>(-1) / sizeof(T);    }    void construct(pointer p, const value_type& x)     {         new(p) value_type(x);     }    void destroy(pointer p)     {         p->~value_type();     }private:    void operator=(const mallocator&);};template<> class mallocator<void>{  typedef void        value_type;  typedef void*       pointer;  typedef const void* const_pointer;  template <class U>   struct rebind { typedef mallocator<U> other; };};template <class T>inline bool operator==(const mallocator<T>&,                        const mallocator<T>&) {  return true;}template <class T>inline bool operator!=(const mallocator<T>&,                        const mallocator<T>&) {  return false;}template <class Allocator>typename Allocator::pointer Reallocate(    Allocator& alloc,    typename Allocator::pointer p,     typename Allocator::size_type oldObjCount,    typename Allocator::size_type newObjCount,    void*){    // @@@ not implemented}template <class Allocator>typename Allocator::pointer Reallocate(    Allocator& alloc,    typename Allocator::pointer p,     typename Allocator::size_type oldObjCount,    typename Allocator::size_type newObjCount,    mallocator<void>*){    // @@@ not implemented}////////////////////////////////////////////////////////////////////////////////// class template flex_string// a std::basic_string compatible implementation // Uses a Storage policy ////////////////////////////////////////////////////////////////////////////////template <typename E,    class T = std::char_traits<E>,    class A = std::allocator<E>,    class Storage = AllocatorStringStorage<E, A> >class flex_string : private Storage{    template <typename Exception>    static void Enforce(bool condition, Exception*, const char* msg)    { if (!condition) throw Exception(msg); }    bool Sane() const    {        return            begin() <= end() &&            empty() == (size() == 0) &&            empty() == (begin() == end()) &&            size() <= max_size() &&            capacity() <= max_size() &&            size() <= capacity();    }    struct Invariant;    friend struct Invariant;    struct Invariant    {#ifndef NDEBUG        Invariant(const flex_string& s) : s_(s)        {            assert(s_.Sane());        }        ~Invariant()        {            assert(s_.Sane());        }    private:        const flex_string& s_;#else        Invariant(const flex_string&) {} #endif    Invariant& operator=(const Invariant&);    };    public:    // types    typedef T traits_type;    typedef typename traits_type::char_type value_type;    typedef A allocator_type;    typedef typename A::size_type size_type;    typedef typename A::difference_type difference_type;        typedef typename Storage::reference reference;    typedef typename A::const_reference const_reference;    typedef typename A::pointer pointer;    typedef typename A::const_pointer const_pointer;        typedef typename Storage::iterator iterator;    typedef typename Storage::const_iterator const_iterator;    typedef std::reverse_iterator<iterator#ifdef NO_ITERATOR_TRAITS    , value_type#endif    > reverse_iterator;    typedef std::reverse_iterator<const_iterator#ifdef NO_ITERATOR_TRAITS    , const value_type #endif    > const_reverse_iterator;    static const size_type npos;    // = size_type(-1)private:    static size_type Min(size_type lhs, size_type rhs)    { return lhs < rhs ? lhs : rhs; }    static size_type Max(size_type lhs, size_type rhs)    { return lhs > rhs ? lhs : rhs; }    static void Procust(size_type& n, size_type nmax)    { if (n > nmax) n = nmax; }    public:        // 21.3.1 construct/copy/destroy    explicit flex_string(const A& a = A())    : Storage(a)     {}        flex_string(const flex_string& str)    : Storage(str)     {}        flex_string(const flex_string& str, size_type pos,         size_type n = npos, const A& a = A())    : Storage(a)     {        assign(str, pos, n);    }        flex_string(const value_type* s, const A& a = A())    : Storage(s, traits_type::length(s), a)    {}        flex_string(const value_type* s, size_type n, const A& a = A())    : Storage(s, n, a)    {}        flex_string(size_type n, value_type c, const A& a = A())    : Storage(n, c, a)    {}    template <class InputIterator>    flex_string(InputIterator begin, InputIterator end, const A& a = A())    : Storage(a)    {        assign(begin, end);    }    ~flex_string()    {}        flex_string& operator=(const flex_string& str)    {        Storage& s = *this;        s = str;        return *this;    }           flex_string& operator=(const value_type* s)    {        assign(s);        return *this;    }    flex_string& operator=(value_type c)    {        assign(1, c);        return *this;    }        // 21.3.2 iterators:    iterator begin()    { return Storage::begin(); }        const_iterator begin() const    { return Storage::begin(); }        iterator end()    { return Storage::end(); }        const_iterator end() const    { return Storage::end(); }    reverse_iterator rbegin()    { return reverse_iterator(end()); }        const_reverse_iterator rbegin() const    { return const_reverse_iterator(end()); }        reverse_iterator rend()    { return reverse_iterator(begin()); }        const_reverse_iterator rend() const    { return const_reverse_iterator(begin()); }        // 21.3.3 capacity:    size_type size() const    { return Storage::size(); }        size_type length() const    { return size(); }        size_type max_size() const    { return Storage::max_size(); }    void resize(size_type n, value_type c)    { Storage::resize(n, c); }        void resize(size_type n)    { resize(n, value_type()); }        size_type capacity() const    { return Storage::capacity(); }        void reserve(size_type res_arg = 0)    {        Enforce(res_arg <= max_size(), static_cast<std::length_error*>(0), "");        Storage::reserve(res_arg);    }        void clear()    { resize(0); }         bool empty() const    { return size() == 0; }        // 21.3.4 element access:    const_reference operator[](size_type pos) const    { return *(c_str() + pos); }        reference operator[](size_type pos)    { return *(begin() + pos); }    const_reference at(size_type n) const    {        Enforce(n <= size(), static_cast<std::out_of_range*>(0), "");        return (*this)[n];    }        reference at(size_type n)    {        Enforce(n < size(), static_cast<std::out_of_range*>(0), "");        return (*this)[n];    }        // 21.3.5 modifiers:    flex_string& operator+=(const flex_string& str)    { return append(str); }        flex_string& operator+=(const value_type* s)    { return append(s); }    flex_string& operator+=(const value_type c)    {         push_back(c);        return *this;    }        flex_string& append(const flex_string& str)    { return append(str.data(), str.length()); }        flex_string& append(const flex_string& str, const size_type pos,        size_type n)    {         const size_type sz = str.size();        Enforce(pos <= sz, static_cast<std::out_of_range*>(0), "");        Procust(n, sz - pos);        return append(str.data() + pos, n);     }        flex_string& append(const value_type* s, const size_type n)    {         Invariant checker(*this);         (void) checker;         static std::less_equal<const value_type*> le;        if (le(&*begin(), s) && le(s, &*end())) // aliasing        {            const size_type offset = s - &*begin();            Storage::reserve(size() + n);            s = &*begin() + offset;        }        Storage::append(s, s + n);         return *this;    }        flex_string& append(const value_type* s)    { return append(s, traits_type::length(s)); }        flex_string& append(size_type n, value_type c)    {         resize(size() + n, c);        return *this;    }        template<class InputIterator>    flex_string& append(InputIterator first, InputIterator last)    {        insert(end(), first, last);        return *this;    }        void push_back(const value_type c) // primitive    {         const size_type cap = capacity();        if (size() == cap)        {            reserve(cap << 1u);        }        Storage::append(&c, &c + 1);    }    flex_string& assign(const flex_string& str)    {         if (&str == this) return *this;        return assign(str.data(), str.size());    }        flex_string& assign(const flex_string& str, const size_type pos,

⌨️ 快捷键说明

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