38 #ifndef LIBPMEMOBJ_CPP_BASIC_STRING_HPP
39 #define LIBPMEMOBJ_CPP_BASIC_STRING_HPP
69 template <
typename CharT,
typename Traits = std::
char_traits<CharT>>
73 using traits_type = Traits;
74 using value_type = CharT;
75 using size_type = std::size_t;
76 using difference_type = std::ptrdiff_t;
77 using reference = value_type &;
78 using const_reference =
const value_type &;
79 using pointer = value_type *;
80 using const_pointer =
const value_type *;
82 using const_iterator = const_pointer;
83 using reverse_iterator = std::reverse_iterator<iterator>;
84 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
85 using for_each_ptr_function =
89 static constexpr size_type sso_capacity = (32 - 8) /
sizeof(CharT) - 1;
95 size_type count = npos);
96 basic_string(
const std::basic_string<CharT> &other, size_type pos,
97 size_type count = npos);
102 typename Enable =
typename std::enable_if<
126 size_type count = npos);
128 size_type pos, size_type count = npos);
131 template <
typename InputIt,
139 reference
at(size_type n);
140 const_reference
at(size_type n)
const;
141 const_reference
const_at(size_type n)
const;
143 const_reference
operator[](size_type n)
const;
145 const CharT &
front()
const;
146 const CharT &
cfront()
const;
148 const CharT &
back()
const;
149 const CharT &
cback()
const;
151 const CharT *
data()
const noexcept;
152 const CharT *
cdata()
const noexcept;
153 const CharT *
c_str()
const noexcept;
158 const_iterator
begin()
const noexcept;
159 const_iterator
cbegin()
const noexcept;
161 const_iterator
end()
const noexcept;
162 const_iterator
cend()
const noexcept;
163 reverse_iterator
rbegin();
164 const_reverse_iterator
rbegin()
const noexcept;
165 const_reverse_iterator
crbegin()
const noexcept;
166 reverse_iterator
rend();
167 const_reverse_iterator
rend()
const noexcept;
168 const_reverse_iterator
crend()
const noexcept;
171 bool empty()
const noexcept;
172 size_type
size()
const noexcept;
173 size_type
length()
const noexcept;
174 size_type
max_size()
const noexcept;
175 size_type
capacity()
const noexcept;
176 void resize(size_type count, CharT ch);
178 void reserve(size_type new_cap = 0);
187 template <
typename T,
188 typename Enable =
typename std::enable_if<
189 std::is_convertible<T, size_type>::value>::type>
191 template <
typename T,
192 typename Enable =
typename std::enable_if<
193 !std::is_convertible<T, size_type>::value>::type>
200 size_type count = npos);
203 template <
typename InputIt,
219 size_type index2, size_type count = npos);
222 template <
typename InputIt,
226 iterator insert(const_iterator pos, std::initializer_list<CharT> ilist);
227 template <
typename T,
228 typename Enable =
typename std::enable_if<
229 std::is_convertible<T, size_type>::value>::type>
231 template <
typename T,
232 typename Enable =
typename std::enable_if<
233 !std::is_convertible<T, size_type>::value>::type>
242 size_type count2 = npos);
243 template <
typename InputIt,
247 InputIt first2, InputIt last2);
249 const CharT *s, size_type count2);
253 size_type count2, CharT ch);
255 size_type count2, CharT ch);
260 std::initializer_list<CharT> ilist);
262 size_type
copy(CharT *s, size_type count, size_type index = 0)
const;
265 int compare(
const std::basic_string<CharT> &other)
const;
266 int compare(size_type pos, size_type count,
268 int compare(size_type pos, size_type count,
269 const std::basic_string<CharT> &other)
const;
271 size_type pos2, size_type count2 = npos)
const;
272 int compare(size_type pos1, size_type count1,
273 const std::basic_string<CharT> &other, size_type pos2,
274 size_type count2 = npos)
const;
275 int compare(
const CharT *s)
const;
276 int compare(size_type pos, size_type count,
const CharT *s)
const;
277 int compare(size_type pos, size_type count1,
const CharT *s,
278 size_type count2)
const;
283 size_type
find(
const CharT *s, size_type pos, size_type count)
const;
284 size_type
find(
const CharT *s, size_type pos = 0)
const;
285 size_type
find(CharT ch, size_type pos = 0)
const noexcept;
288 size_type
rfind(
const CharT *s, size_type pos, size_type count)
const;
289 size_type
rfind(
const CharT *s, size_type pos = npos)
const;
290 size_type
rfind(CharT ch, size_type pos = npos)
const noexcept;
292 size_type pos = 0)
const noexcept;
294 size_type count)
const;
295 size_type
find_first_of(
const CharT *s, size_type pos = 0)
const;
296 size_type
find_first_of(CharT ch, size_type pos = 0)
const noexcept;
298 size_type pos = 0)
const noexcept;
300 size_type count)
const;
304 size_type pos = npos)
const noexcept;
306 size_type count)
const;
307 size_type
find_last_of(
const CharT *s, size_type pos = npos)
const;
308 size_type
find_last_of(CharT ch, size_type pos = npos)
const noexcept;
310 size_type pos = npos)
const noexcept;
312 size_type count)
const;
318 static const size_type npos =
static_cast<size_type
>(-1);
362 static constexpr size_type _sso_mask = 1ULL
363 << (std::numeric_limits<size_type>::digits - 1);
366 bool is_sso_used()
const;
370 typename Enable =
typename std::enable_if<
372 size_type
get_size(InputIt first, InputIt last)
const;
373 size_type
get_size(size_type count, value_type ch)
const;
375 template <
typename... Args>
377 template <
typename... Args>
382 typename Enable =
typename std::enable_if<
389 typename Enable =
typename std::enable_if<
408 non_sso_data()
const;
421 template <
typename CharT,
typename Traits>
428 initialize(0U, value_type(
'\0'));
445 template <
typename CharT,
typename Traits>
452 initialize(count, ch);
472 template <
typename CharT,
typename Traits>
474 size_type pos, size_type count)
479 if (pos > other.
size())
480 throw std::out_of_range(
"Index out of range.");
482 if (count == npos || pos + count > other.
size())
483 count = other.
size() - pos;
485 auto first =
static_cast<difference_type
>(pos);
486 auto last = first +
static_cast<difference_type
>(count);
489 initialize(other.
cbegin() + first, other.
cbegin() + last);
510 template <
typename CharT,
typename Traits>
512 size_type pos, size_type count)
517 if (pos > other.size())
518 throw std::out_of_range(
"Index out of range.");
520 if (count == npos || pos + count > other.size())
521 count = other.size() - pos;
523 auto first =
static_cast<difference_type
>(pos);
524 auto last = first +
static_cast<difference_type
>(count);
527 initialize(other.cbegin() + first, other.cbegin() + last);
545 template <
typename CharT,
typename Traits>
552 initialize(s, s + count);
568 template <
typename CharT,
typename Traits>
574 auto length = traits_type::length(s);
577 initialize(s, s + length);
596 template <
typename CharT,
typename Traits>
597 template <
typename InputIt,
typename Enable>
600 auto len = std::distance(first, last);
606 allocate(
static_cast<size_type
>(len));
607 initialize(first, last);
624 template <
typename CharT,
typename Traits>
630 allocate(other.
size());
649 template <
typename CharT,
typename Traits>
669 template <
typename CharT,
typename Traits>
675 allocate(other.size());
676 initialize(std::move(other));
678 if (other.is_sso_used())
679 other.initialize(0U, value_type(
'\0'));
696 template <
typename CharT,
typename Traits>
702 allocate(ilist.size());
703 initialize(ilist.begin(), ilist.end());
711 template <
typename CharT,
typename Traits>
715 detail::destroy<non_sso_type>(non_sso_data());
727 template <
typename CharT,
typename Traits>
731 return assign(other);
744 template <
typename CharT,
typename Traits>
748 return assign(other);
760 template <
typename CharT,
typename Traits>
764 return assign(std::move(other));
775 template <
typename CharT,
typename Traits>
790 template <
typename CharT,
typename Traits>
794 return assign(1, ch);
806 template <
typename CharT,
typename Traits>
810 return assign(ilist);
823 template <
typename CharT,
typename Traits>
827 auto pop = get_pool();
843 template <
typename CharT,
typename Traits>
850 auto pop = get_pool();
853 pop, [&] { replace_content(other.
cbegin(), other.
cend()); });
868 template <
typename CharT,
typename Traits>
872 return assign(other.cbegin(), other.cend());
887 template <
typename CharT,
typename Traits>
892 if (pos > other.
size())
893 throw std::out_of_range(
"Index out of range.");
895 if (count == npos || pos + count > other.
size())
896 count = other.
size() - pos;
898 auto pop = get_pool();
899 auto first =
static_cast<difference_type
>(pos);
900 auto last = first +
static_cast<difference_type
>(count);
903 replace_content(other.
cbegin() + first, other.
cbegin() + last);
923 template <
typename CharT,
typename Traits>
926 size_type pos, size_type count)
928 if (pos > other.size())
929 throw std::out_of_range(
"Index out of range.");
931 if (count == npos || pos + count > other.size())
932 count = other.size() - pos;
934 return assign(other.c_str() + pos, count);
947 template <
typename CharT,
typename Traits>
951 auto pop = get_pool();
966 template <
typename CharT,
typename Traits>
970 auto pop = get_pool();
972 auto length = traits_type::length(s);
990 template <
typename CharT,
typename Traits>
991 template <
typename InputIt,
typename Enable>
995 auto pop = get_pool();
1011 template <
typename CharT,
typename Traits>
1018 auto pop = get_pool();
1021 replace_content(std::move(other));
1023 if (other.is_sso_used())
1024 other.initialize(0U, value_type(
'\0'));
1039 template <
typename CharT,
typename Traits>
1043 return assign(ilist.begin(), ilist.end());
1053 template <
typename CharT,
typename Traits>
1057 if (!is_sso_used()) {
1058 non_sso._data.for_each_ptr(func);
1067 template <
typename CharT,
typename Traits>
1080 template <
typename CharT,
typename Traits>
1081 typename basic_string<CharT, Traits>::const_iterator
1092 template <
typename CharT,
typename Traits>
1093 typename basic_string<CharT, Traits>::const_iterator
1096 return is_sso_used() ? const_iterator(&*sso_data().
cbegin())
1097 : const_iterator(&*non_sso_data().
cbegin());
1105 template <
typename CharT,
typename Traits>
1109 return begin() +
static_cast<difference_type
>(size());
1118 template <
typename CharT,
typename Traits>
1119 typename basic_string<CharT, Traits>::const_iterator
1122 return cbegin() +
static_cast<difference_type
>(size());
1131 template <
typename CharT,
typename Traits>
1132 typename basic_string<CharT, Traits>::const_iterator
1135 return cbegin() +
static_cast<difference_type
>(size());
1144 template <
typename CharT,
typename Traits>
1145 typename basic_string<CharT, Traits>::reverse_iterator
1148 return reverse_iterator(
end());
1157 template <
typename CharT,
typename Traits>
1158 typename basic_string<CharT, Traits>::const_reverse_iterator
1170 template <
typename CharT,
typename Traits>
1171 typename basic_string<CharT, Traits>::const_reverse_iterator
1174 return const_reverse_iterator(
cend());
1183 template <
typename CharT,
typename Traits>
1184 typename basic_string<CharT, Traits>::reverse_iterator
1187 return reverse_iterator(
begin());
1196 template <
typename CharT,
typename Traits>
1197 typename basic_string<CharT, Traits>::const_reverse_iterator
1209 template <
typename CharT,
typename Traits>
1210 typename basic_string<CharT, Traits>::const_reverse_iterator
1213 return const_reverse_iterator(
cbegin());
1229 template <
typename CharT,
typename Traits>
1230 typename basic_string<CharT, Traits>::reference
1234 throw std::out_of_range(
"string::at");
1236 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1249 template <
typename CharT,
typename Traits>
1250 typename basic_string<CharT, Traits>::const_reference
1269 template <
typename CharT,
typename Traits>
1270 typename basic_string<CharT, Traits>::const_reference
1274 throw std::out_of_range(
"string::const_at");
1276 return is_sso_used()
1277 ?
static_cast<const sso_type &
>(sso_data())[n]
1278 :
static_cast<const non_sso_type &
>(non_sso_data())[n];
1292 template <
typename CharT,
typename Traits>
1293 typename basic_string<CharT, Traits>::reference
1296 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1306 template <
typename CharT,
typename Traits>
1307 typename basic_string<CharT, Traits>::const_reference
1310 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1322 template <
typename CharT,
typename Traits>
1334 template <
typename CharT,
typename Traits>
1349 template <
typename CharT,
typename Traits>
1365 template <
typename CharT,
typename Traits>
1369 return (*
this)[size() - 1];
1377 template <
typename CharT,
typename Traits>
1392 template <
typename CharT,
typename Traits>
1396 return static_cast<const basic_string &
>(*this)[size() - 1];
1402 template <
typename CharT,
typename Traits>
1403 typename basic_string<CharT, Traits>::size_type
1407 return get_sso_size();
1408 else if (non_sso_data().size() == 0)
1411 return non_sso_data().size() - 1;
1420 template <
typename CharT,
typename Traits>
1424 return is_sso_used() ? sso_data().range(0, get_sso_size() + 1).begin()
1425 : non_sso_data().data();
1446 template <
typename CharT,
typename Traits>
1453 throw std::out_of_range(
"Index exceeds size.");
1455 count = (std::min)(count, sz - index);
1457 auto pop = get_pool();
1459 auto first =
begin() +
static_cast<difference_type
>(index);
1460 auto last = first +
static_cast<difference_type
>(count);
1462 if (is_sso_used()) {
1464 auto move_len = sz - index - count;
1465 auto new_size = sz - count;
1467 auto range = sso_data().range(index, move_len + 1);
1469 traits_type::move(range.begin(), &*last, move_len);
1471 set_sso_size(new_size);
1473 assert(range.end() - 1 ==
1474 &sso_data()._data[index + move_len]);
1475 *(range.end() - 1) = value_type(
'\0');
1478 non_sso_data().erase(first, last);
1500 template <
typename CharT,
typename Traits>
1504 return erase(pos, pos + 1);
1525 template <
typename CharT,
typename Traits>
1530 static_cast<size_type
>(std::distance(
cbegin(), first));
1531 size_type len =
static_cast<size_type
>(std::distance(first, last));
1535 return begin() +
static_cast<difference_type
>(index);
1548 template <
typename CharT,
typename Traits>
1552 erase(size() - 1, 1);
1574 template <
typename CharT,
typename Traits>
1579 auto new_size = sz + count;
1581 if (new_size > max_size())
1582 throw std::length_error(
"Size exceeds max size.");
1584 if (is_sso_used()) {
1585 auto pop = get_pool();
1588 if (new_size > sso_capacity) {
1589 sso_to_large(new_size);
1591 non_sso_data().insert(
1592 non_sso_data().
cbegin() +
1593 static_cast<difference_type
>(
1597 add_sso_to_tx(sz, count + 1);
1598 traits_type::assign(&sso_data()._data[sz],
1601 assert(new_size == sz + count);
1602 set_sso_size(new_size);
1603 sso_data()._data[new_size] = value_type(
'\0');
1607 non_sso_data().insert(non_sso_data().
cbegin() +
1608 static_cast<difference_type
>(sz),
1633 template <
typename CharT,
typename Traits>
1637 return append(str.
data(), str.
size());
1665 template <
typename CharT,
typename Traits>
1670 auto sz = str.
size();
1673 throw std::out_of_range(
"Index out of range.");
1675 count = (std::min)(count, sz - pos);
1677 append(str.
data() + pos, count);
1701 template <
typename CharT,
typename Traits>
1705 return append(s, s + count);
1727 template <
typename CharT,
typename Traits>
1731 return append(s, traits_type::length(s));
1755 template <
typename CharT,
typename Traits>
1756 template <
typename InputIt,
typename Enable>
1761 auto count =
static_cast<size_type
>(std::distance(first, last));
1762 auto new_size = sz + count;
1764 if (new_size > max_size())
1765 throw std::length_error(
"Size exceeds max size.");
1767 if (is_sso_used()) {
1768 auto pop = get_pool();
1771 if (new_size > sso_capacity) {
1780 std::vector<value_type> str(first, last);
1782 sso_to_large(new_size);
1783 non_sso_data().insert(
1784 non_sso_data().
cbegin() +
1785 static_cast<difference_type
>(
1787 str.begin(), str.end());
1789 add_sso_to_tx(sz, count + 1);
1790 std::copy(first, last, &sso_data()._data[sz]);
1792 assert(new_size == sz + count);
1793 set_sso_size(new_size);
1794 sso_data()._data[new_size] = value_type(
'\0');
1798 non_sso_data().insert(non_sso_data().
cbegin() +
1799 static_cast<difference_type
>(sz),
1824 template <
typename CharT,
typename Traits>
1828 return append(ilist.begin(), ilist.end());
1847 template <
typename CharT,
typename Traits>
1851 append(
static_cast<size_type
>(1), ch);
1872 template <
typename CharT,
typename Traits>
1898 template <
typename CharT,
typename Traits>
1921 template <
typename CharT,
typename Traits>
1948 template <
typename CharT,
typename Traits>
1952 return append(ilist);
1976 template <
typename CharT,
typename Traits>
1981 throw std::out_of_range(
"Index out of range.");
1983 auto pos =
cbegin() +
static_cast<difference_type
>(index);
1985 insert(pos, count, ch);
2011 template <
typename CharT,
typename Traits>
2015 return insert(index, s, traits_type::length(s));
2039 template <
typename CharT,
typename Traits>
2045 throw std::out_of_range(
"Index out of range.");
2047 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2049 insert(pos, s, s + count);
2074 template <
typename CharT,
typename Traits>
2078 return insert(index, str.
data(), str.
size());
2103 template <
typename CharT,
typename Traits>
2106 size_type index2, size_type count)
2108 auto sz = str.
size();
2110 if (index1 > size() || index2 > sz)
2111 throw std::out_of_range(
"Index out of range.");
2113 count = (std::min)(count, sz - index2);
2115 return insert(index1, str.
data() + index2, count);
2140 template <
typename CharT,
typename Traits>
2144 return insert(pos, 1, ch);
2171 template <
typename CharT,
typename Traits>
2178 if (sz + count > max_size())
2179 throw std::length_error(
"Count exceeds max size.");
2181 auto new_size = sz + count;
2183 auto pop = get_pool();
2185 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2188 if (is_sso_used() && new_size <= sso_capacity) {
2189 auto len = sz - index;
2191 add_sso_to_tx(index, len + count + 1);
2193 traits_type::move(&sso_data()._data[index + count],
2194 &sso_data()._data[index], len);
2195 traits_type::assign(&sso_data()._data[index], count,
2198 assert(new_size == index + len + count);
2199 set_sso_size(new_size);
2200 sso_data()._data[new_size] = value_type(
'\0');
2203 sso_to_large(new_size);
2205 non_sso_data().insert(
2206 non_sso_data().
begin() +
2207 static_cast<difference_type
>(index),
2212 return iterator(&data()[
static_cast<difference_type
>(index)]);
2239 template <
typename CharT,
typename Traits>
2240 template <
typename InputIt,
typename Enable>
2247 auto count =
static_cast<size_type
>(std::distance(first, last));
2249 if (sz + count > max_size())
2250 throw std::length_error(
"Count exceeds max size.");
2252 auto pop = get_pool();
2254 auto new_size = sz + count;
2256 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2259 if (is_sso_used() && new_size <= sso_capacity) {
2260 auto len = sz - index;
2262 add_sso_to_tx(index, len + count + 1);
2264 traits_type::move(&sso_data()._data[index + count],
2265 &sso_data()._data[index], len);
2266 std::copy(first, last, &sso_data()._data[index]);
2268 assert(new_size == index + len + count);
2269 set_sso_size(new_size);
2270 sso_data()._data[new_size] = value_type(
'\0');
2272 if (is_sso_used()) {
2281 std::vector<value_type> str(first, last);
2283 sso_to_large(new_size);
2284 non_sso_data().insert(
2285 non_sso_data().
begin() +
2286 static_cast<difference_type
>(
2288 str.begin(), str.end());
2290 non_sso_data().insert(
2291 non_sso_data().
begin() +
2292 static_cast<difference_type
>(
2299 return iterator(&data()[
static_cast<difference_type
>(index)]);
2325 template <
typename CharT,
typename Traits>
2328 std::initializer_list<CharT> ilist)
2330 return insert(pos, ilist.begin(), ilist.end());
2355 template <
typename CharT,
typename Traits>
2360 return replace(index, count, str.
data(), str.
size());
2383 template <
typename CharT,
typename Traits>
2388 return replace(first, last, str.
data(), str.
data() + str.
size());
2417 template <
typename CharT,
typename Traits>
2423 auto sz = str.
size();
2426 throw std::out_of_range(
"Index out of range.");
2428 count2 = (std::min)(count2, sz - index2);
2430 return replace(index, count, str.
data() + index2, count2);
2458 template <
typename CharT,
typename Traits>
2459 template <
typename InputIt,
typename Enable>
2462 InputIt first2, InputIt last2)
2465 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2466 auto count =
static_cast<size_type
>(std::distance(first, last));
2467 auto count2 =
static_cast<size_type
>(std::distance(first2, last2));
2469 count = (std::min)(count, sz - index);
2471 if (sz - count + count2 > max_size())
2472 throw std::length_error(
"Count exceeds max size.");
2474 auto new_size = sz - count + count2;
2476 auto pop = get_pool();
2479 if (is_sso_used() && new_size <= sso_capacity) {
2480 add_sso_to_tx(index, new_size - index + 1);
2482 assert(count2 < new_size + 1);
2483 traits_type::move(&sso_data()._data[index + count2],
2484 &sso_data()._data[index + count],
2485 sz - index - count);
2486 std::copy(first2, last2, &sso_data()._data[index]);
2488 set_sso_size(new_size);
2489 sso_data()._data[new_size] = value_type(
'\0');
2499 std::vector<value_type> str(first2, last2);
2501 if (is_sso_used()) {
2502 sso_to_large(new_size);
2506 begin() +
static_cast<difference_type
>(index);
2507 auto end = beg +
static_cast<difference_type
>(count);
2508 non_sso_data().erase(beg,
end);
2509 non_sso_data().insert(beg, str.begin(), str.end());
2512 if (!is_sso_used() && new_size <= sso_capacity)
2541 template <
typename CharT,
typename Traits>
2544 const CharT *s, size_type count2)
2546 return replace(first, last, s, s + count2);
2572 template <
typename CharT,
typename Traits>
2575 const CharT *s, size_type count2)
2578 throw std::out_of_range(
"Index out of range.");
2580 auto first =
cbegin() +
static_cast<difference_type
>(index);
2581 auto last = first +
static_cast<difference_type
>(count);
2583 return replace(first, last, s, s + count2);
2609 template <
typename CharT,
typename Traits>
2614 return replace(index, count, s, traits_type::length(s));
2640 template <
typename CharT,
typename Traits>
2643 size_type count2, CharT ch)
2646 throw std::out_of_range(
"Index out of range.");
2648 auto first =
cbegin() +
static_cast<difference_type
>(index);
2649 auto last = first +
static_cast<difference_type
>(count);
2651 return replace(first, last, count2, ch);
2676 template <
typename CharT,
typename Traits>
2679 size_type count2, CharT ch)
2682 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2683 auto count =
static_cast<size_type
>(std::distance(first, last));
2685 count = (std::min)(count, sz - index);
2687 if (sz - count + count2 > max_size())
2688 throw std::length_error(
"Count exceeds max size.");
2690 auto new_size = sz - count + count2;
2692 auto pop = get_pool();
2695 if (is_sso_used() && new_size <= sso_capacity) {
2696 add_sso_to_tx(index, new_size - index + 1);
2698 assert(count2 < new_size + 1);
2699 traits_type::move(&sso_data()._data[index + count2],
2700 &sso_data()._data[index + count],
2701 sz - index - count);
2702 traits_type::assign(&sso_data()._data[index], count2,
2705 set_sso_size(new_size);
2706 sso_data()._data[new_size] = value_type(
'\0');
2708 if (is_sso_used()) {
2709 sso_to_large(new_size);
2713 begin() +
static_cast<difference_type
>(index);
2714 auto end = beg +
static_cast<difference_type
>(count);
2715 non_sso_data().erase(beg,
end);
2716 non_sso_data().insert(beg, count2, ch);
2719 if (!is_sso_used() && new_size <= sso_capacity)
2747 template <
typename CharT,
typename Traits>
2752 return replace(first, last, s, traits_type::length(s));
2777 template <
typename CharT,
typename Traits>
2780 std::initializer_list<CharT> ilist)
2782 return replace(first, last, ilist.begin(), ilist.end());
2798 template <
typename CharT,
typename Traits>
2799 typename basic_string<CharT, Traits>::size_type
2801 size_type index)
const
2806 throw std::out_of_range(
"Index out of range.");
2808 auto len = (std::min)(count, sz - index);
2810 traits_type::copy(s, data() + index, len);
2832 template <
typename CharT,
typename Traits>
2835 const CharT *s, size_type count2)
const
2838 throw std::out_of_range(
"Index out of range.");
2840 if (count1 > size() - pos)
2841 count1 = size() - pos;
2843 auto ret = traits_type::compare(cdata() + pos, s,
2844 std::min<size_type>(count1, count2));
2849 if (count1 < count2)
2851 else if (count1 == count2)
2866 template <
typename CharT,
typename Traits>
2867 typename basic_string<CharT, Traits>::size_type
2871 return find(str.data(), pos, str.size());
2885 template <
typename CharT,
typename Traits>
2886 typename basic_string<CharT, Traits>::size_type
2888 size_type count)
const
2898 while (pos + count <= sz) {
2899 auto found = traits_type::find(cdata() + pos, sz - pos, s[0]);
2902 pos =
static_cast<size_type
>(std::distance(cdata(), found));
2903 if (traits_type::compare(found, s, count) == 0) {
2921 template <
typename CharT,
typename Traits>
2922 typename basic_string<CharT, Traits>::size_type
2925 return find(s, pos, traits_type::length(s));
2937 template <
typename CharT,
typename Traits>
2938 typename basic_string<CharT, Traits>::size_type
2941 return find(&ch, pos, 1);
2954 template <
typename CharT,
typename Traits>
2955 typename basic_string<CharT, Traits>::size_type
2959 return rfind(str.cdata(), pos, str.size());
2978 template <
typename CharT,
typename Traits>
2979 typename basic_string<CharT, Traits>::size_type
2981 size_type count)
const
2983 if (count <= size()) {
2984 pos = (std::min)(size() - count, pos);
2986 if (traits_type::compare(cdata() + pos, s, count) == 0)
2988 }
while (pos-- > 0);
3005 template <
typename CharT,
typename Traits>
3006 typename basic_string<CharT, Traits>::size_type
3009 return rfind(s, pos, traits_type::length(s));
3023 template <
typename CharT,
typename Traits>
3024 typename basic_string<CharT, Traits>::size_type
3027 return rfind(&ch, pos, 1);
3039 template <
typename CharT,
typename Traits>
3040 typename basic_string<CharT, Traits>::size_type
3042 size_type pos)
const noexcept
3044 return find_first_of(str.cdata(), pos, str.size());
3060 template <
typename CharT,
typename Traits>
3061 typename basic_string<CharT, Traits>::size_type
3063 size_type count)
const
3065 size_type first_of = npos;
3066 for (
const CharT *c = s; c != s + count; ++c) {
3067 size_type found = find(*c, pos);
3068 if (found != npos && found < first_of)
3086 template <
typename CharT,
typename Traits>
3087 typename basic_string<CharT, Traits>::size_type
3090 return find_first_of(s, pos, traits_type::length(s));
3102 template <
typename CharT,
typename Traits>
3103 typename basic_string<CharT, Traits>::size_type
3107 return find(ch, pos);
3119 template <
typename CharT,
typename Traits>
3120 typename basic_string<CharT, Traits>::size_type
3122 size_type pos)
const noexcept
3124 return find_first_not_of(str.cdata(), pos, str.size());
3140 template <
typename CharT,
typename Traits>
3141 typename basic_string<CharT, Traits>::size_type
3143 size_type count)
const
3148 for (
auto it =
cbegin() + pos; it !=
cend(); ++it)
3149 if (!traits_type::find(s, count, *it))
3150 return static_cast<size_type
>(
3151 std::distance(
cbegin(), it));
3167 template <
typename CharT,
typename Traits>
3168 typename basic_string<CharT, Traits>::size_type
3170 size_type pos)
const
3172 return find_first_not_of(s, pos, traits_type::length(s));
3184 template <
typename CharT,
typename Traits>
3185 typename basic_string<CharT, Traits>::size_type
3189 return find_first_not_of(&ch, pos, 1);
3201 template <
typename CharT,
typename Traits>
3202 typename basic_string<CharT, Traits>::size_type
3204 size_type pos)
const noexcept
3206 return find_last_of(str.cdata(), pos, str.size());
3222 template <
typename CharT,
typename Traits>
3223 typename basic_string<CharT, Traits>::size_type
3225 size_type count)
const
3227 if (size() == 0 || count == 0)
3231 size_type last_of = 0;
3232 for (
const CharT *c = s; c != s + count; ++c) {
3233 size_type position = rfind(*c, pos);
3234 if (position != npos) {
3236 if (position > last_of)
3257 template <
typename CharT,
typename Traits>
3258 typename basic_string<CharT, Traits>::size_type
3261 return find_last_of(s, pos, traits_type::length(s));
3273 template <
typename CharT,
typename Traits>
3274 typename basic_string<CharT, Traits>::size_type
3278 return rfind(ch, pos);
3290 template <
typename CharT,
typename Traits>
3291 typename basic_string<CharT, Traits>::size_type
3293 size_type pos)
const noexcept
3295 return find_last_not_of(str.cdata(), pos, str.size());
3311 template <
typename CharT,
typename Traits>
3312 typename basic_string<CharT, Traits>::size_type
3314 size_type count)
const
3317 pos = (std::min)(pos, size() - 1);
3319 if (!traits_type::find(s, count, *(cdata() + pos)))
3322 }
while (pos-- > 0);
3339 template <
typename CharT,
typename Traits>
3340 typename basic_string<CharT, Traits>::size_type
3342 size_type pos)
const
3344 return find_last_not_of(s, pos, traits_type::length(s));
3356 template <
typename CharT,
typename Traits>
3357 typename basic_string<CharT, Traits>::size_type
3361 return find_last_not_of(&ch, pos, 1);
3372 template <
typename CharT,
typename Traits>
3376 return compare(0, size(), other.
cdata(), other.
size());
3387 template <
typename CharT,
typename Traits>
3390 const std::basic_string<CharT> &other)
const
3392 return compare(0, size(), other.data(), other.size());
3408 template <
typename CharT,
typename Traits>
3413 return compare(pos, count, other.
cdata(), other.
size());
3430 template <
typename CharT,
typename Traits>
3433 size_type pos, size_type count,
3434 const std::basic_string<CharT> &other)
const
3436 return compare(pos, count, other.data(), other.size());
3457 template <
typename CharT,
typename Traits>
3461 size_type count2)
const
3463 if (pos2 > other.
size())
3464 throw std::out_of_range(
"Index out of range.");
3466 if (count2 > other.
size() - pos2)
3467 count2 = other.
size() - pos2;
3469 return compare(pos1, count1, other.
cdata() + pos2, count2);
3490 template <
typename CharT,
typename Traits>
3493 const std::basic_string<CharT> &other,
3494 size_type pos2, size_type count2)
const
3496 if (pos2 > other.size())
3497 throw std::out_of_range(
"Index out of range.");
3499 if (count2 > other.size() - pos2)
3500 count2 = other.size() - pos2;
3502 return compare(pos1, count1, other.data() + pos2, count2);
3513 template <
typename CharT,
typename Traits>
3517 return compare(0, size(), s, traits_type::length(s));
3533 template <
typename CharT,
typename Traits>
3536 const CharT *s)
const
3538 return compare(pos, count, s, traits_type::length(s));
3544 template <
typename CharT,
typename Traits>
3548 return is_sso_used() ? sso_data().cdata() : non_sso_data().cdata();
3554 template <
typename CharT,
typename Traits>
3564 template <
typename CharT,
typename Traits>
3574 template <
typename CharT,
typename Traits>
3575 typename basic_string<CharT, Traits>::size_type
3584 template <
typename CharT,
typename Traits>
3585 typename basic_string<CharT, Traits>::size_type
3588 return PMEMOBJ_MAX_ALLOC_SIZE /
sizeof(CharT) - 1;
3595 template <
typename CharT,
typename Traits>
3596 typename basic_string<CharT, Traits>::size_type
3599 return is_sso_used() ? sso_capacity : non_sso_data().capacity() - 1;
3621 template <
typename CharT,
typename Traits>
3625 if (count > max_size())
3626 throw std::length_error(
"Count exceeds max size.");
3630 auto pop = get_pool();
3634 append(count - sz, ch);
3635 }
else if (is_sso_used()) {
3636 set_sso_size(count);
3637 sso_data()[count] = value_type(
'\0');
3639 non_sso_data().resize(count + 1, ch);
3640 non_sso_data().back() = value_type(
'\0');
3663 template <
typename CharT,
typename Traits>
3667 resize(count, CharT());
3690 template <
typename CharT,
typename Traits>
3694 if (new_cap > max_size())
3695 throw std::length_error(
"New capacity exceeds max size.");
3697 if (new_cap < capacity() || new_cap <= sso_capacity)
3700 if (is_sso_used()) {
3701 auto pop = get_pool();
3705 non_sso_data().reserve(new_cap + 1);
3722 template <
typename CharT,
typename Traits>
3729 if (size() <= sso_capacity) {
3730 auto pop = get_pool();
3734 non_sso_data().shrink_to_fit();
3747 template <
typename CharT,
typename Traits>
3757 template <
typename CharT,
typename Traits>
3764 template <
typename CharT,
typename Traits>
3768 return (sso._size & _sso_mask) != 0;
3771 template <
typename CharT,
typename Traits>
3773 basic_string<CharT, Traits>::destroy_data()
3775 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3777 if (is_sso_used()) {
3778 add_sso_to_tx(0, get_sso_size() + 1);
3781 non_sso_data().free_data();
3782 detail::destroy<non_sso_type>(non_sso_data());
3792 template <
typename CharT,
typename Traits>
3793 template <
typename InputIt,
typename Enable>
3794 typename basic_string<CharT, Traits>::size_type
3797 return static_cast<size_type
>(std::distance(first, last));
3806 template <
typename CharT,
typename Traits>
3807 typename basic_string<CharT, Traits>::size_type
3819 template <
typename CharT,
typename Traits>
3820 typename basic_string<CharT, Traits>::size_type
3823 return other.
size();
3833 template <
typename CharT,
typename Traits>
3834 template <
typename... Args>
3835 typename basic_string<CharT, Traits>::pointer
3838 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3840 auto new_size = get_size(std::forward<Args>(args)...);
3843 if (!is_sso_used() && new_size <= capacity())
3844 return assign_large_data(std::forward<Args>(args)...);
3849 return initialize(std::forward<Args>(args)...);
3863 template <
typename CharT,
typename Traits>
3864 template <
typename... Args>
3865 typename basic_string<CharT, Traits>::pointer
3868 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3870 auto size = get_size(std::forward<Args>(args)...);
3872 if (is_sso_used()) {
3873 auto ptr = assign_sso_data(std::forward<Args>(args)...);
3878 return assign_large_data(std::forward<Args>(args)...);
3891 template <
typename CharT,
typename Traits>
3895 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3897 if (capacity <= sso_capacity) {
3907 if (!is_sso_used()) {
3908 detail::conditional_add_to_tx(&non_sso_data(), 1,
3909 POBJ_XADD_NO_SNAPSHOT);
3910 detail::create<non_sso_type>(&non_sso_data());
3911 non_sso_data().reserve(capacity + 1);
3918 template <
typename CharT,
typename Traits>
3919 template <
typename InputIt,
typename Enable>
3920 typename basic_string<CharT, Traits>::pointer
3923 auto size =
static_cast<size_type
>(std::distance(first, last));
3925 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3926 assert(size <= sso_capacity);
3928 add_sso_to_tx(0, size + 1);
3929 std::copy(first, last, &sso_data()._data[0]);
3931 sso_data()._data[size] = value_type(
'\0');
3933 return &sso_data()[0];
3939 template <
typename CharT,
typename Traits>
3940 typename basic_string<CharT, Traits>::pointer
3943 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3944 assert(count <= sso_capacity);
3946 add_sso_to_tx(0, count + 1);
3947 traits_type::assign(&sso_data()._data[0], count, ch);
3949 sso_data()._data[count] = value_type(
'\0');
3951 return &sso_data()[0];
3957 template <
typename CharT,
typename Traits>
3958 typename basic_string<CharT, Traits>::pointer
3961 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3963 return assign_sso_data(other.cbegin(), other.cend());
3970 template <
typename CharT,
typename Traits>
3971 template <
typename InputIt,
typename Enable>
3972 typename basic_string<CharT, Traits>::pointer
3975 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3977 auto size =
static_cast<size_type
>(std::distance(first, last));
3979 non_sso_data().reserve(size + 1);
3980 non_sso_data().assign(first, last);
3981 non_sso_data().push_back(value_type(
'\0'));
3983 return non_sso_data().data();
3990 template <
typename CharT,
typename Traits>
3991 typename basic_string<CharT, Traits>::pointer
3994 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3996 non_sso_data().reserve(count + 1);
3997 non_sso_data().assign(count, ch);
3998 non_sso_data().push_back(value_type(
'\0'));
4000 return non_sso_data().data();
4007 template <
typename CharT,
typename Traits>
4008 typename basic_string<CharT, Traits>::pointer
4011 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4013 if (other.is_sso_used())
4014 return assign_large_data(other.cbegin(), other.cend());
4016 non_sso_data() = std::move(other.non_sso_data());
4018 return non_sso_data().data();
4024 template <
typename CharT,
typename Traits>
4028 auto pop = pmemobj_pool_by_ptr(
this);
4029 assert(pop !=
nullptr);
4037 template <
typename CharT,
typename Traits>
4041 if (pmemobj_pool_by_ptr(
this) ==
nullptr)
4048 template <
typename CharT,
typename Traits>
4052 if (pmemobj_tx_stage() != TX_STAGE_WORK)
4054 "Call made out of transaction scope.");
4061 template <
typename CharT,
typename Traits>
4066 check_tx_stage_work();
4072 template <
typename CharT,
typename Traits>
4075 size_type num)
const
4077 assert(idx_first + num <= sso_capacity + 1);
4078 assert(is_sso_used());
4080 auto initialized_num = get_sso_size() + 1 - idx_first;
4083 detail::conditional_add_to_tx(&sso_data()._data[0] + idx_first,
4084 (std::min)(initialized_num, num));
4086 if (num > initialized_num) {
4088 detail::conditional_add_to_tx(
4089 &sso_data()._data[0] + get_sso_size() + 1,
4090 num - initialized_num, POBJ_XADD_NO_SNAPSHOT);
4097 template <
typename CharT,
typename Traits>
4098 typename basic_string<CharT, Traits>::size_type
4101 return sso._size & ~_sso_mask;
4107 template <
typename CharT,
typename Traits>
4113 sso._size |= (size_type)(_sso_mask);
4119 template <
typename CharT,
typename Traits>
4123 sso._size &= ~_sso_mask;
4129 template <
typename CharT,
typename Traits>
4133 sso._size = new_size | _sso_mask;
4147 template <
typename CharT,
typename Traits>
4151 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4152 assert(new_capacity > sso_capacity);
4153 assert(is_sso_used());
4159 tmp[sz] = value_type(
'\0');
4162 allocate(new_capacity);
4169 assert(!is_sso_used());
4181 template <
typename CharT,
typename Traits>
4185 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4186 assert(!is_sso_used());
4190 assert(sz <= sso_capacity);
4194 tmp[sz] = value_type(
'\0');
4204 assert(is_sso_used());
4207 template <
typename CharT,
typename Traits>
4211 assert(!is_sso_used());
4212 return non_sso._data;
4215 template <
typename CharT,
typename Traits>
4216 typename basic_string<CharT, Traits>::sso_type &
4217 basic_string<CharT, Traits>::sso_data()
4219 assert(is_sso_used());
4223 template <
typename CharT,
typename Traits>
4224 const typename basic_string<CharT, Traits>::non_sso_type &
4225 basic_string<CharT, Traits>::non_sso_data()
const
4227 assert(!is_sso_used());
4228 return non_sso._data;
4231 template <
typename CharT,
typename Traits>
4232 const typename basic_string<CharT, Traits>::sso_type &
4233 basic_string<CharT, Traits>::sso_data()
const
4235 assert(is_sso_used());
4243 template <
typename CharT,
typename Traits>
4244 template <
typename T,
typename Enable>
4245 basic_string<CharT, Traits> &
4248 return erase(
static_cast<size_type
>(param));
4255 template <
typename CharT,
typename Traits>
4256 template <
typename T,
typename Enable>
4260 return erase(
static_cast<const_iterator
>(param));
4268 template <
typename CharT,
typename Traits>
4269 template <
typename T,
typename Enable>
4273 return insert(
static_cast<size_type
>(param), count, ch);
4281 template <
typename CharT,
typename Traits>
4282 template <
typename T,
typename Enable>
4286 return insert(
static_cast<const_iterator
>(param), count, ch);
4292 template <
class CharT,
class Traits>
4303 template <
class CharT,
class Traits>
4314 template <
class CharT,
class Traits>
4325 template <
class CharT,
class Traits>
4336 template <
class CharT,
class Traits>
4347 template <
class CharT,
class Traits>
4358 template <
class CharT,
class Traits>
4368 template <
class CharT,
class Traits>
4378 template <
class CharT,
class Traits>
4388 template <
class CharT,
class Traits>
4398 template <
class CharT,
class Traits>
4408 template <
class CharT,
class Traits>
4418 template <
class CharT,
class Traits>
4428 template <
class CharT,
class Traits>
4438 template <
class CharT,
class Traits>
4448 template <
class CharT,
class Traits>
4458 template <
class CharT,
class Traits>
4468 template <
class CharT,
class Traits>
4478 template <
class CharT,
class Traits>
4489 template <
class CharT,
class Traits>
4500 template <
class CharT,
class Traits>
4502 operator<(
const std::basic_string<CharT, Traits> &lhs,
4511 template <
class CharT,
class Traits>
4513 operator<=(
const std::basic_string<CharT, Traits> &lhs,
4522 template <
class CharT,
class Traits>
4533 template <
class CharT,
class Traits>
4544 template <
class CharT,
class Traits>
4547 const std::basic_string<CharT, Traits> &rhs)
4555 template <
class CharT,
class Traits>
4558 const std::basic_string<CharT, Traits> &rhs)
4566 template <
class CharT,
class Traits>
4569 const std::basic_string<CharT, Traits> &rhs)
4577 template <
class CharT,
class Traits>
4580 const std::basic_string<CharT, Traits> &rhs)
4588 template <
class CharT,
class Traits>
4591 const std::basic_string<CharT, Traits> &rhs)
4599 template <
class CharT,
class Traits>
4602 const std::basic_string<CharT, Traits> &rhs)