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

📄 flex_string_shell.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 3 页
字号:
        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,
            data() + pos + n,

⌨️ 快捷键说明

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