flex_string.hpp
字号:
// 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(), (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 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) {#ifndef NDEBUG Invariant checker(*this); #endif Enforce(pos <= size(), (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.c_str(), 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, 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) { #ifndef NDEBUG Invariant checker(*this); #endif 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(), (std::out_of_range*)0, ""); n = Min(n, size() - pos); flex_string_details::pod_copy( &*begin() + pos, &*begin() + pos + n, s); return n; } void swap(flex_string& rhs) { Storage& srhs = rhs; this->Storage::swap(srhs); } // 21.3.6 string operations: const value_type* c_str() const { return Storage::c_str(); } const value_type* data() const { return Storage::data(); } allocator_type get_allocator() const { return Storage::get_allocator(); } size_type find(const flex_string& str, size_type pos = 0) const { return find(str.data(), pos, str.length()); } size_type find (const value_type* s, size_type pos, size_type n) const { for (; pos <= size(); ++pos) { if (traits_type::compare(&*begin() + pos, s, n) == 0) { return pos; } } return npos; } size_type find (const value_type* s, size_type pos = 0) const { return find(s, pos, traits_type::length(s)); } size_type find (value_type c, size_type pos = 0) const { return find(&c, pos, 1); } size_type rfind(const flex_string& str, size_type pos = npos) const { return rfind(str.c_str(), pos, str.length()); } size_type rfind(const value_type* s, size_type pos, size_type n) const { if (n > length()) return npos; pos = Min(pos, length() - n); if (n == 0) return pos; const_iterator i(begin() + pos); for (; ; --i) { if (traits_type::eq(*i, *s) && traits_type::compare(&*i, s, n) == 0) { return i - begin(); } if (i == begin()) break; } return npos; } size_type rfind(const value_type* s, size_type pos = npos) const { return rfind(s, pos, traits_type::length(s)); } size_type rfind(value_type c, size_type pos = npos) const { return rfind(&c, pos, 1); } size_type find_first_of(const flex_string& str, size_type pos = 0) const { return find_first_of(str.c_str(), pos, str.length()); } size_type find_first_of(const value_type* s, size_type pos, size_type n) const { if (pos > length() || n == 0) return npos; const_iterator i(begin() + pos), finish(end()); for (; i != finish; ++i) { if (traits_type::find(s, n, *i) != 0) { return i - begin(); } } return npos; } size_type find_first_of(const value_type* s, size_type pos = 0) const { return find_first_of(s, pos, traits_type::length(s)); } size_type find_first_of(value_type c, size_type pos = 0) const { return find_first_of(&c, pos, 1); } size_type find_last_of (const flex_string& str, size_type pos = npos) const { return find_last_of(str.c_str(), pos, str.length()); } size_type find_last_of (const value_type* s, size_type pos, size_type n) const { if (!empty() && n > 0) { pos = Min(pos, length() - 1); const_iterator i(begin() + pos); for (;; --i) { if (traits_type::find(s, n, *i) != 0) { return i - begin(); } if (i == begin()) break; } } return npos; } size_type find_last_of (const value_type* s, size_type pos = npos) const { return find_last_of(s, pos, traits_type::length(s)); } size_type find_last_of (value_type c, size_type pos = npos) const { return find_last_of(&c, pos, 1); } size_type find_first_not_of(const flex_string& str, size_type pos = 0) const { return find_first_not_of(str.data(), pos, str.size()); } size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const { if (pos < length()) { const_iterator i(begin() + pos), finish(end()); for (; i != finish; ++i) { if (traits_type::find(s, n, *i) == 0) { return i - begin(); } } } return npos; } size_type find_first_not_of(const value_type* s, size_type pos = 0) const { return find_first_not_of(s, pos, traits_type::length(s)); } size_type find_first_not_of(value_type c, size_type pos = 0) const { return find_first_not_of(&c, pos, 1); } size_type find_last_not_of(const flex_string& str, size_type pos = npos) const { return find_last_not_of(str.c_str(), pos, str.length()); } size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const { if (!empty()) { pos = Min(pos, size() - 1); const_iterator i(begin() + pos); for (;; --i) { if (traits_type::find(s, n, *i) == 0) { return i - begin(); } if (i == begin()) break; } } return npos; } size_type find_last_not_of(const value_type* s, size_type pos = npos) const { return find_last_not_of(s, pos, traits_type::length(s)); } size_type find_last_not_of (value_type c, size_type pos = npos) const { return find_last_not_of(&c, pos, 1); } flex_string substr(size_type pos = 0, size_type n = npos) const { Enforce(pos <= size(), (std::out_of_range*)0, ""); return flex_string(data() + pos, Min(n, size() - pos)); } std::ptrdiff_t compare(const flex_string& str) const { // FIX due to Goncalo N M de Carvalho July 18, 2005 return compare(0, size(), str); } std::ptrdiff_t compare(size_type pos1, size_type n1, const flex_string& str) const { return compare(pos1, n1, str.data(), str.size()); } // FIX to compare: added the TC // (http://www.comeaucomputing.com/iso/lwg-defects.html number 5) // Thanks to Caleb Epstein for the fix std::ptrdiff_t compare(size_type pos1, size_type n1, const value_type* s) const { return compare(pos1, n1, s, traits_type::length(s)); } std::ptrdiff_t compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const { Enforce(pos1 <= size(), (std::out_of_range*)0, ""); Procust(n1, size() - pos1); const int r = traits_type::compare(data()+pos1, s, Min(n1, n2)); return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0; } std::ptrdiff_t compare(size_type pos1, size_type n1, const flex_string& str, size_type pos2, size_type n2) const { Enforce(pos2 <= str.size(), (std::out_of_range*)0, ""); return compare(pos1, n1, str.data() + pos2, Min(n2, str.size() - pos2)); } std::ptrdiff_t compare(const value_type* s) const { return traits_type::compare(data(), s, traits_type::length(s)); }};// non-member functionstemplate <typename E, class T, class A, class S>flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, const flex_string<E, T, A, S>& rhs){ flex_string<E, T, A, S> result; result.reserve(lhs.size() + rhs.size()); result.append(lhs).append(rhs); return result;}template <typename E, class T, class A, class S>flex_string<E, T, A, S> operator+(const typename flex_string<E, T, A, S>::value_type* lhs, const flex_string<E, T, A, S>& rhs){ flex_string<E, T, A, S> result; const typename flex_string<E, T, A, S>::size_type len = flex_string<E, T, A, S>::traits_type::length(lhs); result.reserve(len + rhs.size()); result.append(lhs, len).append(rhs); return result;}template <typename E, class T, class A, class S>flex_string<E, T, A, S> operator+( typename flex_string<E, T, A, S>::value_type lhs, const flex_string<E, T, A, S>& rhs){ flex_string<E, T, A, S> result; result.reserve(1 + rhs.size()); result.push_back(lhs); result.append(rhs); return result;}template <typename E, class T, class A, class S>flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, const typename flex_string<E, T, A, S>::value_type* rhs){ typedef typename flex_string<E, T, A, S>::size_type size_type; typedef typename flex_string<E, T, A, S>::traits_type traits_type; flex_string<E, T, A, S> result; const size_type len = traits_type::length(rhs); result.reserve(lhs.size() + len); result.append(lhs).append(rhs, len); return result;}template <typename E, class T, class A, class S>flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, typename flex_string<E, T, A, S>::value_type rhs){ flex_string<E, T, A, S> result; result.reserve(lhs.size() + 1); result.append(lhs); result.push_back(rhs); return result;}template <typename E, class T, class A, class S>inline bool operator==(const flex_string<E, T, A, S>& lhs, const flex_string<E, T, A, S>& rhs){ return lhs.compare(rhs) == 0; }template <typename E, class T, class A, class S>inline bool operator==(const typename flex_string<E, T, A, S>::value_type* lhs, const flex_string<E, T, A, S>& rhs){ return rhs == lhs; }template <typename E, class T, class A, class S>inline bool operator==(const flex_string<E, T, A, S>& lhs, const typename flex_string<E, T, A, S>::value_type* rhs){ return lhs.compare(rhs) == 0; }template <typename E, class T, class A, class S>inline bool operator!=(const flex_string<E, T, A, S>& lhs, const flex_string<E, T, A, S>& rhs){ return !(lhs == rhs); }template <typename E, class T, class A, class S>inline bool operator!=(const typename flex_string<E, T, A, S>::value_type* lhs, const flex_string<E, T, A, S>& rhs){ return !(lhs == rhs); }template <typename E, class T, class A, class S>inline bool operator!=(const flex_string<E, T, A, S>& lhs, const typename flex_string<E, T, A, S>::value_type* rhs){ return !(lhs =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -