9 #ifndef LIBPMEMOBJ_CPP_BASIC_STRING_HPP
10 #define LIBPMEMOBJ_CPP_BASIC_STRING_HPP
40 template <
typename CharT,
typename Traits = std::
char_traits<CharT>>
44 using traits_type = Traits;
45 using value_type = CharT;
46 using size_type = std::size_t;
47 using difference_type = std::ptrdiff_t;
48 using reference = value_type &;
49 using const_reference =
const value_type &;
50 using pointer = value_type *;
51 using const_pointer =
const value_type *;
53 using const_iterator = const_pointer;
54 using reverse_iterator = std::reverse_iterator<iterator>;
55 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
56 using for_each_ptr_function =
60 static constexpr size_type sso_capacity = (32 - 8) /
sizeof(CharT) - 1;
66 size_type count = npos);
67 basic_string(
const std::basic_string<CharT> &other, size_type pos,
68 size_type count = npos);
73 typename Enable =
typename std::enable_if<
97 size_type count = npos);
99 size_type pos, size_type count = npos);
102 template <
typename InputIt,
110 reference
at(size_type n);
111 const_reference
at(size_type n)
const;
112 const_reference
const_at(size_type n)
const;
114 const_reference
operator[](size_type n)
const;
116 const CharT &
front()
const;
117 const CharT &
cfront()
const;
119 const CharT &
back()
const;
120 const CharT &
cback()
const;
122 const CharT *
data()
const noexcept;
123 const CharT *
cdata()
const noexcept;
124 const CharT *
c_str()
const noexcept;
129 const_iterator
begin()
const noexcept;
130 const_iterator
cbegin()
const noexcept;
132 const_iterator
end()
const noexcept;
133 const_iterator
cend()
const noexcept;
134 reverse_iterator
rbegin();
135 const_reverse_iterator
rbegin()
const noexcept;
136 const_reverse_iterator
crbegin()
const noexcept;
137 reverse_iterator
rend();
138 const_reverse_iterator
rend()
const noexcept;
139 const_reverse_iterator
crend()
const noexcept;
142 bool empty()
const noexcept;
143 size_type
size()
const noexcept;
144 size_type
length()
const noexcept;
145 size_type
max_size()
const noexcept;
146 size_type
capacity()
const noexcept;
147 void resize(size_type count, CharT ch);
149 void reserve(size_type new_cap = 0);
159 template <
typename T,
160 typename Enable =
typename std::enable_if<
161 std::is_convertible<T, size_type>::value>::type>
163 template <
typename T,
164 typename Enable =
typename std::enable_if<
165 !std::is_convertible<T, size_type>::value>::type>
172 size_type count = npos);
175 template <
typename InputIt,
191 size_type index2, size_type count = npos);
194 template <
typename InputIt,
198 iterator insert(const_iterator pos, std::initializer_list<CharT> ilist);
199 template <
typename T,
200 typename Enable =
typename std::enable_if<
201 std::is_convertible<T, size_type>::value>::type>
203 template <
typename T,
204 typename Enable =
typename std::enable_if<
205 !std::is_convertible<T, size_type>::value>::type>
214 size_type count2 = npos);
215 template <
typename InputIt,
219 InputIt first2, InputIt last2);
221 const CharT *s, size_type count2);
225 size_type count2, CharT ch);
227 size_type count2, CharT ch);
232 std::initializer_list<CharT> ilist);
234 size_type
copy(CharT *s, size_type count, size_type index = 0)
const;
237 int compare(
const std::basic_string<CharT> &other)
const;
238 int compare(size_type pos, size_type count,
240 int compare(size_type pos, size_type count,
241 const std::basic_string<CharT> &other)
const;
243 size_type pos2, size_type count2 = npos)
const;
244 int compare(size_type pos1, size_type count1,
245 const std::basic_string<CharT> &other, size_type pos2,
246 size_type count2 = npos)
const;
247 int compare(
const CharT *s)
const;
248 int compare(size_type pos, size_type count,
const CharT *s)
const;
249 int compare(size_type pos, size_type count1,
const CharT *s,
250 size_type count2)
const;
255 size_type
find(
const CharT *s, size_type pos, size_type count)
const;
256 size_type
find(
const CharT *s, size_type pos = 0)
const;
257 size_type
find(CharT ch, size_type pos = 0)
const noexcept;
260 size_type
rfind(
const CharT *s, size_type pos, size_type count)
const;
261 size_type
rfind(
const CharT *s, size_type pos = npos)
const;
262 size_type
rfind(CharT ch, size_type pos = npos)
const noexcept;
264 size_type pos = 0)
const noexcept;
266 size_type count)
const;
267 size_type
find_first_of(
const CharT *s, size_type pos = 0)
const;
268 size_type
find_first_of(CharT ch, size_type pos = 0)
const noexcept;
270 size_type pos = 0)
const noexcept;
272 size_type count)
const;
276 size_type pos = npos)
const noexcept;
278 size_type count)
const;
279 size_type
find_last_of(
const CharT *s, size_type pos = npos)
const;
280 size_type
find_last_of(CharT ch, size_type pos = npos)
const noexcept;
282 size_type pos = npos)
const noexcept;
284 size_type count)
const;
292 static const size_type npos =
static_cast<size_type
>(-1);
336 static constexpr size_type _sso_mask = 1ULL
337 << (std::numeric_limits<size_type>::digits - 1);
340 bool is_sso_used()
const;
344 typename Enable =
typename std::enable_if<
346 size_type
get_size(InputIt first, InputIt last)
const;
347 size_type
get_size(size_type count, value_type ch)
const;
349 template <
typename... Args>
351 template <
typename... Args>
356 typename Enable =
typename std::enable_if<
363 typename Enable =
typename std::enable_if<
381 non_sso_data()
const;
394 template <
typename CharT,
typename Traits>
401 initialize(0U, value_type(
'\0'));
418 template <
typename CharT,
typename Traits>
425 initialize(count, ch);
445 template <
typename CharT,
typename Traits>
447 size_type pos, size_type count)
452 if (pos > other.
size())
453 throw std::out_of_range(
"Index out of range.");
455 if (count == npos || pos + count > other.
size())
456 count = other.
size() - pos;
458 auto first =
static_cast<difference_type
>(pos);
459 auto last = first +
static_cast<difference_type
>(count);
462 initialize(other.
cbegin() + first, other.
cbegin() + last);
483 template <
typename CharT,
typename Traits>
485 size_type pos, size_type count)
490 if (pos > other.size())
491 throw std::out_of_range(
"Index out of range.");
493 if (count == npos || pos + count > other.size())
494 count = other.size() - pos;
496 auto first =
static_cast<difference_type
>(pos);
497 auto last = first +
static_cast<difference_type
>(count);
500 initialize(other.cbegin() + first, other.cbegin() + last);
518 template <
typename CharT,
typename Traits>
525 initialize(s, s + count);
541 template <
typename CharT,
typename Traits>
547 auto length = traits_type::length(s);
550 initialize(s, s + length);
569 template <
typename CharT,
typename Traits>
570 template <
typename InputIt,
typename Enable>
573 auto len = std::distance(first, last);
579 allocate(
static_cast<size_type
>(len));
580 initialize(first, last);
597 template <
typename CharT,
typename Traits>
603 allocate(other.
size());
622 template <
typename CharT,
typename Traits>
642 template <
typename CharT,
typename Traits>
648 move_data(std::move(other));
665 template <
typename CharT,
typename Traits>
671 allocate(ilist.size());
672 initialize(ilist.begin(), ilist.end());
678 template <
typename CharT,
typename Traits>
697 template <
typename CharT,
typename Traits>
701 return assign(other);
714 template <
typename CharT,
typename Traits>
718 return assign(other);
730 template <
typename CharT,
typename Traits>
734 return assign(std::move(other));
745 template <
typename CharT,
typename Traits>
760 template <
typename CharT,
typename Traits>
764 return assign(1, ch);
776 template <
typename CharT,
typename Traits>
780 return assign(ilist);
793 template <
typename CharT,
typename Traits>
797 auto pop = get_pool();
813 template <
typename CharT,
typename Traits>
820 auto pop = get_pool();
823 pop, [&] { replace_content(other.
cbegin(), other.
cend()); });
838 template <
typename CharT,
typename Traits>
842 return assign(other.cbegin(), other.cend());
857 template <
typename CharT,
typename Traits>
862 if (pos > other.
size())
863 throw std::out_of_range(
"Index out of range.");
865 if (count == npos || pos + count > other.
size())
866 count = other.
size() - pos;
868 auto pop = get_pool();
869 auto first =
static_cast<difference_type
>(pos);
870 auto last = first +
static_cast<difference_type
>(count);
873 replace_content(other.
cbegin() + first, other.
cbegin() + last);
893 template <
typename CharT,
typename Traits>
896 size_type pos, size_type count)
898 if (pos > other.size())
899 throw std::out_of_range(
"Index out of range.");
901 if (count == npos || pos + count > other.size())
902 count = other.size() - pos;
904 return assign(other.c_str() + pos, count);
917 template <
typename CharT,
typename Traits>
921 auto pop = get_pool();
936 template <
typename CharT,
typename Traits>
940 auto pop = get_pool();
942 auto length = traits_type::length(s);
960 template <
typename CharT,
typename Traits>
961 template <
typename InputIt,
typename Enable>
965 auto pop = get_pool();
981 template <
typename CharT,
typename Traits>
988 auto pop = get_pool();
992 move_data(std::move(other));
1007 template <
typename CharT,
typename Traits>
1011 return assign(ilist.begin(), ilist.end());
1021 template <
typename CharT,
typename Traits>
1025 if (!is_sso_used()) {
1026 non_sso._data.for_each_ptr(func);
1035 template <
typename CharT,
typename Traits>
1048 template <
typename CharT,
typename Traits>
1049 typename basic_string<CharT, Traits>::const_iterator
1060 template <
typename CharT,
typename Traits>
1061 typename basic_string<CharT, Traits>::const_iterator
1064 return is_sso_used() ? const_iterator(&*sso_data().
cbegin())
1065 : const_iterator(&*non_sso_data().
cbegin());
1073 template <
typename CharT,
typename Traits>
1077 return begin() +
static_cast<difference_type
>(size());
1086 template <
typename CharT,
typename Traits>
1087 typename basic_string<CharT, Traits>::const_iterator
1090 return cbegin() +
static_cast<difference_type
>(size());
1099 template <
typename CharT,
typename Traits>
1100 typename basic_string<CharT, Traits>::const_iterator
1103 return cbegin() +
static_cast<difference_type
>(size());
1112 template <
typename CharT,
typename Traits>
1113 typename basic_string<CharT, Traits>::reverse_iterator
1116 return reverse_iterator(
end());
1125 template <
typename CharT,
typename Traits>
1126 typename basic_string<CharT, Traits>::const_reverse_iterator
1138 template <
typename CharT,
typename Traits>
1139 typename basic_string<CharT, Traits>::const_reverse_iterator
1142 return const_reverse_iterator(
cend());
1151 template <
typename CharT,
typename Traits>
1152 typename basic_string<CharT, Traits>::reverse_iterator
1155 return reverse_iterator(
begin());
1164 template <
typename CharT,
typename Traits>
1165 typename basic_string<CharT, Traits>::const_reverse_iterator
1177 template <
typename CharT,
typename Traits>
1178 typename basic_string<CharT, Traits>::const_reverse_iterator
1181 return const_reverse_iterator(
cbegin());
1197 template <
typename CharT,
typename Traits>
1198 typename basic_string<CharT, Traits>::reference
1202 throw std::out_of_range(
"string::at");
1204 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1217 template <
typename CharT,
typename Traits>
1218 typename basic_string<CharT, Traits>::const_reference
1237 template <
typename CharT,
typename Traits>
1238 typename basic_string<CharT, Traits>::const_reference
1242 throw std::out_of_range(
"string::const_at");
1244 return is_sso_used()
1245 ?
static_cast<const sso_type &
>(sso_data())[n]
1246 :
static_cast<const non_sso_type &
>(non_sso_data())[n];
1260 template <
typename CharT,
typename Traits>
1261 typename basic_string<CharT, Traits>::reference
1264 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1274 template <
typename CharT,
typename Traits>
1275 typename basic_string<CharT, Traits>::const_reference
1278 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1290 template <
typename CharT,
typename Traits>
1302 template <
typename CharT,
typename Traits>
1317 template <
typename CharT,
typename Traits>
1333 template <
typename CharT,
typename Traits>
1337 return (*
this)[size() - 1];
1345 template <
typename CharT,
typename Traits>
1360 template <
typename CharT,
typename Traits>
1364 return static_cast<const basic_string &
>(*this)[size() - 1];
1370 template <
typename CharT,
typename Traits>
1371 typename basic_string<CharT, Traits>::size_type
1375 return get_sso_size();
1376 else if (non_sso_data().size() == 0)
1379 return non_sso_data().size() - 1;
1388 template <
typename CharT,
typename Traits>
1392 return is_sso_used() ? sso_data().range(0, get_sso_size() + 1).begin()
1393 : non_sso_data().data();
1414 template <
typename CharT,
typename Traits>
1421 throw std::out_of_range(
"Index exceeds size.");
1423 count = (std::min)(count, sz - index);
1425 auto pop = get_pool();
1427 auto first =
begin() +
static_cast<difference_type
>(index);
1428 auto last = first +
static_cast<difference_type
>(count);
1430 if (is_sso_used()) {
1432 auto move_len = sz - index - count;
1433 auto new_size = sz - count;
1437 sso_data().range(index, move_len + 1);
1438 traits_type::move(range.begin(), &*last,
1441 assert(range.end() - 1 ==
1442 &sso_data()._data[index + move_len]);
1445 sso_data()[index + move_len] = value_type(
'\0');
1446 set_sso_size(new_size);
1449 non_sso_data().erase(first, last);
1471 template <
typename CharT,
typename Traits>
1475 return erase(pos, pos + 1);
1496 template <
typename CharT,
typename Traits>
1501 static_cast<size_type
>(std::distance(
cbegin(), first));
1502 size_type len =
static_cast<size_type
>(std::distance(first, last));
1506 return begin() +
static_cast<difference_type
>(index);
1519 template <
typename CharT,
typename Traits>
1523 erase(size() - 1, 1);
1545 template <
typename CharT,
typename Traits>
1550 auto new_size = sz + count;
1552 if (new_size > max_size())
1553 throw std::length_error(
"Size exceeds max size.");
1555 if (is_sso_used()) {
1556 auto pop = get_pool();
1559 if (new_size > sso_capacity) {
1560 sso_to_large(new_size);
1562 non_sso_data().insert(
1563 non_sso_data().
cbegin() +
1564 static_cast<difference_type
>(
1568 add_sso_to_tx(sz, count + 1);
1569 traits_type::assign(&sso_data()._data[sz],
1572 assert(new_size == sz + count);
1573 set_sso_size(new_size);
1574 sso_data()._data[new_size] = value_type(
'\0');
1578 non_sso_data().insert(non_sso_data().
cbegin() +
1579 static_cast<difference_type
>(sz),
1604 template <
typename CharT,
typename Traits>
1608 return append(str.
data(), str.
size());
1636 template <
typename CharT,
typename Traits>
1641 auto sz = str.
size();
1644 throw std::out_of_range(
"Index out of range.");
1646 count = (std::min)(count, sz - pos);
1648 append(str.
data() + pos, count);
1672 template <
typename CharT,
typename Traits>
1676 return append(s, s + count);
1698 template <
typename CharT,
typename Traits>
1702 return append(s, traits_type::length(s));
1726 template <
typename CharT,
typename Traits>
1727 template <
typename InputIt,
typename Enable>
1732 auto count =
static_cast<size_type
>(std::distance(first, last));
1733 auto new_size = sz + count;
1735 if (new_size > max_size())
1736 throw std::length_error(
"Size exceeds max size.");
1738 if (is_sso_used()) {
1739 auto pop = get_pool();
1742 if (new_size > sso_capacity) {
1751 std::vector<value_type> str(first, last);
1753 sso_to_large(new_size);
1754 non_sso_data().insert(
1755 non_sso_data().
cbegin() +
1756 static_cast<difference_type
>(
1758 str.begin(), str.end());
1760 add_sso_to_tx(sz, count + 1);
1761 std::copy(first, last, &sso_data()._data[sz]);
1763 assert(new_size == sz + count);
1764 set_sso_size(new_size);
1765 sso_data()._data[new_size] = value_type(
'\0');
1769 non_sso_data().insert(non_sso_data().
cbegin() +
1770 static_cast<difference_type
>(sz),
1795 template <
typename CharT,
typename Traits>
1799 return append(ilist.begin(), ilist.end());
1818 template <
typename CharT,
typename Traits>
1822 append(
static_cast<size_type
>(1), ch);
1843 template <
typename CharT,
typename Traits>
1869 template <
typename CharT,
typename Traits>
1892 template <
typename CharT,
typename Traits>
1919 template <
typename CharT,
typename Traits>
1923 return append(ilist);
1947 template <
typename CharT,
typename Traits>
1952 throw std::out_of_range(
"Index out of range.");
1954 auto pos =
cbegin() +
static_cast<difference_type
>(index);
1956 insert(pos, count, ch);
1982 template <
typename CharT,
typename Traits>
1986 return insert(index, s, traits_type::length(s));
2010 template <
typename CharT,
typename Traits>
2016 throw std::out_of_range(
"Index out of range.");
2018 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2020 insert(pos, s, s + count);
2045 template <
typename CharT,
typename Traits>
2049 return insert(index, str.
data(), str.
size());
2074 template <
typename CharT,
typename Traits>
2077 size_type index2, size_type count)
2079 auto sz = str.
size();
2081 if (index1 > size() || index2 > sz)
2082 throw std::out_of_range(
"Index out of range.");
2084 count = (std::min)(count, sz - index2);
2086 return insert(index1, str.
data() + index2, count);
2111 template <
typename CharT,
typename Traits>
2115 return insert(pos, 1, ch);
2142 template <
typename CharT,
typename Traits>
2149 if (sz + count > max_size())
2150 throw std::length_error(
"Count exceeds max size.");
2152 auto new_size = sz + count;
2154 auto pop = get_pool();
2156 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2159 if (is_sso_used() && new_size <= sso_capacity) {
2160 auto len = sz - index;
2162 add_sso_to_tx(index, len + count + 1);
2164 traits_type::move(&sso_data()._data[index + count],
2165 &sso_data()._data[index], len);
2166 traits_type::assign(&sso_data()._data[index], count,
2169 assert(new_size == index + len + count);
2170 set_sso_size(new_size);
2171 sso_data()._data[new_size] = value_type(
'\0');
2174 sso_to_large(new_size);
2176 non_sso_data().insert(
2177 non_sso_data().
begin() +
2178 static_cast<difference_type
>(index),
2183 return iterator(&data()[
static_cast<difference_type
>(index)]);
2210 template <
typename CharT,
typename Traits>
2211 template <
typename InputIt,
typename Enable>
2218 auto count =
static_cast<size_type
>(std::distance(first, last));
2220 if (sz + count > max_size())
2221 throw std::length_error(
"Count exceeds max size.");
2223 auto pop = get_pool();
2225 auto new_size = sz + count;
2227 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2230 if (is_sso_used() && new_size <= sso_capacity) {
2231 auto len = sz - index;
2233 add_sso_to_tx(index, len + count + 1);
2235 traits_type::move(&sso_data()._data[index + count],
2236 &sso_data()._data[index], len);
2237 std::copy(first, last, &sso_data()._data[index]);
2239 assert(new_size == index + len + count);
2240 set_sso_size(new_size);
2241 sso_data()._data[new_size] = value_type(
'\0');
2243 if (is_sso_used()) {
2252 std::vector<value_type> str(first, last);
2254 sso_to_large(new_size);
2255 non_sso_data().insert(
2256 non_sso_data().
begin() +
2257 static_cast<difference_type
>(
2259 str.begin(), str.end());
2261 non_sso_data().insert(
2262 non_sso_data().
begin() +
2263 static_cast<difference_type
>(
2270 return iterator(&data()[
static_cast<difference_type
>(index)]);
2296 template <
typename CharT,
typename Traits>
2299 std::initializer_list<CharT> ilist)
2301 return insert(pos, ilist.begin(), ilist.end());
2326 template <
typename CharT,
typename Traits>
2331 return replace(index, count, str.
data(), str.
size());
2354 template <
typename CharT,
typename Traits>
2359 return replace(first, last, str.
data(), str.
data() + str.
size());
2388 template <
typename CharT,
typename Traits>
2394 auto sz = str.
size();
2397 throw std::out_of_range(
"Index out of range.");
2399 count2 = (std::min)(count2, sz - index2);
2401 return replace(index, count, str.
data() + index2, count2);
2429 template <
typename CharT,
typename Traits>
2430 template <
typename InputIt,
typename Enable>
2433 InputIt first2, InputIt last2)
2436 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2437 auto count =
static_cast<size_type
>(std::distance(first, last));
2438 auto count2 =
static_cast<size_type
>(std::distance(first2, last2));
2440 count = (std::min)(count, sz - index);
2442 if (sz - count + count2 > max_size())
2443 throw std::length_error(
"Count exceeds max size.");
2445 auto new_size = sz - count + count2;
2447 auto pop = get_pool();
2450 if (is_sso_used() && new_size <= sso_capacity) {
2451 add_sso_to_tx(index, new_size - index + 1);
2453 assert(count2 < new_size + 1);
2454 traits_type::move(&sso_data()._data[index + count2],
2455 &sso_data()._data[index + count],
2456 sz - index - count);
2457 std::copy(first2, last2, &sso_data()._data[index]);
2459 set_sso_size(new_size);
2460 sso_data()._data[new_size] = value_type(
'\0');
2470 std::vector<value_type> str(first2, last2);
2472 if (is_sso_used()) {
2473 sso_to_large(new_size);
2477 begin() +
static_cast<difference_type
>(index);
2478 auto end = beg +
static_cast<difference_type
>(count);
2479 non_sso_data().erase(beg,
end);
2480 non_sso_data().insert(beg, str.begin(), str.end());
2483 if (!is_sso_used() && new_size <= sso_capacity)
2512 template <
typename CharT,
typename Traits>
2515 const CharT *s, size_type count2)
2517 return replace(first, last, s, s + count2);
2543 template <
typename CharT,
typename Traits>
2546 const CharT *s, size_type count2)
2549 throw std::out_of_range(
"Index out of range.");
2551 auto first =
cbegin() +
static_cast<difference_type
>(index);
2552 auto last = first +
static_cast<difference_type
>(count);
2554 return replace(first, last, s, s + count2);
2580 template <
typename CharT,
typename Traits>
2585 return replace(index, count, s, traits_type::length(s));
2611 template <
typename CharT,
typename Traits>
2614 size_type count2, CharT ch)
2617 throw std::out_of_range(
"Index out of range.");
2619 auto first =
cbegin() +
static_cast<difference_type
>(index);
2620 auto last = first +
static_cast<difference_type
>(count);
2622 return replace(first, last, count2, ch);
2647 template <
typename CharT,
typename Traits>
2650 size_type count2, CharT ch)
2653 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2654 auto count =
static_cast<size_type
>(std::distance(first, last));
2656 count = (std::min)(count, sz - index);
2658 if (sz - count + count2 > max_size())
2659 throw std::length_error(
"Count exceeds max size.");
2661 auto new_size = sz - count + count2;
2663 auto pop = get_pool();
2666 if (is_sso_used() && new_size <= sso_capacity) {
2667 add_sso_to_tx(index, new_size - index + 1);
2669 assert(count2 < new_size + 1);
2670 traits_type::move(&sso_data()._data[index + count2],
2671 &sso_data()._data[index + count],
2672 sz - index - count);
2673 traits_type::assign(&sso_data()._data[index], count2,
2676 set_sso_size(new_size);
2677 sso_data()._data[new_size] = value_type(
'\0');
2679 if (is_sso_used()) {
2680 sso_to_large(new_size);
2684 begin() +
static_cast<difference_type
>(index);
2685 auto end = beg +
static_cast<difference_type
>(count);
2686 non_sso_data().erase(beg,
end);
2687 non_sso_data().insert(beg, count2, ch);
2690 if (!is_sso_used() && new_size <= sso_capacity)
2718 template <
typename CharT,
typename Traits>
2723 return replace(first, last, s, traits_type::length(s));
2748 template <
typename CharT,
typename Traits>
2751 std::initializer_list<CharT> ilist)
2753 return replace(first, last, ilist.begin(), ilist.end());
2769 template <
typename CharT,
typename Traits>
2770 typename basic_string<CharT, Traits>::size_type
2772 size_type index)
const
2777 throw std::out_of_range(
"Index out of range.");
2779 auto len = (std::min)(count, sz - index);
2781 traits_type::copy(s, data() + index, len);
2803 template <
typename CharT,
typename Traits>
2806 const CharT *s, size_type count2)
const
2809 throw std::out_of_range(
"Index out of range.");
2811 if (count1 > size() - pos)
2812 count1 = size() - pos;
2814 auto ret = traits_type::compare(cdata() + pos, s,
2815 std::min<size_type>(count1, count2));
2820 if (count1 < count2)
2822 else if (count1 == count2)
2837 template <
typename CharT,
typename Traits>
2838 typename basic_string<CharT, Traits>::size_type
2842 return find(str.data(), pos, str.size());
2856 template <
typename CharT,
typename Traits>
2857 typename basic_string<CharT, Traits>::size_type
2859 size_type count)
const
2869 while (pos + count <= sz) {
2870 auto found = traits_type::find(cdata() + pos, sz - pos, s[0]);
2873 pos =
static_cast<size_type
>(std::distance(cdata(), found));
2874 if (traits_type::compare(found, s, count) == 0) {
2892 template <
typename CharT,
typename Traits>
2893 typename basic_string<CharT, Traits>::size_type
2896 return find(s, pos, traits_type::length(s));
2908 template <
typename CharT,
typename Traits>
2909 typename basic_string<CharT, Traits>::size_type
2912 return find(&ch, pos, 1);
2925 template <
typename CharT,
typename Traits>
2926 typename basic_string<CharT, Traits>::size_type
2930 return rfind(str.cdata(), pos, str.size());
2949 template <
typename CharT,
typename Traits>
2950 typename basic_string<CharT, Traits>::size_type
2952 size_type count)
const
2954 if (count <= size()) {
2955 pos = (std::min)(size() - count, pos);
2957 if (traits_type::compare(cdata() + pos, s, count) == 0)
2959 }
while (pos-- > 0);
2976 template <
typename CharT,
typename Traits>
2977 typename basic_string<CharT, Traits>::size_type
2980 return rfind(s, pos, traits_type::length(s));
2994 template <
typename CharT,
typename Traits>
2995 typename basic_string<CharT, Traits>::size_type
2998 return rfind(&ch, pos, 1);
3010 template <
typename CharT,
typename Traits>
3011 typename basic_string<CharT, Traits>::size_type
3013 size_type pos)
const noexcept
3015 return find_first_of(str.cdata(), pos, str.size());
3031 template <
typename CharT,
typename Traits>
3032 typename basic_string<CharT, Traits>::size_type
3034 size_type count)
const
3036 size_type first_of = npos;
3037 for (
const CharT *c = s; c != s + count; ++c) {
3038 size_type found = find(*c, pos);
3039 if (found != npos && found < first_of)
3057 template <
typename CharT,
typename Traits>
3058 typename basic_string<CharT, Traits>::size_type
3061 return find_first_of(s, pos, traits_type::length(s));
3073 template <
typename CharT,
typename Traits>
3074 typename basic_string<CharT, Traits>::size_type
3078 return find(ch, pos);
3090 template <
typename CharT,
typename Traits>
3091 typename basic_string<CharT, Traits>::size_type
3093 size_type pos)
const noexcept
3095 return find_first_not_of(str.cdata(), pos, str.size());
3111 template <
typename CharT,
typename Traits>
3112 typename basic_string<CharT, Traits>::size_type
3114 size_type count)
const
3119 for (
auto it =
cbegin() + pos; it !=
cend(); ++it)
3120 if (!traits_type::find(s, count, *it))
3121 return static_cast<size_type
>(
3122 std::distance(
cbegin(), it));
3138 template <
typename CharT,
typename Traits>
3139 typename basic_string<CharT, Traits>::size_type
3141 size_type pos)
const
3143 return find_first_not_of(s, pos, traits_type::length(s));
3155 template <
typename CharT,
typename Traits>
3156 typename basic_string<CharT, Traits>::size_type
3160 return find_first_not_of(&ch, pos, 1);
3172 template <
typename CharT,
typename Traits>
3173 typename basic_string<CharT, Traits>::size_type
3175 size_type pos)
const noexcept
3177 return find_last_of(str.cdata(), pos, str.size());
3193 template <
typename CharT,
typename Traits>
3194 typename basic_string<CharT, Traits>::size_type
3196 size_type count)
const
3198 if (size() == 0 || count == 0)
3202 size_type last_of = 0;
3203 for (
const CharT *c = s; c != s + count; ++c) {
3204 size_type position = rfind(*c, pos);
3205 if (position != npos) {
3207 if (position > last_of)
3228 template <
typename CharT,
typename Traits>
3229 typename basic_string<CharT, Traits>::size_type
3232 return find_last_of(s, pos, traits_type::length(s));
3244 template <
typename CharT,
typename Traits>
3245 typename basic_string<CharT, Traits>::size_type
3249 return rfind(ch, pos);
3261 template <
typename CharT,
typename Traits>
3262 typename basic_string<CharT, Traits>::size_type
3264 size_type pos)
const noexcept
3266 return find_last_not_of(str.cdata(), pos, str.size());
3282 template <
typename CharT,
typename Traits>
3283 typename basic_string<CharT, Traits>::size_type
3285 size_type count)
const
3288 pos = (std::min)(pos, size() - 1);
3290 if (!traits_type::find(s, count, *(cdata() + pos)))
3293 }
while (pos-- > 0);
3310 template <
typename CharT,
typename Traits>
3311 typename basic_string<CharT, Traits>::size_type
3313 size_type pos)
const
3315 return find_last_not_of(s, pos, traits_type::length(s));
3327 template <
typename CharT,
typename Traits>
3328 typename basic_string<CharT, Traits>::size_type
3332 return find_last_not_of(&ch, pos, 1);
3343 template <
typename CharT,
typename Traits>
3347 return compare(0, size(), other.
cdata(), other.
size());
3358 template <
typename CharT,
typename Traits>
3361 const std::basic_string<CharT> &other)
const
3363 return compare(0, size(), other.data(), other.size());
3379 template <
typename CharT,
typename Traits>
3384 return compare(pos, count, other.
cdata(), other.
size());
3401 template <
typename CharT,
typename Traits>
3404 size_type pos, size_type count,
3405 const std::basic_string<CharT> &other)
const
3407 return compare(pos, count, other.data(), other.size());
3428 template <
typename CharT,
typename Traits>
3432 size_type count2)
const
3434 if (pos2 > other.
size())
3435 throw std::out_of_range(
"Index out of range.");
3437 if (count2 > other.
size() - pos2)
3438 count2 = other.
size() - pos2;
3440 return compare(pos1, count1, other.
cdata() + pos2, count2);
3461 template <
typename CharT,
typename Traits>
3464 const std::basic_string<CharT> &other,
3465 size_type pos2, size_type count2)
const
3467 if (pos2 > other.size())
3468 throw std::out_of_range(
"Index out of range.");
3470 if (count2 > other.size() - pos2)
3471 count2 = other.size() - pos2;
3473 return compare(pos1, count1, other.data() + pos2, count2);
3484 template <
typename CharT,
typename Traits>
3488 return compare(0, size(), s, traits_type::length(s));
3504 template <
typename CharT,
typename Traits>
3507 const CharT *s)
const
3509 return compare(pos, count, s, traits_type::length(s));
3515 template <
typename CharT,
typename Traits>
3519 return is_sso_used() ? sso_data().cdata() : non_sso_data().cdata();
3525 template <
typename CharT,
typename Traits>
3535 template <
typename CharT,
typename Traits>
3545 template <
typename CharT,
typename Traits>
3546 typename basic_string<CharT, Traits>::size_type
3555 template <
typename CharT,
typename Traits>
3556 typename basic_string<CharT, Traits>::size_type
3559 return PMEMOBJ_MAX_ALLOC_SIZE /
sizeof(CharT) - 1;
3566 template <
typename CharT,
typename Traits>
3567 typename basic_string<CharT, Traits>::size_type
3570 return is_sso_used() ? sso_capacity : non_sso_data().capacity() - 1;
3592 template <
typename CharT,
typename Traits>
3596 if (count > max_size())
3597 throw std::length_error(
"Count exceeds max size.");
3601 auto pop = get_pool();
3605 append(count - sz, ch);
3606 }
else if (is_sso_used()) {
3607 set_sso_size(count);
3608 sso_data()[count] = value_type(
'\0');
3610 non_sso_data().resize(count + 1, ch);
3611 non_sso_data().back() = value_type(
'\0');
3634 template <
typename CharT,
typename Traits>
3638 resize(count, CharT());
3661 template <
typename CharT,
typename Traits>
3665 if (new_cap > max_size())
3666 throw std::length_error(
"New capacity exceeds max size.");
3668 if (new_cap < capacity() || new_cap <= sso_capacity)
3671 if (is_sso_used()) {
3672 auto pop = get_pool();
3676 non_sso_data().reserve(new_cap + 1);
3693 template <
typename CharT,
typename Traits>
3700 if (size() <= sso_capacity) {
3701 auto pop = get_pool();
3705 non_sso_data().shrink_to_fit();
3718 template <
typename CharT,
typename Traits>
3737 template <
typename CharT,
typename Traits>
3741 auto pop = get_pool();
3744 if (is_sso_used()) {
3745 add_sso_to_tx(0, get_sso_size() + 1);
3749 non_sso_data().free_data();
3750 detail::destroy<non_sso_type>(non_sso_data());
3759 template <
typename CharT,
typename Traits>
3766 template <
typename CharT,
typename Traits>
3770 return (sso._size & _sso_mask) != 0;
3773 template <
typename CharT,
typename Traits>
3775 basic_string<CharT, Traits>::destroy_data()
3777 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3779 if (is_sso_used()) {
3780 add_sso_to_tx(0, get_sso_size() + 1);
3783 non_sso_data().free_data();
3784 detail::destroy<non_sso_type>(non_sso_data());
3794 template <
typename CharT,
typename Traits>
3795 template <
typename InputIt,
typename Enable>
3796 typename basic_string<CharT, Traits>::size_type
3799 return static_cast<size_type
>(std::distance(first, last));
3808 template <
typename CharT,
typename Traits>
3809 typename basic_string<CharT, Traits>::size_type
3821 template <
typename CharT,
typename Traits>
3822 typename basic_string<CharT, Traits>::size_type
3825 return other.
size();
3834 template <
typename CharT,
typename Traits>
3835 template <
typename... Args>
3836 typename basic_string<CharT, Traits>::pointer
3839 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3841 auto new_size = get_size(std::forward<Args>(args)...);
3844 if (!is_sso_used() && new_size <= capacity())
3845 return assign_large_data(std::forward<Args>(args)...);
3850 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 if (is_sso_used()) {
3871 return assign_sso_data(std::forward<Args>(args)...);
3873 return assign_large_data(std::forward<Args>(args)...);
3886 template <
typename CharT,
typename Traits>
3890 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3892 if (capacity <= sso_capacity) {
3902 if (!is_sso_used()) {
3903 detail::conditional_add_to_tx(&non_sso_data(), 1,
3904 POBJ_XADD_NO_SNAPSHOT);
3905 detail::create<non_sso_type>(&non_sso_data());
3906 non_sso_data().reserve(capacity + 1);
3913 template <
typename CharT,
typename Traits>
3914 template <
typename InputIt,
typename Enable>
3915 typename basic_string<CharT, Traits>::pointer
3918 auto size =
static_cast<size_type
>(std::distance(first, last));
3920 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3921 assert(size <= sso_capacity);
3923 add_sso_to_tx(0, size + 1);
3924 std::copy(first, last, &sso_data()._data[0]);
3926 sso_data()._data[size] = value_type(
'\0');
3930 return &sso_data()[0];
3936 template <
typename CharT,
typename Traits>
3937 typename basic_string<CharT, Traits>::pointer
3940 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3941 assert(count <= sso_capacity);
3943 add_sso_to_tx(0, count + 1);
3944 traits_type::assign(&sso_data()._data[0], count, ch);
3946 sso_data()._data[count] = value_type(
'\0');
3948 set_sso_size(count);
3950 return &sso_data()[0];
3957 template <
typename CharT,
typename Traits>
3958 template <
typename InputIt,
typename Enable>
3959 typename basic_string<CharT, Traits>::pointer
3962 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3964 auto size =
static_cast<size_type
>(std::distance(first, last));
3966 non_sso_data().reserve(size + 1);
3967 non_sso_data().assign(first, last);
3968 non_sso_data().push_back(value_type(
'\0'));
3970 return non_sso_data().data();
3977 template <
typename CharT,
typename Traits>
3978 typename basic_string<CharT, Traits>::pointer
3981 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3983 non_sso_data().reserve(count + 1);
3984 non_sso_data().assign(count, ch);
3985 non_sso_data().push_back(value_type(
'\0'));
3987 return non_sso_data().data();
3994 template <
typename CharT,
typename Traits>
3995 typename basic_string<CharT, Traits>::pointer
3998 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4000 typename basic_string::pointer ptr;
4002 if (other.size() <= sso_capacity) {
4004 ptr = assign_sso_data(other.cbegin(), other.cend());
4007 detail::conditional_add_to_tx(&non_sso_data(), 1,
4008 POBJ_XADD_NO_SNAPSHOT);
4009 detail::create<non_sso_type>(&non_sso_data());
4011 assert(!other.is_sso_used());
4012 non_sso_data() = std::move(other.non_sso_data());
4014 ptr = non_sso_data().data();
4017 if (other.is_sso_used())
4018 other.initialize(0U, value_type(
'\0'));
4026 template <
typename CharT,
typename Traits>
4032 if (is_sso_used() && other.is_sso_used()) {
4033 sso_data().swap(other.sso_data());
4034 pmem::obj::swap(sso._size, other.sso._size);
4035 }
else if (!is_sso_used() && !other.is_sso_used()) {
4036 non_sso_data().swap(other.non_sso_data());
4038 basic_string *_short, *_long;
4039 if (size() > other.size()) {
4047 std::basic_string<CharT, Traits> tmp(_short->c_str(),
4058 template <
typename CharT,
typename Traits>
4062 auto pop = pmemobj_pool_by_ptr(
this);
4063 assert(pop !=
nullptr);
4071 template <
typename CharT,
typename Traits>
4075 if (pmemobj_pool_by_ptr(
this) ==
nullptr)
4082 template <
typename CharT,
typename Traits>
4086 if (pmemobj_tx_stage() != TX_STAGE_WORK)
4088 "Call made out of transaction scope.");
4095 template <
typename CharT,
typename Traits>
4100 check_tx_stage_work();
4106 template <
typename CharT,
typename Traits>
4109 size_type num)
const
4111 assert(idx_first + num <= sso_capacity + 1);
4112 assert(is_sso_used());
4114 auto initialized_num = get_sso_size() + 1 - idx_first;
4117 detail::conditional_add_to_tx(&sso_data()._data[0] + idx_first,
4118 (std::min)(initialized_num, num));
4120 if (num > initialized_num) {
4122 detail::conditional_add_to_tx(
4123 &sso_data()._data[0] + get_sso_size() + 1,
4124 num - initialized_num, POBJ_XADD_NO_SNAPSHOT);
4131 template <
typename CharT,
typename Traits>
4132 typename basic_string<CharT, Traits>::size_type
4135 return sso._size & ~_sso_mask;
4141 template <
typename CharT,
typename Traits>
4147 sso._size |= (size_type)(_sso_mask);
4153 template <
typename CharT,
typename Traits>
4157 sso._size &= ~_sso_mask;
4163 template <
typename CharT,
typename Traits>
4167 sso._size = new_size | _sso_mask;
4181 template <
typename CharT,
typename Traits>
4185 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4186 assert(new_capacity > sso_capacity);
4187 assert(is_sso_used());
4193 tmp[sz] = value_type(
'\0');
4196 allocate(new_capacity);
4203 assert(!is_sso_used());
4215 template <
typename CharT,
typename Traits>
4219 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4220 assert(!is_sso_used());
4224 assert(sz <= sso_capacity);
4228 tmp[sz] = value_type(
'\0');
4238 assert(is_sso_used());
4241 template <
typename CharT,
typename Traits>
4245 assert(!is_sso_used());
4246 return non_sso._data;
4249 template <
typename CharT,
typename Traits>
4250 typename basic_string<CharT, Traits>::sso_type &
4251 basic_string<CharT, Traits>::sso_data()
4253 assert(is_sso_used());
4257 template <
typename CharT,
typename Traits>
4258 const typename basic_string<CharT, Traits>::non_sso_type &
4259 basic_string<CharT, Traits>::non_sso_data()
const
4261 assert(!is_sso_used());
4262 return non_sso._data;
4265 template <
typename CharT,
typename Traits>
4266 const typename basic_string<CharT, Traits>::sso_type &
4267 basic_string<CharT, Traits>::sso_data()
const
4269 assert(is_sso_used());
4277 template <
typename CharT,
typename Traits>
4278 template <
typename T,
typename Enable>
4279 basic_string<CharT, Traits> &
4282 return erase(
static_cast<size_type
>(param));
4289 template <
typename CharT,
typename Traits>
4290 template <
typename T,
typename Enable>
4294 return erase(
static_cast<const_iterator
>(param));
4302 template <
typename CharT,
typename Traits>
4303 template <
typename T,
typename Enable>
4307 return insert(
static_cast<size_type
>(param), count, ch);
4315 template <
typename CharT,
typename Traits>
4316 template <
typename T,
typename Enable>
4320 return insert(
static_cast<const_iterator
>(param), count, ch);
4326 template <
class CharT,
class Traits>
4337 template <
class CharT,
class Traits>
4348 template <
class CharT,
class Traits>
4359 template <
class CharT,
class Traits>
4370 template <
class CharT,
class Traits>
4381 template <
class CharT,
class Traits>
4392 template <
class CharT,
class Traits>
4402 template <
class CharT,
class Traits>
4412 template <
class CharT,
class Traits>
4422 template <
class CharT,
class Traits>
4432 template <
class CharT,
class Traits>
4442 template <
class CharT,
class Traits>
4452 template <
class CharT,
class Traits>
4462 template <
class CharT,
class Traits>
4472 template <
class CharT,
class Traits>
4482 template <
class CharT,
class Traits>
4492 template <
class CharT,
class Traits>
4502 template <
class CharT,
class Traits>
4512 template <
class CharT,
class Traits>
4523 template <
class CharT,
class Traits>
4534 template <
class CharT,
class Traits>
4536 operator<(
const std::basic_string<CharT, Traits> &lhs,
4545 template <
class CharT,
class Traits>
4547 operator<=(
const std::basic_string<CharT, Traits> &lhs,
4556 template <
class CharT,
class Traits>
4567 template <
class CharT,
class Traits>
4578 template <
class CharT,
class Traits>
4581 const std::basic_string<CharT, Traits> &rhs)
4589 template <
class CharT,
class Traits>
4592 const std::basic_string<CharT, Traits> &rhs)
4600 template <
class CharT,
class Traits>
4603 const std::basic_string<CharT, Traits> &rhs)
4611 template <
class CharT,
class Traits>
4614 const std::basic_string<CharT, Traits> &rhs)
4622 template <
class CharT,
class Traits>
4625 const std::basic_string<CharT, Traits> &rhs)
4633 template <
class CharT,
class Traits>
4636 const std::basic_string<CharT, Traits> &rhs)
4644 template <
class CharT,
class Traits>
4648 return lhs.
swap(rhs);