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>;
63 using for_each_ptr_function =
67 static constexpr size_type sso_capacity = (32 - 8) /
sizeof(CharT) - 1;
73 size_type count = npos);
74 basic_string(
const std::basic_string<CharT> &other, size_type pos,
75 size_type count = npos);
80 typename Enable =
typename std::enable_if<
89 typename Enable =
typename std::enable_if<
90 std::is_convertible<
const T &,
92 CharT, Traits>>::value &&
93 !std::is_convertible<const T &, const CharT *>::value>>
96 typename Enable =
typename std::enable_if<std::is_convertible<
113 typename Enable =
typename std::enable_if<
114 std::is_convertible<
const T &,
116 CharT, Traits>>::value &&
117 !std::is_convertible<const T &, const CharT *>::value>>
125 size_type count = npos);
127 size_type pos, size_type count = npos);
130 template <
typename InputIt,
138 reference
at(size_type n);
139 const_reference
at(size_type n)
const;
140 const_reference
const_at(size_type n)
const;
142 const_reference
operator[](size_type n)
const;
144 const CharT &
front()
const;
145 const CharT &
cfront()
const;
147 const CharT &
back()
const;
148 const CharT &
cback()
const;
150 const CharT *
data()
const noexcept;
151 const CharT *
cdata()
const noexcept;
152 const CharT *
c_str()
const noexcept;
158 size_type snapshot_size);
164 const_iterator
begin()
const noexcept;
165 const_iterator
cbegin()
const noexcept;
167 const_iterator
end()
const noexcept;
168 const_iterator
cend()
const noexcept;
169 reverse_iterator
rbegin();
170 const_reverse_iterator
rbegin()
const noexcept;
171 const_reverse_iterator
crbegin()
const noexcept;
172 reverse_iterator
rend();
173 const_reverse_iterator
rend()
const noexcept;
174 const_reverse_iterator
crend()
const noexcept;
177 bool empty()
const noexcept;
178 size_type
size()
const noexcept;
179 size_type
length()
const noexcept;
180 size_type
max_size()
const noexcept;
181 size_type
capacity()
const noexcept;
182 void resize(size_type count, CharT ch);
184 void reserve(size_type new_cap = 0);
194 template <
typename T,
195 typename Enable =
typename std::enable_if<
196 std::is_convertible<T, size_type>::value>::type>
198 template <
typename T,
199 typename Enable =
typename std::enable_if<
200 !std::is_convertible<T, size_type>::value>::type>
207 size_type count = npos);
210 template <
typename InputIt,
226 size_type index2, size_type count = npos);
229 template <
typename InputIt,
233 iterator insert(const_iterator pos, std::initializer_list<CharT> ilist);
234 template <
typename T,
235 typename Enable =
typename std::enable_if<
236 std::is_convertible<T, size_type>::value>::type>
238 template <
typename T,
239 typename Enable =
typename std::enable_if<
240 !std::is_convertible<T, size_type>::value>::type>
249 size_type count2 = npos);
250 template <
typename InputIt,
254 InputIt first2, InputIt last2);
256 const CharT *s, size_type count2);
260 size_type count2, CharT ch);
262 size_type count2, CharT ch);
267 std::initializer_list<CharT> ilist);
269 size_type
copy(CharT *s, size_type count, size_type index = 0)
const;
272 int compare(
const std::basic_string<CharT> &other)
const;
273 int compare(size_type pos, size_type count,
275 int compare(size_type pos, size_type count,
276 const std::basic_string<CharT> &other)
const;
278 size_type pos2, size_type count2 = npos)
const;
279 int compare(size_type pos1, size_type count1,
280 const std::basic_string<CharT> &other, size_type pos2,
281 size_type count2 = npos)
const;
282 int compare(
const CharT *s)
const;
283 int compare(size_type pos, size_type count,
const CharT *s)
const;
284 int compare(size_type pos, size_type count1,
const CharT *s,
285 size_type count2)
const;
290 size_type
find(
const CharT *s, size_type pos, size_type count)
const;
291 size_type
find(
const CharT *s, size_type pos = 0)
const;
292 size_type
find(CharT ch, size_type pos = 0)
const noexcept;
295 size_type
rfind(
const CharT *s, size_type pos, size_type count)
const;
296 size_type
rfind(
const CharT *s, size_type pos = npos)
const;
297 size_type
rfind(CharT ch, size_type pos = npos)
const noexcept;
299 size_type pos = 0)
const noexcept;
301 size_type count)
const;
302 size_type
find_first_of(
const CharT *s, size_type pos = 0)
const;
303 size_type
find_first_of(CharT ch, size_type pos = 0)
const noexcept;
305 size_type pos = 0)
const noexcept;
307 size_type count)
const;
311 size_type pos = npos)
const noexcept;
313 size_type count)
const;
314 size_type
find_last_of(
const CharT *s, size_type pos = npos)
const;
315 size_type
find_last_of(CharT ch, size_type pos = npos)
const noexcept;
317 size_type pos = npos)
const noexcept;
319 size_type count)
const;
329 static const size_type npos =
static_cast<size_type
>(-1);
373 static constexpr size_type _sso_mask = 1ULL
374 << (std::numeric_limits<size_type>::digits - 1);
377 bool is_sso_used()
const;
381 typename Enable =
typename std::enable_if<
383 size_type
get_size(InputIt first, InputIt last)
const;
384 size_type
get_size(size_type count, value_type ch)
const;
386 template <
typename... Args>
388 template <
typename... Args>
393 typename Enable =
typename std::enable_if<
400 typename Enable =
typename std::enable_if<
418 non_sso_data()
const;
431 template <
typename CharT,
typename Traits>
438 initialize(0U, value_type(
'\0'));
455 template <
typename CharT,
typename Traits>
462 initialize(count, ch);
482 template <
typename CharT,
typename Traits>
484 size_type pos, size_type count)
489 if (pos > other.
size())
490 throw std::out_of_range(
"Index out of range.");
492 if (count == npos || pos + count > other.
size())
493 count = other.
size() - pos;
495 auto first =
static_cast<difference_type
>(pos);
496 auto last = first +
static_cast<difference_type
>(count);
499 initialize(other.
cbegin() + first, other.
cbegin() + last);
520 template <
typename CharT,
typename Traits>
522 size_type pos, size_type count)
542 template <
typename CharT,
typename Traits>
549 initialize(s, s + count);
565 template <
typename CharT,
typename Traits>
571 auto length = traits_type::length(s);
574 initialize(s, s + length);
593 template <
typename CharT,
typename Traits>
594 template <
typename InputIt,
typename Enable>
597 auto len = std::distance(first, last);
603 allocate(
static_cast<size_type
>(len));
604 initialize(first, last);
621 template <
typename CharT,
typename Traits>
627 allocate(other.
size());
646 template <
typename CharT,
typename Traits>
666 template <
typename CharT,
typename Traits>
672 move_data(std::move(other));
689 template <
typename CharT,
typename Traits>
695 allocate(ilist.size());
696 initialize(ilist.begin(), ilist.end());
714 template <
typename CharT,
typename Traits>
715 template <
class T,
typename Enable>
744 template <
typename CharT,
typename Traits>
745 template <
class T,
typename Enable>
755 throw std::out_of_range(
"Index out of range.");
757 if (n == npos || pos + n > sv.
size())
761 auto last = first + n;
764 initialize(sv.
data() + first, sv.
data() + last);
770 template <
typename CharT,
typename Traits>
789 template <
typename CharT,
typename Traits>
793 return assign(other);
806 template <
typename CharT,
typename Traits>
810 return assign(other);
822 template <
typename CharT,
typename Traits>
826 return assign(std::move(other));
837 template <
typename CharT,
typename Traits>
852 template <
typename CharT,
typename Traits>
856 return assign(1, ch);
868 template <
typename CharT,
typename Traits>
872 return assign(ilist);
884 template <
typename CharT,
typename Traits>
885 template <
class T,
typename Enable>
890 return assign(sv.
data(), sv.
size());
903 template <
typename CharT,
typename Traits>
907 auto pop = get_pool();
923 template <
typename CharT,
typename Traits>
930 auto pop = get_pool();
933 pop, [&] { replace_content(other.
cbegin(), other.
cend()); });
948 template <
typename CharT,
typename Traits>
952 return assign(other.cbegin(), other.cend());
967 template <
typename CharT,
typename Traits>
972 if (pos > other.
size())
973 throw std::out_of_range(
"Index out of range.");
975 if (count == npos || pos + count > other.
size())
976 count = other.
size() - pos;
978 auto pop = get_pool();
979 auto first =
static_cast<difference_type
>(pos);
980 auto last = first +
static_cast<difference_type
>(count);
983 replace_content(other.
cbegin() + first, other.
cbegin() + last);
1003 template <
typename CharT,
typename Traits>
1006 size_type pos, size_type count)
1008 if (pos > other.size())
1009 throw std::out_of_range(
"Index out of range.");
1011 if (count == npos || pos + count > other.size())
1012 count = other.size() - pos;
1014 return assign(other.c_str() + pos, count);
1027 template <
typename CharT,
typename Traits>
1031 auto pop = get_pool();
1046 template <
typename CharT,
typename Traits>
1050 auto pop = get_pool();
1052 auto length = traits_type::length(s);
1070 template <
typename CharT,
typename Traits>
1071 template <
typename InputIt,
typename Enable>
1075 auto pop = get_pool();
1091 template <
typename CharT,
typename Traits>
1098 auto pop = get_pool();
1102 move_data(std::move(other));
1117 template <
typename CharT,
typename Traits>
1121 return assign(ilist.begin(), ilist.end());
1131 template <
typename CharT,
typename Traits>
1135 if (!is_sso_used()) {
1136 non_sso._data.for_each_ptr(func);
1145 template <
typename CharT,
typename Traits>
1158 template <
typename CharT,
typename Traits>
1159 typename basic_string<CharT, Traits>::const_iterator
1170 template <
typename CharT,
typename Traits>
1171 typename basic_string<CharT, Traits>::const_iterator
1174 return is_sso_used() ? const_iterator(&*sso_data().
cbegin())
1175 : const_iterator(&*non_sso_data().
cbegin());
1183 template <
typename CharT,
typename Traits>
1187 return begin() +
static_cast<difference_type
>(size());
1196 template <
typename CharT,
typename Traits>
1197 typename basic_string<CharT, Traits>::const_iterator
1200 return cbegin() +
static_cast<difference_type
>(size());
1209 template <
typename CharT,
typename Traits>
1210 typename basic_string<CharT, Traits>::const_iterator
1213 return cbegin() +
static_cast<difference_type
>(size());
1222 template <
typename CharT,
typename Traits>
1223 typename basic_string<CharT, Traits>::reverse_iterator
1226 return reverse_iterator(
end());
1235 template <
typename CharT,
typename Traits>
1236 typename basic_string<CharT, Traits>::const_reverse_iterator
1248 template <
typename CharT,
typename Traits>
1249 typename basic_string<CharT, Traits>::const_reverse_iterator
1252 return const_reverse_iterator(
cend());
1261 template <
typename CharT,
typename Traits>
1262 typename basic_string<CharT, Traits>::reverse_iterator
1265 return reverse_iterator(
begin());
1274 template <
typename CharT,
typename Traits>
1275 typename basic_string<CharT, Traits>::const_reverse_iterator
1287 template <
typename CharT,
typename Traits>
1288 typename basic_string<CharT, Traits>::const_reverse_iterator
1291 return const_reverse_iterator(
cbegin());
1307 template <
typename CharT,
typename Traits>
1308 typename basic_string<CharT, Traits>::reference
1312 throw std::out_of_range(
"string::at");
1314 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1327 template <
typename CharT,
typename Traits>
1328 typename basic_string<CharT, Traits>::const_reference
1347 template <
typename CharT,
typename Traits>
1348 typename basic_string<CharT, Traits>::const_reference
1352 throw std::out_of_range(
"string::const_at");
1354 return is_sso_used()
1355 ?
static_cast<const sso_type &
>(sso_data())[n]
1356 :
static_cast<const non_sso_type &
>(non_sso_data())[n];
1370 template <
typename CharT,
typename Traits>
1371 typename basic_string<CharT, Traits>::reference
1374 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1384 template <
typename CharT,
typename Traits>
1385 typename basic_string<CharT, Traits>::const_reference
1388 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1404 template <
typename CharT,
typename Traits>
1408 if (start + n > size())
1409 throw std::out_of_range(
"basic_string::range");
1411 return is_sso_used() ? sso_data().range(start, n)
1412 : non_sso_data().range(start, n);
1431 template <
typename CharT,
typename Traits>
1434 size_type snapshot_size)
1436 if (start + n > size())
1437 throw std::out_of_range(
"basic_string::range");
1439 if (snapshot_size > n)
1442 return is_sso_used() ? sso_data().range(start, n, snapshot_size)
1443 : non_sso_data().range(start, n, snapshot_size);
1457 template <
typename CharT,
typename Traits>
1461 return crange(start, n);
1475 template <
typename CharT,
typename Traits>
1479 if (start + n > size())
1480 throw std::out_of_range(
"basic_string::range");
1482 return {const_iterator(cdata() + start),
1483 const_iterator(cdata() + start + n)};
1495 template <
typename CharT,
typename Traits>
1507 template <
typename CharT,
typename Traits>
1522 template <
typename CharT,
typename Traits>
1538 template <
typename CharT,
typename Traits>
1542 return (*
this)[size() - 1];
1550 template <
typename CharT,
typename Traits>
1565 template <
typename CharT,
typename Traits>
1569 return static_cast<const basic_string &
>(*this)[size() - 1];
1575 template <
typename CharT,
typename Traits>
1576 typename basic_string<CharT, Traits>::size_type
1580 return get_sso_size();
1581 else if (non_sso_data().size() == 0)
1584 return non_sso_data().size() - 1;
1593 template <
typename CharT,
typename Traits>
1597 return is_sso_used() ? sso_data().range(0, get_sso_size() + 1).begin()
1598 : non_sso_data().data();
1619 template <
typename CharT,
typename Traits>
1626 throw std::out_of_range(
"Index exceeds size.");
1628 count = (std::min)(count, sz - index);
1630 auto pop = get_pool();
1632 auto first =
begin() +
static_cast<difference_type
>(index);
1633 auto last = first +
static_cast<difference_type
>(count);
1635 if (is_sso_used()) {
1637 auto move_len = sz - index - count;
1638 auto new_size = sz - count;
1642 sso_data().range(index, move_len + 1);
1643 traits_type::move(range.begin(), &*last,
1646 assert(range.end() - 1 ==
1647 &sso_data()._data[index + move_len]);
1650 sso_data()[index + move_len] = value_type(
'\0');
1651 set_sso_size(new_size);
1654 non_sso_data().erase(first, last);
1676 template <
typename CharT,
typename Traits>
1680 return erase(pos, pos + 1);
1701 template <
typename CharT,
typename Traits>
1706 static_cast<size_type
>(std::distance(
cbegin(), first));
1707 size_type len =
static_cast<size_type
>(std::distance(first, last));
1711 return begin() +
static_cast<difference_type
>(index);
1724 template <
typename CharT,
typename Traits>
1728 erase(size() - 1, 1);
1750 template <
typename CharT,
typename Traits>
1755 auto new_size = sz + count;
1757 if (new_size > max_size())
1758 throw std::length_error(
"Size exceeds max size.");
1760 if (is_sso_used()) {
1761 auto pop = get_pool();
1764 if (new_size > sso_capacity) {
1765 sso_to_large(new_size);
1767 non_sso_data().insert(
1768 non_sso_data().
cbegin() +
1769 static_cast<difference_type
>(
1773 add_sso_to_tx(sz, count + 1);
1774 traits_type::assign(&sso_data()._data[sz],
1777 assert(new_size == sz + count);
1778 set_sso_size(new_size);
1779 sso_data()._data[new_size] = value_type(
'\0');
1783 non_sso_data().insert(non_sso_data().
cbegin() +
1784 static_cast<difference_type
>(sz),
1809 template <
typename CharT,
typename Traits>
1813 return append(str.
data(), str.
size());
1841 template <
typename CharT,
typename Traits>
1846 auto sz = str.
size();
1849 throw std::out_of_range(
"Index out of range.");
1851 count = (std::min)(count, sz - pos);
1853 append(str.
data() + pos, count);
1877 template <
typename CharT,
typename Traits>
1881 return append(s, s + count);
1903 template <
typename CharT,
typename Traits>
1907 return append(s, traits_type::length(s));
1931 template <
typename CharT,
typename Traits>
1932 template <
typename InputIt,
typename Enable>
1937 auto count =
static_cast<size_type
>(std::distance(first, last));
1938 auto new_size = sz + count;
1940 if (new_size > max_size())
1941 throw std::length_error(
"Size exceeds max size.");
1943 if (is_sso_used()) {
1944 auto pop = get_pool();
1947 if (new_size > sso_capacity) {
1956 std::vector<value_type> str(first, last);
1958 sso_to_large(new_size);
1959 non_sso_data().insert(
1960 non_sso_data().
cbegin() +
1961 static_cast<difference_type
>(
1963 str.begin(), str.end());
1965 add_sso_to_tx(sz, count + 1);
1966 std::copy(first, last, &sso_data()._data[sz]);
1968 assert(new_size == sz + count);
1969 set_sso_size(new_size);
1970 sso_data()._data[new_size] = value_type(
'\0');
1974 non_sso_data().insert(non_sso_data().
cbegin() +
1975 static_cast<difference_type
>(sz),
2000 template <
typename CharT,
typename Traits>
2004 return append(ilist.begin(), ilist.end());
2023 template <
typename CharT,
typename Traits>
2027 append(
static_cast<size_type
>(1), ch);
2048 template <
typename CharT,
typename Traits>
2074 template <
typename CharT,
typename Traits>
2097 template <
typename CharT,
typename Traits>
2124 template <
typename CharT,
typename Traits>
2128 return append(ilist);
2152 template <
typename CharT,
typename Traits>
2157 throw std::out_of_range(
"Index out of range.");
2159 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2161 insert(pos, count, ch);
2187 template <
typename CharT,
typename Traits>
2191 return insert(index, s, traits_type::length(s));
2215 template <
typename CharT,
typename Traits>
2221 throw std::out_of_range(
"Index out of range.");
2223 auto pos =
cbegin() +
static_cast<difference_type
>(index);
2225 insert(pos, s, s + count);
2250 template <
typename CharT,
typename Traits>
2254 return insert(index, str.
data(), str.
size());
2279 template <
typename CharT,
typename Traits>
2282 size_type index2, size_type count)
2284 auto sz = str.
size();
2286 if (index1 > size() || index2 > sz)
2287 throw std::out_of_range(
"Index out of range.");
2289 count = (std::min)(count, sz - index2);
2291 return insert(index1, str.
data() + index2, count);
2316 template <
typename CharT,
typename Traits>
2320 return insert(pos, 1, ch);
2347 template <
typename CharT,
typename Traits>
2354 if (sz + count > max_size())
2355 throw std::length_error(
"Count exceeds max size.");
2357 auto new_size = sz + count;
2359 auto pop = get_pool();
2361 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2364 if (is_sso_used() && new_size <= sso_capacity) {
2365 auto len = sz - index;
2367 add_sso_to_tx(index, len + count + 1);
2369 traits_type::move(&sso_data()._data[index + count],
2370 &sso_data()._data[index], len);
2371 traits_type::assign(&sso_data()._data[index], count,
2374 assert(new_size == index + len + count);
2375 set_sso_size(new_size);
2376 sso_data()._data[new_size] = value_type(
'\0');
2379 sso_to_large(new_size);
2381 non_sso_data().insert(
2382 non_sso_data().
begin() +
2383 static_cast<difference_type
>(index),
2388 return iterator(&data()[
static_cast<difference_type
>(index)]);
2415 template <
typename CharT,
typename Traits>
2416 template <
typename InputIt,
typename Enable>
2423 auto count =
static_cast<size_type
>(std::distance(first, last));
2425 if (sz + count > max_size())
2426 throw std::length_error(
"Count exceeds max size.");
2428 auto pop = get_pool();
2430 auto new_size = sz + count;
2432 auto index =
static_cast<size_type
>(std::distance(
cbegin(), pos));
2435 if (is_sso_used() && new_size <= sso_capacity) {
2436 auto len = sz - index;
2438 add_sso_to_tx(index, len + count + 1);
2440 traits_type::move(&sso_data()._data[index + count],
2441 &sso_data()._data[index], len);
2442 std::copy(first, last, &sso_data()._data[index]);
2444 assert(new_size == index + len + count);
2445 set_sso_size(new_size);
2446 sso_data()._data[new_size] = value_type(
'\0');
2448 if (is_sso_used()) {
2457 std::vector<value_type> str(first, last);
2459 sso_to_large(new_size);
2460 non_sso_data().insert(
2461 non_sso_data().
begin() +
2462 static_cast<difference_type
>(
2464 str.begin(), str.end());
2466 non_sso_data().insert(
2467 non_sso_data().
begin() +
2468 static_cast<difference_type
>(
2475 return iterator(&data()[
static_cast<difference_type
>(index)]);
2501 template <
typename CharT,
typename Traits>
2504 std::initializer_list<CharT> ilist)
2506 return insert(pos, ilist.begin(), ilist.end());
2531 template <
typename CharT,
typename Traits>
2536 return replace(index, count, str.
data(), str.
size());
2559 template <
typename CharT,
typename Traits>
2564 return replace(first, last, str.
data(), str.
data() + str.
size());
2593 template <
typename CharT,
typename Traits>
2599 auto sz = str.
size();
2602 throw std::out_of_range(
"Index out of range.");
2604 count2 = (std::min)(count2, sz - index2);
2606 return replace(index, count, str.
data() + index2, count2);
2634 template <
typename CharT,
typename Traits>
2635 template <
typename InputIt,
typename Enable>
2638 InputIt first2, InputIt last2)
2641 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2642 auto count =
static_cast<size_type
>(std::distance(first, last));
2643 auto count2 =
static_cast<size_type
>(std::distance(first2, last2));
2645 count = (std::min)(count, sz - index);
2647 if (sz - count + count2 > max_size())
2648 throw std::length_error(
"Count exceeds max size.");
2650 auto new_size = sz - count + count2;
2652 auto pop = get_pool();
2655 if (is_sso_used() && new_size <= sso_capacity) {
2656 add_sso_to_tx(index, new_size - index + 1);
2658 assert(count2 < new_size + 1);
2659 traits_type::move(&sso_data()._data[index + count2],
2660 &sso_data()._data[index + count],
2661 sz - index - count);
2662 std::copy(first2, last2, &sso_data()._data[index]);
2664 set_sso_size(new_size);
2665 sso_data()._data[new_size] = value_type(
'\0');
2675 std::vector<value_type> str(first2, last2);
2677 if (is_sso_used()) {
2678 sso_to_large(new_size);
2682 begin() +
static_cast<difference_type
>(index);
2683 auto end = beg +
static_cast<difference_type
>(count);
2684 non_sso_data().erase(beg,
end);
2685 non_sso_data().insert(beg, str.begin(), str.end());
2688 if (!is_sso_used() && new_size <= sso_capacity)
2717 template <
typename CharT,
typename Traits>
2720 const CharT *s, size_type count2)
2722 return replace(first, last, s, s + count2);
2748 template <
typename CharT,
typename Traits>
2751 const CharT *s, size_type count2)
2754 throw std::out_of_range(
"Index out of range.");
2756 auto first =
cbegin() +
static_cast<difference_type
>(index);
2757 auto last = first +
static_cast<difference_type
>(count);
2759 return replace(first, last, s, s + count2);
2785 template <
typename CharT,
typename Traits>
2790 return replace(index, count, s, traits_type::length(s));
2816 template <
typename CharT,
typename Traits>
2819 size_type count2, CharT ch)
2822 throw std::out_of_range(
"Index out of range.");
2824 auto first =
cbegin() +
static_cast<difference_type
>(index);
2825 auto last = first +
static_cast<difference_type
>(count);
2827 return replace(first, last, count2, ch);
2852 template <
typename CharT,
typename Traits>
2855 size_type count2, CharT ch)
2858 auto index =
static_cast<size_type
>(std::distance(
cbegin(), first));
2859 auto count =
static_cast<size_type
>(std::distance(first, last));
2861 count = (std::min)(count, sz - index);
2863 if (sz - count + count2 > max_size())
2864 throw std::length_error(
"Count exceeds max size.");
2866 auto new_size = sz - count + count2;
2868 auto pop = get_pool();
2871 if (is_sso_used() && new_size <= sso_capacity) {
2872 add_sso_to_tx(index, new_size - index + 1);
2874 assert(count2 < new_size + 1);
2875 traits_type::move(&sso_data()._data[index + count2],
2876 &sso_data()._data[index + count],
2877 sz - index - count);
2878 traits_type::assign(&sso_data()._data[index], count2,
2881 set_sso_size(new_size);
2882 sso_data()._data[new_size] = value_type(
'\0');
2884 if (is_sso_used()) {
2885 sso_to_large(new_size);
2889 begin() +
static_cast<difference_type
>(index);
2890 auto end = beg +
static_cast<difference_type
>(count);
2891 non_sso_data().erase(beg,
end);
2892 non_sso_data().insert(beg, count2, ch);
2895 if (!is_sso_used() && new_size <= sso_capacity)
2923 template <
typename CharT,
typename Traits>
2928 return replace(first, last, s, traits_type::length(s));
2953 template <
typename CharT,
typename Traits>
2956 std::initializer_list<CharT> ilist)
2958 return replace(first, last, ilist.begin(), ilist.end());
2974 template <
typename CharT,
typename Traits>
2975 typename basic_string<CharT, Traits>::size_type
2977 size_type index)
const
2982 throw std::out_of_range(
"Index out of range.");
2984 auto len = (std::min)(count, sz - index);
2986 traits_type::copy(s, data() + index, len);
3008 template <
typename CharT,
typename Traits>
3011 const CharT *s, size_type count2)
const
3014 throw std::out_of_range(
"Index out of range.");
3016 if (count1 > size() - pos)
3017 count1 = size() - pos;
3019 auto ret = traits_type::compare(cdata() + pos, s,
3020 std::min<size_type>(count1, count2));
3025 if (count1 < count2)
3027 else if (count1 == count2)
3042 template <
typename CharT,
typename Traits>
3043 typename basic_string<CharT, Traits>::size_type
3047 return find(str.data(), pos, str.size());
3061 template <
typename CharT,
typename Traits>
3062 typename basic_string<CharT, Traits>::size_type
3064 size_type count)
const
3079 template <
typename CharT,
typename Traits>
3080 typename basic_string<CharT, Traits>::size_type
3083 return find(s, pos, traits_type::length(s));
3095 template <
typename CharT,
typename Traits>
3096 typename basic_string<CharT, Traits>::size_type
3099 return find(&ch, pos, 1);
3112 template <
typename CharT,
typename Traits>
3113 typename basic_string<CharT, Traits>::size_type
3117 return rfind(str.cdata(), pos, str.size());
3136 template <
typename CharT,
typename Traits>
3137 typename basic_string<CharT, Traits>::size_type
3139 size_type count)
const
3156 template <
typename CharT,
typename Traits>
3157 typename basic_string<CharT, Traits>::size_type
3160 return rfind(s, pos, traits_type::length(s));
3174 template <
typename CharT,
typename Traits>
3175 typename basic_string<CharT, Traits>::size_type
3178 return rfind(&ch, pos, 1);
3190 template <
typename CharT,
typename Traits>
3191 typename basic_string<CharT, Traits>::size_type
3193 size_type pos)
const noexcept
3195 return find_first_of(str.cdata(), pos, str.size());
3211 template <
typename CharT,
typename Traits>
3212 typename basic_string<CharT, Traits>::size_type
3214 size_type count)
const
3232 template <
typename CharT,
typename Traits>
3233 typename basic_string<CharT, Traits>::size_type
3236 return find_first_of(s, pos, traits_type::length(s));
3248 template <
typename CharT,
typename Traits>
3249 typename basic_string<CharT, Traits>::size_type
3253 return find(ch, pos);
3265 template <
typename CharT,
typename Traits>
3266 typename basic_string<CharT, Traits>::size_type
3268 size_type pos)
const noexcept
3270 return find_first_not_of(str.cdata(), pos, str.size());
3286 template <
typename CharT,
typename Traits>
3287 typename basic_string<CharT, Traits>::size_type
3289 size_type count)
const
3307 template <
typename CharT,
typename Traits>
3308 typename basic_string<CharT, Traits>::size_type
3310 size_type pos)
const
3312 return find_first_not_of(s, pos, traits_type::length(s));
3324 template <
typename CharT,
typename Traits>
3325 typename basic_string<CharT, Traits>::size_type
3329 return find_first_not_of(&ch, pos, 1);
3341 template <
typename CharT,
typename Traits>
3342 typename basic_string<CharT, Traits>::size_type
3344 size_type pos)
const noexcept
3346 return find_last_of(str.cdata(), pos, str.size());
3362 template <
typename CharT,
typename Traits>
3363 typename basic_string<CharT, Traits>::size_type
3365 size_type count)
const
3383 template <
typename CharT,
typename Traits>
3384 typename basic_string<CharT, Traits>::size_type
3387 return find_last_of(s, pos, traits_type::length(s));
3399 template <
typename CharT,
typename Traits>
3400 typename basic_string<CharT, Traits>::size_type
3404 return rfind(ch, pos);
3416 template <
typename CharT,
typename Traits>
3417 typename basic_string<CharT, Traits>::size_type
3419 size_type pos)
const noexcept
3421 return find_last_not_of(str.cdata(), pos, str.size());
3437 template <
typename CharT,
typename Traits>
3438 typename basic_string<CharT, Traits>::size_type
3440 size_type count)
const
3458 template <
typename CharT,
typename Traits>
3459 typename basic_string<CharT, Traits>::size_type
3461 size_type pos)
const
3463 return find_last_not_of(s, pos, traits_type::length(s));
3475 template <
typename CharT,
typename Traits>
3476 typename basic_string<CharT, Traits>::size_type
3480 return find_last_not_of(&ch, pos, 1);
3491 template <
typename CharT,
typename Traits>
3495 return compare(0, size(), other.
cdata(), other.
size());
3506 template <
typename CharT,
typename Traits>
3509 const std::basic_string<CharT> &other)
const
3511 return compare(0, size(), other.data(), other.size());
3527 template <
typename CharT,
typename Traits>
3532 return compare(pos, count, other.
cdata(), other.
size());
3549 template <
typename CharT,
typename Traits>
3552 size_type pos, size_type count,
3553 const std::basic_string<CharT> &other)
const
3555 return compare(pos, count, other.data(), other.size());
3576 template <
typename CharT,
typename Traits>
3580 size_type count2)
const
3582 if (pos2 > other.
size())
3583 throw std::out_of_range(
"Index out of range.");
3585 if (count2 > other.
size() - pos2)
3586 count2 = other.
size() - pos2;
3588 return compare(pos1, count1, other.
cdata() + pos2, count2);
3609 template <
typename CharT,
typename Traits>
3612 const std::basic_string<CharT> &other,
3613 size_type pos2, size_type count2)
const
3615 if (pos2 > other.size())
3616 throw std::out_of_range(
"Index out of range.");
3618 if (count2 > other.size() - pos2)
3619 count2 = other.size() - pos2;
3621 return compare(pos1, count1, other.data() + pos2, count2);
3632 template <
typename CharT,
typename Traits>
3636 return compare(0, size(), s, traits_type::length(s));
3652 template <
typename CharT,
typename Traits>
3655 const CharT *s)
const
3657 return compare(pos, count, s, traits_type::length(s));
3663 template <
typename CharT,
typename Traits>
3667 return is_sso_used() ? sso_data().cdata() : non_sso_data().cdata();
3673 template <
typename CharT,
typename Traits>
3683 template <
typename CharT,
typename Traits>
3693 template <
typename CharT,
typename Traits>
3694 typename basic_string<CharT, Traits>::size_type
3703 template <
typename CharT,
typename Traits>
3704 typename basic_string<CharT, Traits>::size_type
3707 return PMEMOBJ_MAX_ALLOC_SIZE /
sizeof(CharT) - 1;
3714 template <
typename CharT,
typename Traits>
3715 typename basic_string<CharT, Traits>::size_type
3718 return is_sso_used() ? sso_capacity : non_sso_data().capacity() - 1;
3740 template <
typename CharT,
typename Traits>
3744 if (count > max_size())
3745 throw std::length_error(
"Count exceeds max size.");
3749 auto pop = get_pool();
3753 append(count - sz, ch);
3754 }
else if (is_sso_used()) {
3755 set_sso_size(count);
3756 sso_data()[count] = value_type(
'\0');
3758 non_sso_data().resize(count + 1, ch);
3759 non_sso_data().back() = value_type(
'\0');
3782 template <
typename CharT,
typename Traits>
3786 resize(count, CharT());
3809 template <
typename CharT,
typename Traits>
3813 if (new_cap > max_size())
3814 throw std::length_error(
"New capacity exceeds max size.");
3816 if (new_cap < capacity() || new_cap <= sso_capacity)
3819 if (is_sso_used()) {
3820 auto pop = get_pool();
3824 non_sso_data().reserve(new_cap + 1);
3841 template <
typename CharT,
typename Traits>
3848 if (size() <= sso_capacity) {
3849 auto pop = get_pool();
3853 non_sso_data().shrink_to_fit();
3866 template <
typename CharT,
typename Traits>
3885 template <
typename CharT,
typename Traits>
3889 auto pop = get_pool();
3892 if (is_sso_used()) {
3893 add_sso_to_tx(0, get_sso_size() + 1);
3897 non_sso_data().free_data();
3898 detail::destroy<non_sso_type>(non_sso_data());
3907 template <
typename CharT,
typename Traits>
3914 template <
typename CharT,
typename Traits>
3918 return (sso._size & _sso_mask) != 0;
3921 template <
typename CharT,
typename Traits>
3923 basic_string<CharT, Traits>::destroy_data()
3925 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3927 if (is_sso_used()) {
3928 add_sso_to_tx(0, get_sso_size() + 1);
3931 non_sso_data().free_data();
3932 detail::destroy<non_sso_type>(non_sso_data());
3942 template <
typename CharT,
typename Traits>
3943 template <
typename InputIt,
typename Enable>
3944 typename basic_string<CharT, Traits>::size_type
3947 return static_cast<size_type
>(std::distance(first, last));
3956 template <
typename CharT,
typename Traits>
3957 typename basic_string<CharT, Traits>::size_type
3969 template <
typename CharT,
typename Traits>
3970 typename basic_string<CharT, Traits>::size_type
3973 return other.
size();
3982 template <
typename CharT,
typename Traits>
3983 template <
typename... Args>
3984 typename basic_string<CharT, Traits>::pointer
3987 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3989 auto new_size = get_size(std::forward<Args>(args)...);
3992 if (!is_sso_used() && new_size <= capacity())
3993 return assign_large_data(std::forward<Args>(args)...);
3998 return initialize(std::forward<Args>(args)...);
4011 template <
typename CharT,
typename Traits>
4012 template <
typename... Args>
4013 typename basic_string<CharT, Traits>::pointer
4016 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4018 if (is_sso_used()) {
4019 return assign_sso_data(std::forward<Args>(args)...);
4021 return assign_large_data(std::forward<Args>(args)...);
4034 template <
typename CharT,
typename Traits>
4038 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4040 if (n <= sso_capacity) {
4050 if (!is_sso_used()) {
4051 detail::conditional_add_to_tx(&non_sso_data(), 1,
4052 POBJ_XADD_NO_SNAPSHOT);
4053 detail::create<non_sso_type>(&non_sso_data());
4054 non_sso_data().reserve(n + 1);
4061 template <
typename CharT,
typename Traits>
4062 template <
typename InputIt,
typename Enable>
4063 typename basic_string<CharT, Traits>::pointer
4066 auto size =
static_cast<size_type
>(std::distance(first, last));
4068 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4069 assert(size <= sso_capacity);
4071 add_sso_to_tx(0, size + 1);
4072 std::copy(first, last, &sso_data()._data[0]);
4074 sso_data()._data[size] = value_type(
'\0');
4078 return &sso_data()[0];
4084 template <
typename CharT,
typename Traits>
4085 typename basic_string<CharT, Traits>::pointer
4088 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4089 assert(count <= sso_capacity);
4091 add_sso_to_tx(0, count + 1);
4092 traits_type::assign(&sso_data()._data[0], count, ch);
4094 sso_data()._data[count] = value_type(
'\0');
4096 set_sso_size(count);
4098 return &sso_data()[0];
4105 template <
typename CharT,
typename Traits>
4106 template <
typename InputIt,
typename Enable>
4107 typename basic_string<CharT, Traits>::pointer
4110 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4112 auto size =
static_cast<size_type
>(std::distance(first, last));
4114 non_sso_data().reserve(size + 1);
4115 non_sso_data().assign(first, last);
4116 non_sso_data().push_back(value_type(
'\0'));
4118 return non_sso_data().data();
4125 template <
typename CharT,
typename Traits>
4126 typename basic_string<CharT, Traits>::pointer
4129 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4131 non_sso_data().reserve(count + 1);
4132 non_sso_data().assign(count, ch);
4133 non_sso_data().push_back(value_type(
'\0'));
4135 return non_sso_data().data();
4142 template <
typename CharT,
typename Traits>
4143 typename basic_string<CharT, Traits>::pointer
4146 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4148 typename basic_string::pointer ptr;
4150 if (other.size() <= sso_capacity) {
4152 ptr = assign_sso_data(other.cbegin(), other.cend());
4155 detail::conditional_add_to_tx(&non_sso_data(), 1,
4156 POBJ_XADD_NO_SNAPSHOT);
4157 detail::create<non_sso_type>(&non_sso_data());
4159 assert(!other.is_sso_used());
4160 non_sso_data() = std::move(other.non_sso_data());
4162 ptr = non_sso_data().data();
4165 if (other.is_sso_used())
4166 other.initialize(0U, value_type(
'\0'));
4174 template <
typename CharT,
typename Traits>
4180 if (is_sso_used() && other.is_sso_used()) {
4181 sso_data().swap(other.sso_data());
4182 pmem::obj::swap(sso._size, other.sso._size);
4183 }
else if (!is_sso_used() && !other.is_sso_used()) {
4184 non_sso_data().swap(other.non_sso_data());
4186 basic_string *_short, *_long;
4187 if (size() > other.size()) {
4195 std::basic_string<CharT, Traits> tmp(_short->c_str(),
4206 template <
typename CharT,
typename Traits>
4215 template <
typename CharT,
typename Traits>
4225 template <
typename CharT,
typename Traits>
4229 if (pmemobj_pool_by_ptr(
this) ==
nullptr)
4236 template <
typename CharT,
typename Traits>
4240 if (pmemobj_tx_stage() != TX_STAGE_WORK)
4242 "Call made out of transaction scope.");
4249 template <
typename CharT,
typename Traits>
4254 check_tx_stage_work();
4260 template <
typename CharT,
typename Traits>
4263 size_type num)
const
4265 assert(idx_first + num <= sso_capacity + 1);
4266 assert(is_sso_used());
4268 auto initialized_num = get_sso_size() + 1 - idx_first;
4271 detail::conditional_add_to_tx(&sso_data()._data[0] + idx_first,
4272 (std::min)(initialized_num, num));
4274 if (num > initialized_num) {
4276 detail::conditional_add_to_tx(
4277 &sso_data()._data[0] + get_sso_size() + 1,
4278 num - initialized_num, POBJ_XADD_NO_SNAPSHOT);
4285 template <
typename CharT,
typename Traits>
4286 typename basic_string<CharT, Traits>::size_type
4289 return sso._size & ~_sso_mask;
4295 template <
typename CharT,
typename Traits>
4301 sso._size |= (size_type)(_sso_mask);
4307 template <
typename CharT,
typename Traits>
4311 sso._size &= ~_sso_mask;
4317 template <
typename CharT,
typename Traits>
4321 sso._size = new_size | _sso_mask;
4335 template <
typename CharT,
typename Traits>
4339 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4340 assert(new_capacity > sso_capacity);
4341 assert(is_sso_used());
4347 tmp[sz] = value_type(
'\0');
4350 allocate(new_capacity);
4357 assert(!is_sso_used());
4369 template <
typename CharT,
typename Traits>
4373 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
4374 assert(!is_sso_used());
4378 assert(sz <= sso_capacity);
4382 tmp[sz] = value_type(
'\0');
4392 assert(is_sso_used());
4395 template <
typename CharT,
typename Traits>
4399 assert(!is_sso_used());
4400 return non_sso._data;
4403 template <
typename CharT,
typename Traits>
4404 typename basic_string<CharT, Traits>::sso_type &
4405 basic_string<CharT, Traits>::sso_data()
4407 assert(is_sso_used());
4411 template <
typename CharT,
typename Traits>
4412 const typename basic_string<CharT, Traits>::non_sso_type &
4413 basic_string<CharT, Traits>::non_sso_data()
const
4415 assert(!is_sso_used());
4416 return non_sso._data;
4419 template <
typename CharT,
typename Traits>
4420 const typename basic_string<CharT, Traits>::sso_type &
4421 basic_string<CharT, Traits>::sso_data()
const
4423 assert(is_sso_used());
4431 template <
typename CharT,
typename Traits>
4432 template <
typename T,
typename Enable>
4433 basic_string<CharT, Traits> &
4436 return erase(
static_cast<size_type
>(param));
4443 template <
typename CharT,
typename Traits>
4444 template <
typename T,
typename Enable>
4448 return erase(
static_cast<const_iterator
>(param));
4456 template <
typename CharT,
typename Traits>
4457 template <
typename T,
typename Enable>
4461 return insert(
static_cast<size_type
>(param), count, ch);
4469 template <
typename CharT,
typename Traits>
4470 template <
typename T,
typename Enable>
4474 return insert(
static_cast<const_iterator
>(param), count, ch);
4480 template <
class CharT,
class Traits>
4491 template <
class CharT,
class Traits>
4502 template <
class CharT,
class Traits>
4513 template <
class CharT,
class Traits>
4524 template <
class CharT,
class Traits>
4535 template <
class CharT,
class Traits>
4546 template <
class CharT,
class Traits>
4556 template <
class CharT,
class Traits>
4566 template <
class CharT,
class Traits>
4576 template <
class CharT,
class Traits>
4586 template <
class CharT,
class Traits>
4596 template <
class CharT,
class Traits>
4606 template <
class CharT,
class Traits>
4616 template <
class CharT,
class Traits>
4626 template <
class CharT,
class Traits>
4636 template <
class CharT,
class Traits>
4646 template <
class CharT,
class Traits>
4656 template <
class CharT,
class Traits>
4666 template <
class CharT,
class Traits>
4677 template <
class CharT,
class Traits>
4688 template <
class CharT,
class Traits>
4690 operator<(
const std::basic_string<CharT, Traits> &lhs,
4699 template <
class CharT,
class Traits>
4701 operator<=(
const std::basic_string<CharT, Traits> &lhs,
4710 template <
class CharT,
class Traits>
4721 template <
class CharT,
class Traits>
4732 template <
class CharT,
class Traits>
4735 const std::basic_string<CharT, Traits> &rhs)
4743 template <
class CharT,
class Traits>
4746 const std::basic_string<CharT, Traits> &rhs)
4754 template <
class CharT,
class Traits>
4757 const std::basic_string<CharT, Traits> &rhs)
4765 template <
class CharT,
class Traits>
4768 const std::basic_string<CharT, Traits> &rhs)
4776 template <
class CharT,
class Traits>
4779 const std::basic_string<CharT, Traits> &rhs)
4787 template <
class CharT,
class Traits>
4790 const std::basic_string<CharT, Traits> &rhs)
4798 template <
class CharT,
class Traits>
4802 return lhs.
swap(rhs);