flex_string.hpp
字号:
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_; };#endif 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; } 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) { 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()); }#if BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK != 0 // temporary hack to make it easier to serialize flex_string's using // the Boost.Serialization library value_type & back() { return *(begin()+size()-1); } value_type const& back() const { return *(begin()+size()-1); }#endif // 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) { push_back(c); return *this; } flex_string& append(const flex_string& str) { return append(str, 0, npos); } flex_string& append(const flex_string& str, const size_type pos, size_type n) { const size_type sz = str.size(); Enforce(pos <= sz, (std::out_of_range*)0, ""); Procust(n, sz - pos); return append(str.c_str() + pos, n); } flex_string& append(const value_type* s, const size_type n) { #ifndef NDEBUG Invariant checker(*this); #endif 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(value_type c) { 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, size_type pos, size_type n) { const size_type sz = str.size(); Enforce(pos <= str.size(), (std::out_of_range*)0, ""); Procust(n, sz - pos); return assign(str.data() + pos, n); } flex_string& assign(const value_type* s, size_type n) {#ifndef NDEBUG Invariant checker(*this); #endif 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(), (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(), (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(), (std::out_of_range*)0, ""); insert(begin() + pos, n, c); return *this; } iterator insert(iterator p, value_type c = value_type()) { const size_type pos = p - begin(); insert(pos, &c, 1); return begin() + pos; } private: template <int i> class Selector {}; flex_string& InsertImplDiscr(iterator p, size_type n, value_type c, Selector<1>) { #ifndef NDEBUG Invariant checker(*this); #endif 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) { append(oldEnd - n, 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, std::iterator_traits<InputIterator>::iterator_category()); return *this; } template <class FwdIterator> void InsertImpl(iterator i, FwdIterator s1, FwdIterator s2, std::forward_iterator_tag) { #ifndef NDEBUG Invariant checker(*this); #endif 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 tailBegin = end() - n2; Storage::append(tailBegin, tailBegin + 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) { #ifndef NDEBUG Invariant checker(*this); #endif Enforce(pos <= length(), (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, 0, npos); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -