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

📄 flex_string.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 5 页
字号:

template <typename E,
    class T = std::char_traits<E>,
    class A = std::allocator<E>,
    class Storage = AllocatorStringStorage<E, A> >
class flex_string : private Storage
{
#if defined(THROW_ON_ENFORCE)
    template <typename Exception>
    static void Enforce(bool condition, Exception*, const char* msg)
    { if (!condition) throw Exception(msg); }
#else
    template <typename Exception>
    static inline void Enforce(bool condition, Exception*, const char* msg)
    { BOOST_ASSERT(condition && msg); }
#endif // defined(THROW_ON_ENFORCE)

    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
    {
        Invariant(const flex_string& s) : s_(s)
        {
            BOOST_ASSERT(s_.Sane());
        }
        ~Invariant()
        {
            BOOST_ASSERT(s_.Sane());
        }
    private:
        const flex_string& s_;
    };
    
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 A::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 boost::reverse_iterator<iterator> reverse_iterator;
    typedef boost::reverse_iterator<const_iterator> 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; }
    
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) 
    {
        Enforce(pos <= str.size(), (std::out_of_range*)0, "");
        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)
    {
        if (this != &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(), (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 *(begin() + pos); }
    
    reference operator[](size_type pos)
    { return *(begin() + pos); }

    const_reference at(size_type n) const
    {
        Enforce(n < size(), (std::out_of_range*)0, "");
        return (*this)[n];
    }
    
    reference at(size_type n)
    {
        Enforce(n < size(), (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+=(value_type c)
    { 
        const size_type cap = capacity();
        if (size() == cap)
        {
            reserve(cap << 1u);
        }
        resize(size() + 1, c);
        return *this;
    }
    
    flex_string& append(const flex_string& str)
    { return append(str, 0, npos); }
    
    flex_string& append(const flex_string& str, size_type pos,
        size_type n)
    { 
        const size_type sz = str.size();
        Enforce(pos <= sz, (std::out_of_range*)0, "");
        return append(str.c_str() + pos, Min(n, sz - pos)); 
    }
    
    flex_string& append(const value_type* s, size_type n)
    { 
        Storage::append(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)
    {
        for (; first != last; ++first) *this += E(*first);
        return *this;
    }
*/    
    void push_back(value_type c)
    { 
        *this += c;
    }

    flex_string& assign(const flex_string& str)
    { 
        if (&str == this) return *this;
        replace(0, size(), &*str.begin(), str.size());
        return *this;
    }
    
    flex_string& assign(const flex_string& str, size_type pos,
        size_type n)
    { 
        Enforce(pos <= str.size(), (std::out_of_range*)0, "");
        return assign(str.data() + pos, Min(n, str.size() - pos));
    }
    
    flex_string& assign(const value_type* s, size_type n)
    {
        if (size() >= n)
        {
            flex_string_details::pod_move(s, s + n, &*begin());
            resize(n, value_type());
        }
        else
        {
            flex_string_details::pod_move(s, s + size(), &*begin());
            Storage::append(s + size(), n - size());
        }
        return *this;
    }
    
    flex_string& assign(const value_type* s)
    { return assign(s, traits_type::length(s)); }
    
    flex_string& assign(size_type n, value_type c)
    { return replace(begin(), end(), n, c); } 
    
    template<class InputIterator>
    flex_string& assign(InputIterator first, InputIterator last)
    { return replace(begin(), end(), first, last); }
    
    flex_string& insert(size_type pos1, const flex_string& str)
    { return insert(pos1, str, 0, npos); }
    
    flex_string& insert(size_type pos1, const flex_string& str,
        size_type pos2, size_type n)
    { return replace(pos1, 0, str, pos2, n); }
    
    flex_string& insert(size_type pos, const value_type* s, size_type n)
    { return replace(pos, 0, s, n); }
    
    flex_string& insert(size_type pos, const value_type* s)
    { return insert(pos, s, traits_type::length(s)); }
    
    flex_string& insert(size_type pos, size_type n, value_type c)
    { return replace(pos, 0, n, c); }
    
    iterator insert(iterator p, value_type c = value_type()) 
    {
        const size_type pos = p - begin();
        insert(pos, &c, 1);
        return begin() + pos;
    }
    
    void insert(iterator p, size_type n, value_type c)
    { insert(p - begin(), n, c); }
    
    template<class InputIterator>
    void insert(iterator p, InputIterator first, InputIterator last)
    { replace(p, p, first, last); }
    
    flex_string& erase(size_type pos = 0, size_type n = npos)
    { 
        return replace(pos, Min(n, size() - pos), 0, value_type()); 
    }
    
    iterator erase(iterator position)
    {
        const size_type pos(position - begin());
        erase(pos, 1);
        return begin() + pos;
    }
    
    iterator erase(iterator first, iterator last)
    {
        const size_type pos(first - begin());
        erase(pos, last - first);
        return begin() + pos;
    }

    // @@@ replace

    flex_string& replace(size_type pos1, size_type n1, const flex_string& str)
    { return replace(pos1, n1, str, 0, npos); }
    
    flex_string& replace(size_type pos1, size_type n1, const flex_string& str,
        size_type pos2, size_type n2)
    {
        Enforce(pos1 <= length() && pos2 <= str.length(), 
            (std::out_of_range*)0, "");
        return replace(pos1, n1, &*str.begin() + pos2, 
            Min(n2, str.length() - pos2));
    }
    
    flex_string& replace(const size_type d, size_type n1, const value_type* s1,
        const size_type n2)
    {
        using namespace flex_string_details;
        Enforce(d <= size(), (std::out_of_range*)0, "");
        if (d + n1 > size()) n1 = size() - d;
        const int delta = int(n2 - n1);
        static const std::less_equal<const value_type*> le = 
            std::less_equal<const value_type*>();
        const bool aliased = le(&*begin(), s1) && le(s1, &*end());

        if (delta > 0)
        {
            if (capacity() < size() + delta)
            {
                // realloc the string
                if (aliased)
                {
                    const size_type offset = s1 - &*begin();
                    reserve(size() + delta);
                    s1 = &*begin() + offset;
                }
                else
                {
                    reserve(size() + delta);
                }
            }

            const value_type* s2 = s1 + n2;
            value_type* d1 = &*begin() + d;
            value_type* d2 = d1 + n1;

            const int tailLen = int(&*end() - d2);

            if (delta <= tailLen)
            {
                value_type* oldEnd = &*end();
                // simple case
                Storage::append(oldEnd - delta, delta);

                pod_move(d2, d2 + (tailLen - delta), d2 + delta);
                if (le(d2, s1))
                {
                    if (aliased)
                    {
                        pod_copy(s1 + delta, s2 + delta, d1);
                    }
                    else
                    {
                        pod_copy(s1, s2, d1);
                    }
                }
                else
                {
                    // d2 > s1
                    if (le(d2, s2))
                    {
                        BOOST_ASSERT(aliased);
                        pod_move(s1, d2, d1);
                        pod_move(d2 + delta, s2 + delta, d1 + (d2 - s1));
                    }
                    else
                    {
                        pod_move(s1, s2, d1);
                    }
                }
            }
            else
            {
                const size_type sz = delta - tailLen;
                Storage::append(s2 - sz, sz);
                Storage::append(d2, tailLen);
                pod_move(s1, s2 - (delta - tailLen), d1);
            }
        }
        else
        {
            pod_move(s1, s1 + n2, &*begin() + d);
            pod_move(&*begin() + d + n1, &*end(), &*begin() + d + n1 + delta);
            resize(size() + delta);
        }
        return *this;
    }

    flex_string& replace(size_type pos, size_type n1, const value_type* s)
    { return replace(pos, n1, s, traits_type::length(s)); }
    
    flex_string& replace(size_type pos, size_type n1, size_type n2, 
        value_type c)
    {
        if (pos + n1 > size()) n1 = size() - pos;
        const size_type oldSize = size();
        if (pos + n2 > oldSize)
        {

⌨️ 快捷键说明

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