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

📄 flex_string_shell.h

📁 < Modern C++ Design>>即<<C++设计新思维>>源码.
💻 H
📖 第 1 页 / 共 3 页
字号:
        size_type n)    {         const size_type sz = str.size();        Enforce(pos <= sz, static_cast<std::out_of_range*>(0), "");        Procust(n, sz - pos);        return assign(str.data() + pos, n);    }        flex_string& assign(const value_type* s, const size_type n)    {        Invariant checker(*this);         (void) checker;         if (size() >= n)        {            std::copy(s, s + n, begin());            resize(n);        }        else        {            const value_type *const s2 = s + size();            std::copy(s, s2, begin());            append(s2, n - size());        }        return *this;    }        flex_string& assign(const value_type* s)    { return assign(s, traits_type::length(s)); }        template <class ItOrLength, class ItOrChar>    flex_string& assign(ItOrLength first_or_n, ItOrChar last_or_c)    { return replace(begin(), end(), first_or_n, last_or_c); }        flex_string& insert(size_type pos1, const flex_string& str)    { return insert(pos1, str.data(), str.size()); }        flex_string& insert(size_type pos1, const flex_string& str,        size_type pos2, size_type n)    {         Enforce(pos2 <= str.length(), static_cast<std::out_of_range*>(0), "");        Procust(n, str.length() - pos2);        return insert(pos1, str.data() + pos2, n);     }        flex_string& insert(size_type pos, const value_type* s, size_type n)    {         Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");        insert(begin() + pos, s, s + n);         return *this;    }        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)    {        Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");        insert(begin() + pos, n, c);        return *this;    }        iterator insert(const iterator p, const value_type c)     {        const size_type pos = p - begin();        insert(p, 1, c);        return begin() + pos;    }    private:    template <int i> class Selector {};    flex_string& InsertImplDiscr(iterator p,         size_type n, value_type c, Selector<1>)    {         Invariant checker(*this);         (void) checker;         assert(p >= begin() && p <= end());        if (capacity() - size() < n)        {            const size_type sz = p - begin();            reserve(size() + n);            p = begin() + sz;        }        const iterator oldEnd = end();        //if (p + n < oldEnd) // replaced because of crash (pk)        if( n < size_type(oldEnd - p))        {            append(oldEnd - n, oldEnd);            //std::copy(            //    reverse_iterator(oldEnd - n),             //    reverse_iterator(p),             //    reverse_iterator(oldEnd));            flex_string_details::pod_move(&*p, &*oldEnd - n, &*p + n);            std::fill(p, p + n, c);        }        else        {            append(n - (end() - p), c);            append(p, oldEnd);            std::fill(p, oldEnd, c);        }        return *this;    }        template<class InputIterator>    flex_string& InsertImplDiscr(iterator i,        InputIterator b, InputIterator e, Selector<0>)    {         InsertImpl(i, b, e,             typename std::iterator_traits<InputIterator>::iterator_category());        return *this;    }    template <class FwdIterator>    void InsertImpl(iterator i,        FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)    {         Invariant checker(*this);         (void) checker;        const size_type pos = i - begin();        const typename std::iterator_traits<FwdIterator>::difference_type n2 =             std::distance(s1, s2);        assert(n2 >= 0);        using namespace flex_string_details;        assert(pos <= size());        const typename std::iterator_traits<FwdIterator>::difference_type maxn2 =             capacity() - size();        if (maxn2 < n2)        {            // realloc the string            static const std::less_equal<const value_type*> le =                 std::less_equal<const value_type*>();            assert(!(le(&*begin(), &*s1) && le(&*s1, &*end())));            reserve(size() + n2);            i = begin() + pos;        }        if (pos + n2 <= size())        {            //const iterator oldEnd = end();            //Storage::append(oldEnd - n2, n2);            //std::copy(i, oldEnd - n2, i + n2);            const iterator tailBegin = end() - n2;            Storage::append(tailBegin, tailBegin + n2);            //std::copy(i, tailBegin, i + n2);            std::copy(reverse_iterator(tailBegin), reverse_iterator(i),                 reverse_iterator(tailBegin + n2));            std::copy(s1, s2, i);        }        else        {            FwdIterator t = s1;            const size_type old_size = size();            std::advance(t, old_size - pos);            assert(std::distance(t, s2) >= 0);            Storage::append(t, s2);            Storage::append(data() + pos, data() + old_size);            std::copy(s1, t, i);        }    }    template <class InputIterator>    void InsertImpl(iterator i1, iterator i2,        InputIterator b, InputIterator e, std::input_iterator_tag)    {         flex_string temp(begin(), i1);        for (; b != e; ++b)        {            temp.push_back(*b);        }        temp.append(i2, end());        swap(temp);    }public:    template <class ItOrLength, class ItOrChar>    void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c)    {         Selector<std::numeric_limits<ItOrLength>::is_specialized> sel;        InsertImplDiscr(p, first_or_n, last_or_c, sel);    }        flex_string& erase(size_type pos = 0, size_type n = npos)    {         Invariant checker(*this);         (void) checker;        Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");        Procust(n, length() - pos);        std::copy(begin() + pos + n, end(), begin() + pos);        resize(length() - n);        return *this;    }        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;    }    // Replaces at most n1 chars of *this, starting with pos1 with the content of str    flex_string& replace(size_type pos1, size_type n1, const flex_string& str)    { return replace(pos1, n1, str.data(), str.size()); }        // Replaces at most n1 chars of *this, starting with pos1,    // with at most n2 chars of str starting with pos2    flex_string& replace(size_type pos1, size_type n1, const flex_string& str,        size_type pos2, size_type n2)    {        Enforce(pos2 <= str.length(), static_cast<std::out_of_range*>(0), "");        return replace(pos1, n1, str.data() + pos2,             Min(n2, str.size() - pos2));    }    /*    // Replaces at most n1 chars of *this, starting with pos,    // with at most n2 chars of str.    // str must have at least n2 chars.    flex_string& replace(const size_type pos, size_type n1,         const value_type* s1, const size_type n2)    {        Invariant checker(*this);         (void) checker;        Enforce(pos <= size(), (std::out_of_range*)0, "");        Procust(n1, size() - pos);        const iterator b = begin() + pos;        return replace(b, b + n1, s1, s1 + n2);        using namespace flex_string_details;        const int delta = int(n2 - n1);        static const std::less_equal<const value_type*> le;        const bool aliased = le(&*begin(), s1) && le(s1, &*end());        // From here on we're dealing with an aliased replace        if (delta <= 0)        {            // simple case, we're shrinking            pod_move(s1, s1 + n2, &*begin() + pos);            pod_move(&*begin() + pos + n1, &*end(), &*begin() + pos + n1 + delta);            resize(size() + delta);            return *this;        }        // From here on we deal with aliased growth        if (capacity() < size() + delta)        {            // realloc the string            const size_type offset = s1 - data();            reserve(size() + delta);            s1 = data() + offset;        }        const value_type* s2 = s1 + n2;        value_type* d1 = &*begin() + pos;        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))            {                pod_copy(s1 + delta, s2 + delta, d1);            }            else            {                // d2 > s1                if (le(d2, s2))                {                    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);        }        return *this;    }*/    // Replaces at most n1 chars of *this, starting with pos, with chars from s    flex_string& replace(size_type pos, size_type n1, const value_type* s)    { return replace(pos, n1, s, traits_type::length(s)); }        // Replaces at most n1 chars of *this, starting with pos, with n2 occurences of c    // consolidated with    // Replaces at most n1 chars of *this, starting with pos,    // with at most n2 chars of str.    // str must have at least n2 chars.    template <class StrOrLength, class NumOrChar>    flex_string& replace(size_type pos, size_type n1,         StrOrLength s_or_n2, NumOrChar n_or_c)    {        Invariant checker(*this);         (void) checker;        Enforce(pos <= size(), static_cast<std::out_of_range*>(0), "");        Procust(n1, length() - pos);        const iterator b = begin() + pos;        return replace(b, b + n1, s_or_n2, n_or_c);    }            flex_string& replace(iterator i1, iterator i2, const flex_string& str)    { return replace(i1, i2, str.data(), str.length()); }        flex_string& replace(iterator i1, iterator i2, const value_type* s)    { return replace(i1, i2, s, traits_type::length(s)); }    private:    flex_string& ReplaceImplDiscr(iterator i1, iterator i2,         const value_type* s, size_type n, Selector<2>)    {         assert(i1 <= i2);        assert(begin() <= i1 && i1 <= end());        assert(begin() <= i2 && i2 <= end());        return replace(i1, i2, s, s + n);     }        flex_string& ReplaceImplDiscr(iterator i1, iterator i2,        size_type n2, value_type c, Selector<1>)    {         const size_type n1 = i2 - i1;        if (n1 > n2)        {            std::fill(i1, i1 + n2, c);            erase(i1 + n2, i2);        }        else        {            std::fill(i1, i2, c);            insert(i2, n2 - n1, c);        }        return *this;    }        template <class InputIterator>    flex_string& ReplaceImplDiscr(iterator i1, iterator i2,        InputIterator b, InputIterator e, Selector<0>)    {         ReplaceImpl(i1, i2, b, e,             typename std::iterator_traits<InputIterator>::iterator_category());        return *this;    }    template <class FwdIterator>    void ReplaceImpl(iterator i1, iterator i2,        FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)    {         Invariant checker(*this);         (void) checker;        const typename std::iterator_traits<iterator>::difference_type n1 =             i2 - i1;        assert(n1 >= 0);        const typename std::iterator_traits<FwdIterator>::difference_type n2 =             std::distance(s1, s2);        assert(n2 >= 0);        // Handle aliased replace        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 (aliased /* && capacity() < size() - n1 + n2 */)        {            // Aliased replace, copy to new string            flex_string temp;            temp.reserve(size() - n1 + n2);            temp.append(begin(), i1).append(s1, s2).append(i2, end());            swap(temp);            return;        }        if (n1 > n2)        {            // shrinks            std::copy(s1, s2, i1);            erase(i1 + n2, i2);        }        else        {            // grows            flex_string_details::copy_n(s1, n1, i1);            std::advance(s1, n1);            insert(i2, s1, s2);        }    }    template <class InputIterator>    void ReplaceImpl(iterator i1, iterator i2,        InputIterator b, InputIterator e, std::input_iterator_tag)    {        flex_string temp(begin(), i1);        temp.append(b, e).append(i2, end());        swap(temp);    }public:    template <class T1, class T2>    flex_string& replace(iterator i1, iterator i2,        T1 first_or_n_or_s, T2 last_or_c_or_n)    {         const bool             num1 = std::numeric_limits<T1>::is_specialized,            num2 = std::numeric_limits<T2>::is_specialized;        return ReplaceImplDiscr(i1, i2, first_or_n_or_s, last_or_c_or_n,             Selector<num1 ? (num2 ? 1 : -1) : (num2 ? 2 : 0)>());     }           size_type copy(value_type* s, size_type n, size_type pos = 0) const    {        Enforce(pos <= size(), static_cast<std::out_of_range*>(0), "");        Procust(n, size() - pos);                flex_string_details::pod_copy(            data() + pos,

⌨️ 快捷键说明

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