9 #ifndef LIBPMEMOBJ_CPP_BASIC_STRING_HPP
10 #define LIBPMEMOBJ_CPP_BASIC_STRING_HPP
45 template <
typename CharT,
typename Traits = std::
char_traits<CharT>>
49 using traits_type = Traits;
50 using value_type = CharT;
51 using size_type = std::size_t;
52 using difference_type = std::ptrdiff_t;
53 using reference = value_type &;
54 using const_reference =
const value_type &;
55 using pointer = value_type *;
56 using const_pointer =
const value_type *;
58 using const_iterator = const_pointer;
59 using reverse_iterator = std::reverse_iterator<iterator>;
60 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
61 using for_each_ptr_function =
65 static constexpr size_type sso_capacity = (32 - 8) /
sizeof(CharT) - 1;
71 size_type count = npos);
72 basic_string(
const std::basic_string<CharT> &other, size_type pos,
73 size_type count = npos);
78 typename Enable =
typename std::enable_if<
87 typename Enable =
typename std::enable_if<
88 std::is_convertible<
const T &,
90 CharT, Traits>>::value &&
91 !std::is_convertible<const T &, const CharT *>::value>>
94 typename Enable =
typename std::enable_if<std::is_convertible<
111 typename Enable =
typename std::enable_if<
112 std::is_convertible<
const T &,
114 CharT, Traits>>::value &&
115 !std::is_convertible<const T &, const CharT *>::value>>
123 size_type count = npos);
125 size_type pos, size_type count = npos);
128 template <
typename InputIt,
136 reference
at(size_type n);
137 const_reference
at(size_type n)
const;
138 const_reference
const_at(size_type n)
const;
140 const_reference
operator[](size_type n)
const;
142 const CharT &
front()
const;
143 const CharT &
cfront()
const;
145 const CharT &
back()
const;
146 const CharT &
cback()
const;
148 const CharT *
data()
const noexcept;
149 const CharT *
cdata()
const noexcept;
150 const CharT *
c_str()
const noexcept;
155 const_iterator
begin()
const noexcept;
156 const_iterator
cbegin()
const noexcept;
158 const_iterator
end()
const noexcept;
159 const_iterator
cend()
const noexcept;
160 reverse_iterator
rbegin();
161 const_reverse_iterator
rbegin()
const noexcept;
162 const_reverse_iterator
crbegin()
const noexcept;
163 reverse_iterator
rend();
164 const_reverse_iterator
rend()
const noexcept;
165 const_reverse_iterator
crend()
const noexcept;
168 bool empty()
const noexcept;
169 size_type
size()
const noexcept;
170 size_type
length()
const noexcept;
171 size_type
max_size()
const noexcept;
172 size_type
capacity()
const noexcept;
173 void resize(size_type count, CharT ch);
175 void reserve(size_type new_cap = 0);
185 template <
typename T,
186 typename Enable =
typename std::enable_if<
187 std::is_convertible<T, size_type>::value>::type>
189 template <
typename T,
190 typename Enable =
typename std::enable_if<
191 !std::is_convertible<T, size_type>::value>::type>
198 size_type count = npos);
201 template <
typename InputIt,
217 size_type index2, size_type count = npos);
220 template <
typename InputIt,
224 iterator insert(const_iterator pos, std::initializer_list<CharT> ilist);
225 template <
typename T,
226 typename Enable =
typename std::enable_if<
227 std::is_convertible<T, size_type>::value>::type>
229 template <
typename T,
230 typename Enable =
typename std::enable_if<
231 !std::is_convertible<T, size_type>::value>::type>
240 size_type count2 = npos);
241 template <
typename InputIt,
245 InputIt first2, InputIt last2);
247 const CharT *s, size_type count2);
251 size_type count2, CharT ch);
253 size_type count2, CharT ch);
258 std::initializer_list<CharT> ilist);
260 size_type
copy(CharT *s, size_type count, size_type index = 0)
const;
263 int compare(
const std::basic_string<CharT> &other)
const;
264 int compare(size_type pos, size_type count,
266 int compare(size_type pos, size_type count,
267 const std::basic_string<CharT> &other)
const;
269 size_type pos2, size_type count2 = npos)
const;
270 int compare(size_type pos1, size_type count1,
271 const std::basic_string<CharT> &other, size_type pos2,
272 size_type count2 = npos)
const;
273 int compare(
const CharT *s)
const;
274 int compare(size_type pos, size_type count,
const CharT *s)
const;
275 int compare(size_type pos, size_type count1,
const CharT *s,
276 size_type count2)
const;
281 size_type
find(
const CharT *s, size_type pos, size_type count)
const;
282 size_type
find(
const CharT *s, size_type pos = 0)
const;
283 size_type
find(CharT ch, size_type pos = 0)
const noexcept;
286 size_type
rfind(
const CharT *s, size_type pos, size_type count)
const;
287 size_type
rfind(
const CharT *s, size_type pos = npos)
const;
288 size_type
rfind(CharT ch, size_type pos = npos)
const noexcept;
290 size_type pos = 0)
const noexcept;
292 size_type count)
const;
293 size_type
find_first_of(
const CharT *s, size_type pos = 0)
const;
294 size_type
find_first_of(CharT ch, size_type pos = 0)
const noexcept;
296 size_type pos = 0)
const noexcept;
298 size_type count)
const;
302 size_type pos = npos)
const noexcept;
304 size_type count)
const;
305 size_type
find_last_of(
const CharT *s, size_type pos = npos)
const;
306 size_type
find_last_of(CharT ch, size_type pos = npos)
const noexcept;
308 size_type pos = npos)
const noexcept;
310 size_type count)
const;
320 static const size_type npos =
static_cast<size_type
>(-1);
364 static constexpr size_type _sso_mask = 1ULL
365 << (std::numeric_limits<size_type>::digits - 1);
368 bool is_sso_used()
const;
372 typename Enable =
typename std::enable_if<
374 size_type
get_size(InputIt first, InputIt last)
const;
375 size_type
get_size(size_type count, value_type ch)
const;
377 template <
typename... Args>
379 template <
typename... Args>
384 typename Enable =
typename std::enable_if<
391 typename Enable =
typename std::enable_if<
409 non_sso_data()
const;
422 template <
typename CharT,
typename Traits>
429 initialize(0U, value_type(
'\0'));
446 template <
typename CharT,
typename Traits>
453 initialize(count, ch);
473 template <
typename CharT,
typename Traits>
475 size_type pos, size_type count)
480 if (pos > other.
size())
481 throw std::out_of_range(
"Index out of range.");
483 if (count == npos || pos + count > other.
size())
484 count = other.
size() - pos;
486 auto first =
static_cast<difference_type
>(pos);
487 auto last = first +
static_cast<difference_type
>(count);
490 initialize(other.
cbegin() + first, other.
cbegin() + last);
511 template <
typename CharT,
typename Traits>
513 size_type pos, size_type count)
533 template <
typename CharT,
typename Traits>
540 initialize(s, s + count);
556 template <
typename CharT,
typename Traits>
562 auto length = traits_type::length(s);
565 initialize(s, s + length);
584 template <
typename CharT,
typename Traits>
585 template <
typename InputIt,
typename Enable>
588 auto len = std::distance(first, last);
594 allocate(
static_cast<size_type
>(len));
595 initialize(first, last);
612 template <
typename CharT,
typename Traits>
618 allocate(other.
size());
637 template <
typename CharT,
typename Traits>
657 template <
typename CharT,
typename Traits>
663 move_data(std::move(other));
680 template <
typename CharT,
typename Traits>
686 allocate(ilist.size());
687 initialize(ilist.begin(), ilist.end());
705 template <
typename CharT,
typename Traits>
706 template <
class T,
typename Enable>
735 template <
typename CharT,
typename Traits>
736 template <
class T,
typename Enable>
746 throw std::out_of_range(
"Index out of range.");
748 if (n == npos || pos + n > sv.
size())
752 auto last = first + n;
755 initialize(sv.
data() + first, sv.
data() + last);
761 template <
typename CharT,
typename Traits>
780 template <
typename CharT,
typename Traits>
784 return assign(other);
797 template <
typename CharT,
typename Traits>
801 return assign(other);
813 template <
typename CharT,
typename Traits>
817 return assign(std::move(other));
828 template <
typename CharT,
typename Traits>
843 template <
typename CharT,
typename Traits>
847 return assign(1, ch);
859 template <
typename CharT,
typename Traits>
863 return assign(ilist);
875 template <
typename CharT,
typename Traits>
876 template <
class T,
typename Enable>
881 return assign(sv.
data(), sv.
size());
894 template <
typename CharT,
typename Traits>
898 auto pop = get_pool();
914 template <
typename CharT,
typename Traits>
921 auto pop = get_pool();
924 pop, [&] { replace_content(other.
cbegin(), other.
cend()); });
939 template <
typename CharT,
typename Traits>
943 return assign(other.cbegin(), other.cend());
958 template <
typename CharT,
typename Traits>
963 if (pos > other.
size())
964 throw std::out_of_range(
"Index out of range.");
966 if (count == npos || pos + count > other.
size())
967 count = other.
size() - pos;
969 auto pop = get_pool();
970 auto first =
static_cast<difference_type
>(pos);
971 auto last = first +
static_cast<difference_type
>(count);
974 replace_content(other.
cbegin() + first, other.
cbegin() + last);
994 template <
typename CharT,
typename Traits>
997 size_type pos, size_type count)
999 if (pos > other.size())
1000 throw std::out_of_range(
"Index out of range.");
1002 if (count == npos || pos + count > other.size())
1003 count = other.size() - pos;
1005 return assign(other.c_str() + pos, count);
1018 template <
typename CharT,
typename Traits>
1022 auto pop = get_pool();
1037 template <
typename CharT,
typename Traits>
1041 auto pop = get_pool();
1043 auto length = traits_type::length(s);
1061 template <
typename CharT,
typename Traits>
1062 template <
typename InputIt,
typename Enable>
1066 auto pop = get_pool();
1082 template <
typename CharT,
typename Traits>
1089 auto pop = get_pool();
1093 move_data(std::move(other));
1108 template <
typename CharT,
typename Traits>
1112 return assign(ilist.begin(), ilist.end());
1122 template <
typename CharT,
typename Traits>
1126 if (!is_sso_used()) {
1127 non_sso._data.for_each_ptr(func);
1136 template <
typename CharT,
typename Traits>
1149 template <
typename CharT,
typename Traits>
1150 typename basic_string<CharT, Traits>::const_iterator
1161 template <
typename CharT,
typename Traits>
1162 typename basic_string<CharT, Traits>::const_iterator
1165 return is_sso_used() ? const_iterator(&*sso_data().
cbegin())
1166 : const_iterator(&*non_sso_data().
cbegin());
1174 template <
typename CharT,
typename Traits>
1178 return begin() +
static_cast<difference_type
>(size());
1187 template <
typename CharT,
typename Traits>
1188 typename basic_string<CharT, Traits>::const_iterator
1191 return cbegin() +
static_cast<difference_type
>(size());
1200 template <
typename CharT,
typename Traits>
1201 typename basic_string<CharT, Traits>::const_iterator
1204 return cbegin() +
static_cast<difference_type
>(size());
1213 template <
typename CharT,
typename Traits>
1214 typename basic_string<CharT, Traits>::reverse_iterator
1217 return reverse_iterator(
end());
1226 template <
typename CharT,
typename Traits>
1227 typename basic_string<CharT, Traits>::const_reverse_iterator
1239 template <
typename CharT,
typename Traits>
1240 typename basic_string<CharT, Traits>::const_reverse_iterator
1243 return const_reverse_iterator(
cend());
1252 template <
typename CharT,
typename Traits>
1253 typename basic_string<CharT, Traits>::reverse_iterator
1256 return reverse_iterator(
begin());
1265 template <
typename CharT,
typename Traits>
1266 typename basic_string<CharT, Traits>::const_reverse_iterator
1278 template <
typename CharT,
typename Traits>
1279 typename basic_string<CharT, Traits>::const_reverse_iterator
1282 return const_reverse_iterator(
cbegin());
1298 template <
typename CharT,
typename Traits>
1299 typename basic_string<CharT, Traits>::reference
1303 throw std::out_of_range(
"string::at");
1305 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1318 template <
typename CharT,
typename Traits>
1319 typename basic_string<CharT, Traits>::const_reference
1338 template <
typename CharT,
typename Traits>
1339 typename basic_string<CharT, Traits>::const_reference
1343 throw std::out_of_range(
"string::const_at");
1345 return is_sso_used()
1346 ?
static_cast<const sso_type &
>(sso_data())[n]
1347 :
static_cast<const non_sso_type &
>(non_sso_data())[n];
1361 template <
typename CharT,
typename Traits>
1362 typename basic_string<CharT, Traits>::reference
1365 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1375 template <
typename CharT,
typename Traits>
1376 typename basic_string<CharT, Traits>::const_reference
1379 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1391 template <
typename CharT,
typename Traits>
1403 template <
typename CharT,
typename Traits>
1418 template <
typename CharT,
typename Traits>
1434 template <
typename CharT,
typename Traits>
1438 return (*
this)[size() - 1];
1446 template <
typename CharT,
typename Traits>
1461 template <
typename CharT,
typename Traits>
1465 return static_cast<const basic_string &
>(*this)[size() - 1];
1471 template <
typename CharT,
typename Traits>
1472 typename basic_string<CharT, Traits>::size_type
1476 return get_sso_size();
1477 else if (non_sso_data().size() == 0)
1480 return non_sso_data().size() - 1;
1489 template <
typename CharT,
typename Traits>
1493 return is_sso_used() ? sso_data().range(0, get_sso_size() + 1).begin()
1494 : non_sso_data().data();
1515 template <
typename CharT,
typename Traits>
1522 throw std::out_of_range(
"Index exceeds size.");
1524 count = (std::min)(count, sz - index);
1526 auto pop = get_pool();
1528 auto first =
begin() +
static_cast<difference_type
>(index);
1529 auto last = first +
static_cast<difference_type
>(count);
1531 if (is_sso_used()) {
1533 auto move_len = sz - index - count;
1534 auto new_size = sz - count;
1538 sso_data().range(index, move_len + 1);
1539 traits_type::move(range.begin(), &*last,
1542 assert(range.end() - 1 ==
1543 &sso_data()._data[index + move_len]);
1546 sso_data()[index + move_len] = value_type(
'\0');
1547 set_sso_size(new_size);
1550 non_sso_data().erase(first, last);
1572 template <
typename CharT,
typename Traits>
1576 return erase(pos, pos + 1);
1597 template <
typename CharT,
typename Traits>
1602 static_cast<size_type
>(std::distance(
cbegin(), first));
1603 size_type len =
static_cast<size_type
>(std::distance(first, last));
1607 return begin() +
static_cast<difference_type
>(index);
1620 template <
typename CharT,
typename Traits>
1624 erase(size() - 1, 1);
1646 template <
typename CharT,
typename Traits>
1651 auto new_size = sz + count;
1653 if (new_size > max_size())
1654 throw std::length_error(
"Size exceeds max size.");
1656 if (is_sso_used()) {
1657 auto pop = get_pool();
1660 if (new_size > sso_capacity) {
1661 sso_to_large(new_size);
1663 non_sso_data().insert(
1664 non_sso_data().
cbegin() +
1665 static_cast<difference_type
>(
1669 add_sso_to_tx(sz, count + 1);
1670 traits_type::assign(&sso_data()._data[sz],
1673 assert(new_size == sz + count);
1674 set_sso_size(new_size);
1675 sso_data()._data[new_size] = value_type(
'\0');
1679 non_sso_data().insert(non_sso_data().
cbegin() +
1680 static_cast<difference_type
>(sz),
1705 template <
typename CharT,
typename Traits>
1709 return append(str.
data(), str.
size());
1737 template <
typename CharT,
typename Traits>
1742 auto sz = str.
size();
1745 throw std::out_of_range(
"Index out of range.");
1747 count = (std::min)(count, sz - pos);
1749 append(str.
data() + pos, count);
1773 template <
typename CharT,
typename Traits>
1777 return append(s, s + count);
1799 template <
typename CharT,
typename Traits>
1803 return append(s, traits_type::length(s));
1827 template <
typename CharT,
typename Traits>
1828 template <
typename InputIt,
typename Enable>
1833 auto count =
static_cast<size_type
>(std::distance(first, last));
1834 auto new_size = sz + count;
1836 if (new_size > max_size())
1837 throw std::length_error(
"Size exceeds max size.");
1839 if (is_sso_used()) {
1840 auto pop = get_pool();
1843 if (new_size > sso_capacity) {
1852 std::vector<value_type> str(first, last);
1854 sso_to_large(new_size);
1855 non_sso_data().insert(
1856 non_sso_data().
cbegin() +
1857 static_cast<difference_type
>(
1859 str.begin(), str.end());
1861 add_sso_to_tx(sz, count + 1);
1862 std::copy(first, last, &sso_data()._data[sz]);
1864 assert(new_size == sz + count);
1865 set_sso_size(new_size);
1866 sso_data()._data[new_size] = value_type(
'\0');
1870 non_sso_data().insert(non_sso_data().
cbegin() +
1871 static_cast<difference_type
>(sz),
1896 template <
typename CharT,
typename Traits>
1900 return append(ilist.begin(), ilist.end());
1919 template <
typename CharT,
typename Traits>
1923 append(
static_cast<size_type
>(1), ch);
1944 template <
typename CharT,
typename Traits>
1970 template <
typename CharT,
typename Traits>
1993 template <
typename CharT,
typename Traits>
2020 template <
typename CharT,
typename Traits>
2024 return append(ilist);
2048 template <
typename CharT,
typename Traits>
2053 throw std::out_of_range(
"Index out of range.");
2055 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2057 insert(pos, count, ch);
2083 template <
typename CharT,
typename Traits>
2087 return insert(index, s, traits_type::length(s));
2111 template <
typename CharT,
typename Traits>
2117 throw std::out_of_range(
"Index out of range.");
2119 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2121 insert(pos, s, s + count);
2146 template <
typename CharT,
typename Traits>
2150 return insert(index, str.
data(), str.
size());
2175 template <
typename CharT,
typename Traits>
2178 size_type index2, size_type count)
2180 auto sz = str.
size();
2182 if (index1 > size() || index2 > sz)
2183 throw std::out_of_range(
"Index out of range.");
2185 count = (std::min)(count, sz - index2);
2187 return insert(index1, str.
data() + index2, count);
2212 template <
typename CharT,
typename Traits>
2216 return insert(pos, 1, ch);
2243 template <
typename CharT,
typename Traits>
2250 if (sz + count > max_size())
2251 throw std::length_error(
"Count exceeds max size.");
2253 auto new_size = sz + count;
2255 auto pop = get_pool();
2257 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2260 if (is_sso_used() && new_size <= sso_capacity) {
2261 auto len = sz - index;
2263 add_sso_to_tx(index, len + count + 1);
2265 traits_type::move(&sso_data()._data[index + count],
2266 &sso_data()._data[index], len);
2267 traits_type::assign(&sso_data()._data[index], count,
2270 assert(new_size == index + len + count);
2271 set_sso_size(new_size);
2272 sso_data()._data[new_size] = value_type(
'\0');
2275 sso_to_large(new_size);
2277 non_sso_data().insert(
2278 non_sso_data().
begin() +
2279 static_cast<difference_type
>(index),
2284 return iterator(&data()[
static_cast<difference_type
>(index)]);
2311 template <
typename CharT,
typename Traits>
2312 template <
typename InputIt,
typename Enable>
2319 auto count =
static_cast<size_type
>(std::distance(first, last));
2321 if (sz + count > max_size())
2322 throw std::length_error(
"Count exceeds max size.");
2324 auto pop = get_pool();
2326 auto new_size = sz + count;
2328 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2331 if (is_sso_used() && new_size <= sso_capacity) {
2332 auto len = sz - index;
2334 add_sso_to_tx(index, len + count + 1);
2336 traits_type::move(&sso_data()._data[index + count],
2337 &sso_data()._data[index], len);
2338 std::copy(first, last, &sso_data()._data[index]);
2340 assert(new_size == index + len + count);
2341 set_sso_size(new_size);
2342 sso_data()._data[new_size] = value_type(
'\0');
2344 if (is_sso_used()) {
2353 std::vector<value_type> str(first, last);
2355 sso_to_large(new_size);
2356 non_sso_data().insert(
2357 non_sso_data().
begin() +
2358 static_cast<difference_type
>(
2360 str.begin(), str.end());
2362 non_sso_data().insert(
2363 non_sso_data().
begin() +
2364 static_cast<difference_type
>(
2371 return iterator(&data()[
static_cast<difference_type
>(index)]);
2397 template <
typename CharT,
typename Traits>
2400 std::initializer_list<CharT> ilist)
2402 return insert(pos, ilist.begin(), ilist.end());
2427 template <
typename CharT,
typename Traits>
2432 return replace(index, count, str.
data(), str.
size());
2455 template <
typename CharT,
typename Traits>
2460 return replace(first, last, str.
data(), str.
data() + str.
size());
2489 template <
typename CharT,
typename Traits>
2495 auto sz = str.
size();
2498 throw std::out_of_range(
"Index out of range.");
2500 count2 = (std::min)(count2, sz - index2);
2502 return replace(index, count, str.
data() + index2, count2);
2530 template <
typename CharT,
typename Traits>
2531 template <
typename InputIt,
typename Enable>
2534 InputIt first2, InputIt last2)
2537 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2538 auto count =
static_cast<size_type
>(std::distance(first, last));
2539 auto count2 =
static_cast<size_type
>(std::distance(first2, last2));
2541 count = (std::min)(count, sz - index);
2543 if (sz - count + count2 > max_size())
2544 throw std::length_error(
"Count exceeds max size.");
2546 auto new_size = sz - count + count2;
2548 auto pop = get_pool();
2551 if (is_sso_used() && new_size <= sso_capacity) {
2552 add_sso_to_tx(index, new_size - index + 1);
2554 assert(count2 < new_size + 1);
2555 traits_type::move(&sso_data()._data[index + count2],
2556 &sso_data()._data[index + count],
2557 sz - index - count);
2558 std::copy(first2, last2, &sso_data()._data[index]);
2560 set_sso_size(new_size);
2561 sso_data()._data[new_size] = value_type(
'\0');
2571 std::vector<value_type> str(first2, last2);
2573 if (is_sso_used()) {
2574 sso_to_large(new_size);
2578 begin() +
static_cast<difference_type
>(index);
2579 auto end = beg +
static_cast<difference_type
>(count);
2580 non_sso_data().erase(beg,
end);
2581 non_sso_data().insert(beg, str.begin(), str.end());
2584 if (!is_sso_used() && new_size <= sso_capacity)
2613 template <
typename CharT,
typename Traits>
2616 const CharT *s, size_type count2)
2618 return replace(first, last, s, s + count2);
2644 template <
typename CharT,
typename Traits>
2647 const CharT *s, size_type count2)
2650 throw std::out_of_range(
"Index out of range.");
2652 auto first =
cbegin() +
static_cast<difference_type
>(index);
2653 auto last = first +
static_cast<difference_type
>(count);
2655 return replace(first, last, s, s + count2);
2681 template <
typename CharT,
typename Traits>
2686 return replace(index, count, s, traits_type::length(s));
2712 template <
typename CharT,
typename Traits>
2715 size_type count2, CharT ch)
2718 throw std::out_of_range(
"Index out of range.");
2720 auto first =
cbegin() +
static_cast<difference_type
>(index);
2721 auto last = first +
static_cast<difference_type
>(count);
2723 return replace(first, last, count2, ch);
2748 template <
typename CharT,
typename Traits>
2751 size_type count2, CharT ch)
2754 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2755 auto count =
static_cast<size_type
>(std::distance(first, last));
2757 count = (std::min)(count, sz - index);
2759 if (sz - count + count2 > max_size())
2760 throw std::length_error(
"Count exceeds max size.");
2762 auto new_size = sz - count + count2;
2764 auto pop = get_pool();
2767 if (is_sso_used() && new_size <= sso_capacity) {
2768 add_sso_to_tx(index, new_size - index + 1);
2770 assert(count2 < new_size + 1);
2771 traits_type::move(&sso_data()._data[index + count2],
2772 &sso_data()._data[index + count],
2773 sz - index - count);
2774 traits_type::assign(&sso_data()._data[index], count2,
2777 set_sso_size(new_size);
2778 sso_data()._data[new_size] = value_type(
'\0');
2780 if (is_sso_used()) {
2781 sso_to_large(new_size);
2785 begin() +
static_cast<difference_type
>(index);
2786 auto end = beg +
static_cast<difference_type
>(count);
2787 non_sso_data().erase(beg,
end);
2788 non_sso_data().insert(beg, count2, ch);
2791 if (!is_sso_used() && new_size <= sso_capacity)
2819 template <
typename CharT,
typename Traits>
2824 return replace(first, last, s, traits_type::length(s));
2849 template <
typename CharT,
typename Traits>
2852 std::initializer_list<CharT> ilist)
2854 return replace(first, last, ilist.begin(), ilist.end());
2870 template <
typename CharT,
typename Traits>
2871 typename basic_string<CharT, Traits>::size_type
2873 size_type index)
const
2878 throw std::out_of_range(
"Index out of range.");
2880 auto len = (std::min)(count, sz - index);
2882 traits_type::copy(s, data() + index, len);
2904 template <
typename CharT,
typename Traits>
2907 const CharT *s, size_type count2)
const
2910 throw std::out_of_range(
"Index out of range.");
2912 if (count1 > size() - pos)
2913 count1 = size() - pos;
2915 auto ret = traits_type::compare(cdata() + pos, s,
2916 std::min<size_type>(count1, count2));
2921 if (count1 < count2)
2923 else if (count1 == count2)
2938 template <
typename CharT,
typename Traits>
2939 typename basic_string<CharT, Traits>::size_type
2943 return find(str.data(), pos, str.size());
2957 template <
typename CharT,
typename Traits>
2958 typename basic_string<CharT, Traits>::size_type
2960 size_type count)
const
2970 while (pos + count <= sz) {
2971 auto found = traits_type::find(cdata() + pos, sz - pos, s[0]);
2974 pos =
static_cast<size_type
>(std::distance(cdata(), found));
2975 if (traits_type::compare(found, s, count) == 0) {
2993 template <
typename CharT,
typename Traits>
2994 typename basic_string<CharT, Traits>::size_type
2997 return find(s, pos, traits_type::length(s));
3009 template <
typename CharT,
typename Traits>
3010 typename basic_string<CharT, Traits>::size_type
3013 return find(&ch, pos, 1);
3026 template <
typename CharT,
typename Traits>
3027 typename basic_string<CharT, Traits>::size_type
3031 return rfind(str.cdata(), pos, str.size());
3050 template <
typename CharT,
typename Traits>
3051 typename basic_string<CharT, Traits>::size_type
3053 size_type count)
const
3055 if (count <= size()) {
3056 pos = (std::min)(size() - count, pos);
3058 if (traits_type::compare(cdata() + pos, s, count) == 0)
3060 }
while (pos-- > 0);
3077 template <
typename CharT,
typename Traits>
3078 typename basic_string<CharT, Traits>::size_type
3081 return rfind(s, pos, traits_type::length(s));
3095 template <
typename CharT,
typename Traits>
3096 typename basic_string<CharT, Traits>::size_type
3099 return rfind(&ch, pos, 1);
3111 template <
typename CharT,
typename Traits>
3112 typename basic_string<CharT, Traits>::size_type
3114 size_type pos)
const noexcept
3116 return find_first_of(str.cdata(), pos, str.size());
3132 template <
typename CharT,
typename Traits>
3133 typename basic_string<CharT, Traits>::size_type
3135 size_type count)
const
3137 size_type first_of = npos;
3138 for (
const CharT *c = s; c != s + count; ++c) {
3139 size_type found = find(*c, pos);
3140 if (found != npos && found < first_of)
3158 template <
typename CharT,
typename Traits>
3159 typename basic_string<CharT, Traits>::size_type
3162 return find_first_of(s, pos, traits_type::length(s));
3174 template <
typename CharT,
typename Traits>
3175 typename basic_string<CharT, Traits>::size_type
3179 return find(ch, pos);
3191 template <
typename CharT,
typename Traits>
3192 typename basic_string<CharT, Traits>::size_type
3194 size_type pos)
const noexcept
3196 return find_first_not_of(str.cdata(), pos, str.size());
3212 template <
typename CharT,
typename Traits>
3213 typename basic_string<CharT, Traits>::size_type
3215 size_type count)
const
3220 for (
auto it =
cbegin() + pos; it !=
cend(); ++it)
3221 if (!traits_type::find(s, count, *it))
3222 return static_cast<size_type
>(
3223 std::distance(
cbegin(), it));
3239 template <
typename CharT,
typename Traits>
3240 typename basic_string<CharT, Traits>::size_type
3242 size_type pos)
const
3244 return find_first_not_of(s, pos, traits_type::length(s));
3256 template <
typename CharT,
typename Traits>
3257 typename basic_string<CharT, Traits>::size_type
3261 return find_first_not_of(&ch, pos, 1);
3273 template <
typename CharT,
typename Traits>
3274 typename basic_string<CharT, Traits>::size_type
3276 size_type pos)
const noexcept
3278 return find_last_of(str.cdata(), pos, str.size());
3294 template <
typename CharT,
typename Traits>
3295 typename basic_string<CharT, Traits>::size_type
3297 size_type count)
const
3299 if (size() == 0 || count == 0)
3303 size_type last_of = 0;
3304 for (
const CharT *c = s; c != s + count; ++c) {
3305 size_type position = rfind(*c, pos);
3306 if (position != npos) {
3308 if (position > last_of)
3329 template <
typename CharT,
typename Traits>
3330 typename basic_string<CharT, Traits>::size_type
3333 return find_last_of(s, pos, traits_type::length(s));
3345 template <
typename CharT,
typename Traits>
3346 typename basic_string<CharT, Traits>::size_type
3350 return rfind(ch, pos);
3362 template <
typename CharT,
typename Traits>
3363 typename basic_string<CharT, Traits>::size_type
3365 size_type pos)
const noexcept
3367 return find_last_not_of(str.cdata(), pos, str.size());
3383 template <
typename CharT,
typename Traits>
3384 typename basic_string<CharT, Traits>::size_type
3386 size_type count)
const
3389 pos = (std::min)(pos, size() - 1);
3391 if (!traits_type::find(s, count, *(cdata() + pos)))
3394 }
while (pos-- > 0);
3411 template <
typename CharT,
typename Traits>
3412 typename basic_string<CharT, Traits>::size_type
3414 size_type pos)
const
3416 return find_last_not_of(s, pos, traits_type::length(s));
3428 template <
typename CharT,
typename Traits>
3429 typename basic_string<CharT, Traits>::size_type
3433 return find_last_not_of(&ch, pos, 1);
3444 template <
typename CharT,
typename Traits>
3448 return compare(0, size(), other.
cdata(), other.
size());
3459 template <
typename CharT,
typename Traits>
3462 const std::basic_string<CharT> &other)
const
3464 return compare(0, size(), other.data(), other.size());
3480 template <
typename CharT,
typename Traits>
3485 return compare(pos, count, other.
cdata(), other.
size());
3502 template <
typename CharT,
typename Traits>
3505 size_type pos, size_type count,
3506 const std::basic_string<CharT> &other)
const
3508 return compare(pos, count, other.data(), other.size());
3529 template <
typename CharT,
typename Traits>
3533 size_type count2)
const
3535 if (pos2 > other.
size())
3536 throw std::out_of_range(
"Index out of range.");
3538 if (count2 > other.
size() - pos2)
3539 count2 = other.
size() - pos2;
3541 return compare(pos1, count1, other.
cdata() + pos2, count2);
3562 template <
typename CharT,
typename Traits>
3565 const std::basic_string<CharT> &other,
3566 size_type pos2, size_type count2)
const
3568 if (pos2 > other.size())
3569 throw std::out_of_range(
"Index out of range.");
3571 if (count2 > other.size() - pos2)
3572 count2 = other.size() - pos2;
3574 return compare(pos1, count1, other.data() + pos2, count2);
3585 template <
typename CharT,
typename Traits>
3589 return compare(0, size(), s, traits_type::length(s));
3605 template <
typename CharT,
typename Traits>
3608 const CharT *s)
const
3610 return compare(pos, count, s, traits_type::length(s));
3616 template <
typename CharT,
typename Traits>
3620 return is_sso_used() ? sso_data().cdata() : non_sso_data().cdata();
3626 template <
typename CharT,
typename Traits>
3636 template <
typename CharT,
typename Traits>
3646 template <
typename CharT,
typename Traits>
3647 typename basic_string<CharT, Traits>::size_type
3656 template <
typename CharT,
typename Traits>
3657 typename basic_string<CharT, Traits>::size_type
3660 return PMEMOBJ_MAX_ALLOC_SIZE /
sizeof(CharT) - 1;
3667 template <
typename CharT,
typename Traits>
3668 typename basic_string<CharT, Traits>::size_type
3671 return is_sso_used() ? sso_capacity : non_sso_data().capacity() - 1;
3693 template <
typename CharT,
typename Traits>
3697 if (count > max_size())
3698 throw std::length_error(
"Count exceeds max size.");
3702 auto pop = get_pool();
3706 append(count - sz, ch);
3707 }
else if (is_sso_used()) {
3708 set_sso_size(count);
3709 sso_data()[count] = value_type(
'\0');
3711 non_sso_data().resize(count + 1, ch);
3712 non_sso_data().back() = value_type(
'\0');
3735 template <
typename CharT,
typename Traits>
3739 resize(count, CharT());
3762 template <
typename CharT,
typename Traits>
3766 if (new_cap > max_size())
3767 throw std::length_error(
"New capacity exceeds max size.");
3769 if (new_cap < capacity() || new_cap <= sso_capacity)
3772 if (is_sso_used()) {
3773 auto pop = get_pool();
3777 non_sso_data().reserve(new_cap + 1);
3794 template <
typename CharT,
typename Traits>
3801 if (size() <= sso_capacity) {
3802 auto pop = get_pool();
3806 non_sso_data().shrink_to_fit();
3819 template <
typename CharT,
typename Traits>
3838 template <
typename CharT,
typename Traits>
3842 auto pop = get_pool();
3845 if (is_sso_used()) {
3846 add_sso_to_tx(0, get_sso_size() + 1);
3850 non_sso_data().free_data();
3851 detail::destroy<non_sso_type>(non_sso_data());
3860 template <
typename CharT,
typename Traits>
3867 template <
typename CharT,
typename Traits>
3871 return (sso._size & _sso_mask) != 0;
3874 template <
typename CharT,
typename Traits>
3876 basic_string<CharT, Traits>::destroy_data()
3878 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3880 if (is_sso_used()) {
3881 add_sso_to_tx(0, get_sso_size() + 1);
3884 non_sso_data().free_data();
3885 detail::destroy<non_sso_type>(non_sso_data());
3895 template <
typename CharT,
typename Traits>
3896 template <
typename InputIt,
typename Enable>
3897 typename basic_string<CharT, Traits>::size_type
3900 return static_cast<size_type
>(std::distance(first, last));
3909 template <
typename CharT,
typename Traits>
3910 typename basic_string<CharT, Traits>::size_type
3922 template <
typename CharT,
typename Traits>
3923 typename basic_string<CharT, Traits>::size_type
3926 return other.
size();
3935 template <
typename CharT,
typename Traits>
3936 template <
typename... Args>
3937 typename basic_string<CharT, Traits>::pointer
3940 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3942 auto new_size = get_size(std::forward<Args>(args)...);
3945 if (!is_sso_used() && new_size <= capacity())
3946 return assign_large_data(std::forward<Args>(args)...);
3951 return initialize(std::forward<Args>(args)...);
3964 template <
typename CharT,
typename Traits>
3965 template <
typename... Args>
3966 typename basic_string<CharT, Traits>::pointer
3969 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3971 if (is_sso_used()) {
3972 return assign_sso_data(std::forward<Args>(args)...);
3974 return assign_large_data(std::forward<Args>(args)...);
3987 template <
typename CharT,
typename Traits>
3991 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3993 if (n <= sso_capacity) {
4003 if (!is_sso_used()) {
4004 detail::conditional_add_to_tx(&non_sso_data(), 1,
4005 POBJ_XADD_NO_SNAPSHOT);
4006 detail::create<non_sso_type>(&non_sso_data());
4007 non_sso_data().reserve(n + 1);
4014 template <
typename CharT,
typename Traits>
4015 template <
typename InputIt,
typename Enable>
4016 typename basic_string<CharT, Traits>::pointer
4019 auto size =
static_cast<size_type
>(std::distance(first, last));
4021 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4022 assert(size <= sso_capacity);
4024 add_sso_to_tx(0, size + 1);
4025 std::copy(first, last, &sso_data()._data[0]);
4027 sso_data()._data[size] = value_type(
'\0');
4031 return &sso_data()[0];
4037 template <
typename CharT,
typename Traits>
4038 typename basic_string<CharT, Traits>::pointer
4041 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4042 assert(count <= sso_capacity);
4044 add_sso_to_tx(0, count + 1);
4045 traits_type::assign(&sso_data()._data[0], count, ch);
4047 sso_data()._data[count] = value_type(
'\0');
4049 set_sso_size(count);
4051 return &sso_data()[0];
4058 template <
typename CharT,
typename Traits>
4059 template <
typename InputIt,
typename Enable>
4060 typename basic_string<CharT, Traits>::pointer
4063 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4065 auto size =
static_cast<size_type
>(std::distance(first, last));
4067 non_sso_data().reserve(size + 1);
4068 non_sso_data().assign(first, last);
4069 non_sso_data().push_back(value_type(
'\0'));
4071 return non_sso_data().data();
4078 template <
typename CharT,
typename Traits>
4079 typename basic_string<CharT, Traits>::pointer
4082 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4084 non_sso_data().reserve(count + 1);
4085 non_sso_data().assign(count, ch);
4086 non_sso_data().push_back(value_type(
'\0'));
4088 return non_sso_data().data();
4095 template <
typename CharT,
typename Traits>
4096 typename basic_string<CharT, Traits>::pointer
4099 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4101 typename basic_string::pointer ptr;
4103 if (other.size() <= sso_capacity) {
4105 ptr = assign_sso_data(other.cbegin(), other.cend());
4108 detail::conditional_add_to_tx(&non_sso_data(), 1,
4109 POBJ_XADD_NO_SNAPSHOT);
4110 detail::create<non_sso_type>(&non_sso_data());
4112 assert(!other.is_sso_used());
4113 non_sso_data() = std::move(other.non_sso_data());
4115 ptr = non_sso_data().data();
4118 if (other.is_sso_used())
4119 other.initialize(0U, value_type(
'\0'));
4127 template <
typename CharT,
typename Traits>
4133 if (is_sso_used() && other.is_sso_used()) {
4134 sso_data().swap(other.sso_data());
4135 pmem::obj::swap(sso._size, other.sso._size);
4136 }
else if (!is_sso_used() && !other.is_sso_used()) {
4137 non_sso_data().swap(other.non_sso_data());
4139 basic_string *_short, *_long;
4140 if (size() > other.size()) {
4148 std::basic_string<CharT, Traits> tmp(_short->c_str(),
4159 template <
typename CharT,
typename Traits>
4168 template <
typename CharT,
typename Traits>
4178 template <
typename CharT,
typename Traits>
4182 if (pmemobj_pool_by_ptr(
this) ==
nullptr)
4189 template <
typename CharT,
typename Traits>
4193 if (pmemobj_tx_stage() != TX_STAGE_WORK)
4195 "Call made out of transaction scope.");
4202 template <
typename CharT,
typename Traits>
4207 check_tx_stage_work();
4213 template <
typename CharT,
typename Traits>
4216 size_type num)
const
4218 assert(idx_first + num <= sso_capacity + 1);
4219 assert(is_sso_used());
4221 auto initialized_num = get_sso_size() + 1 - idx_first;
4224 detail::conditional_add_to_tx(&sso_data()._data[0] + idx_first,
4225 (std::min)(initialized_num, num));
4227 if (num > initialized_num) {
4229 detail::conditional_add_to_tx(
4230 &sso_data()._data[0] + get_sso_size() + 1,
4231 num - initialized_num, POBJ_XADD_NO_SNAPSHOT);
4238 template <
typename CharT,
typename Traits>
4239 typename basic_string<CharT, Traits>::size_type
4242 return sso._size & ~_sso_mask;
4248 template <
typename CharT,
typename Traits>
4254 sso._size |= (size_type)(_sso_mask);
4260 template <
typename CharT,
typename Traits>
4264 sso._size &= ~_sso_mask;
4270 template <
typename CharT,
typename Traits>
4274 sso._size = new_size | _sso_mask;
4288 template <
typename CharT,
typename Traits>
4292 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4293 assert(new_capacity > sso_capacity);
4294 assert(is_sso_used());
4300 tmp[sz] = value_type(
'\0');
4303 allocate(new_capacity);
4310 assert(!is_sso_used());
4322 template <
typename CharT,
typename Traits>
4326 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4327 assert(!is_sso_used());
4331 assert(sz <= sso_capacity);
4335 tmp[sz] = value_type(
'\0');
4345 assert(is_sso_used());
4348 template <
typename CharT,
typename Traits>
4352 assert(!is_sso_used());
4353 return non_sso._data;
4356 template <
typename CharT,
typename Traits>
4357 typename basic_string<CharT, Traits>::sso_type &
4358 basic_string<CharT, Traits>::sso_data()
4360 assert(is_sso_used());
4364 template <
typename CharT,
typename Traits>
4365 const typename basic_string<CharT, Traits>::non_sso_type &
4366 basic_string<CharT, Traits>::non_sso_data()
const
4368 assert(!is_sso_used());
4369 return non_sso._data;
4372 template <
typename CharT,
typename Traits>
4373 const typename basic_string<CharT, Traits>::sso_type &
4374 basic_string<CharT, Traits>::sso_data()
const
4376 assert(is_sso_used());
4384 template <
typename CharT,
typename Traits>
4385 template <
typename T,
typename Enable>
4386 basic_string<CharT, Traits> &
4389 return erase(
static_cast<size_type
>(param));
4396 template <
typename CharT,
typename Traits>
4397 template <
typename T,
typename Enable>
4401 return erase(
static_cast<const_iterator
>(param));
4409 template <
typename CharT,
typename Traits>
4410 template <
typename T,
typename Enable>
4414 return insert(
static_cast<size_type
>(param), count, ch);
4422 template <
typename CharT,
typename Traits>
4423 template <
typename T,
typename Enable>
4427 return insert(
static_cast<const_iterator
>(param), count, ch);
4433 template <
class CharT,
class Traits>
4444 template <
class CharT,
class Traits>
4455 template <
class CharT,
class Traits>
4466 template <
class CharT,
class Traits>
4477 template <
class CharT,
class Traits>
4488 template <
class CharT,
class Traits>
4499 template <
class CharT,
class Traits>
4509 template <
class CharT,
class Traits>
4519 template <
class CharT,
class Traits>
4529 template <
class CharT,
class Traits>
4539 template <
class CharT,
class Traits>
4549 template <
class CharT,
class Traits>
4559 template <
class CharT,
class Traits>
4569 template <
class CharT,
class Traits>
4579 template <
class CharT,
class Traits>
4589 template <
class CharT,
class Traits>
4599 template <
class CharT,
class Traits>
4609 template <
class CharT,
class Traits>
4619 template <
class CharT,
class Traits>
4630 template <
class CharT,
class Traits>
4641 template <
class CharT,
class Traits>
4643 operator<(
const std::basic_string<CharT, Traits> &lhs,
4652 template <
class CharT,
class Traits>
4654 operator<=(
const std::basic_string<CharT, Traits> &lhs,
4663 template <
class CharT,
class Traits>
4674 template <
class CharT,
class Traits>
4685 template <
class CharT,
class Traits>
4688 const std::basic_string<CharT, Traits> &rhs)
4696 template <
class CharT,
class Traits>
4699 const std::basic_string<CharT, Traits> &rhs)
4707 template <
class CharT,
class Traits>
4710 const std::basic_string<CharT, Traits> &rhs)
4718 template <
class CharT,
class Traits>
4721 const std::basic_string<CharT, Traits> &rhs)
4729 template <
class CharT,
class Traits>
4732 const std::basic_string<CharT, Traits> &rhs)
4740 template <
class CharT,
class Traits>
4743 const std::basic_string<CharT, Traits> &rhs)
4751 template <
class CharT,
class Traits>
4755 return lhs.
swap(rhs);