38 #ifndef LIBPMEMOBJ_CPP_BASIC_STRING_HPP 39 #define LIBPMEMOBJ_CPP_BASIC_STRING_HPP 68 template <
typename CharT,
typename Traits = std::
char_traits<CharT>>
72 using traits_type = Traits;
73 using value_type = CharT;
74 using size_type = std::size_t;
75 using difference_type = std::ptrdiff_t;
76 using reference = value_type &;
77 using const_reference =
const value_type &;
78 using pointer = value_type *;
79 using const_pointer =
const value_type *;
81 using const_iterator = const_pointer;
82 using reverse_iterator = std::reverse_iterator<iterator>;
83 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
86 static constexpr size_type sso_capacity = (32 - 8) /
sizeof(CharT) - 1;
92 size_type count = npos);
93 basic_string(
const std::basic_string<CharT> &other, size_type pos,
94 size_type count = npos);
99 typename Enable =
typename std::enable_if<
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;
154 const_iterator
begin()
const noexcept;
155 const_iterator
cbegin()
const noexcept;
157 const_iterator
end()
const noexcept;
158 const_iterator
cend()
const noexcept;
159 reverse_iterator
rbegin();
160 const_reverse_iterator
rbegin()
const noexcept;
161 const_reverse_iterator
crbegin()
const noexcept;
162 reverse_iterator
rend();
163 const_reverse_iterator
rend()
const noexcept;
164 const_reverse_iterator
crend()
const noexcept;
167 bool empty()
const noexcept;
168 size_type
size()
const noexcept;
169 size_type
length()
const noexcept;
170 size_type
max_size()
const noexcept;
171 size_type
capacity()
const noexcept;
172 void resize(size_type count, CharT ch);
174 void reserve(size_type new_cap = 0);
183 template <
typename T,
184 typename Enable =
typename std::enable_if<
185 std::is_convertible<T, size_type>::value>::type>
187 template <
typename T,
188 typename Enable =
typename std::enable_if<
189 !std::is_convertible<T, size_type>::value>::type>
196 size_type count = npos);
199 template <
typename InputIt,
215 size_type index2, size_type count = npos);
218 template <
typename InputIt,
222 iterator insert(const_iterator pos, std::initializer_list<CharT> ilist);
223 template <
typename T,
224 typename Enable =
typename std::enable_if<
225 std::is_convertible<T, size_type>::value>::type>
227 template <
typename T,
228 typename Enable =
typename std::enable_if<
229 !std::is_convertible<T, size_type>::value>::type>
238 size_type count2 = npos);
239 template <
typename InputIt,
243 InputIt first2, InputIt last2);
245 const CharT *s, size_type count2);
249 size_type count2, CharT ch);
251 size_type count2, CharT ch);
256 std::initializer_list<CharT> ilist);
258 size_type
copy(CharT *s, size_type count, size_type index = 0)
const;
261 int compare(
const std::basic_string<CharT> &other)
const;
262 int compare(size_type pos, size_type count,
264 int compare(size_type pos, size_type count,
265 const std::basic_string<CharT> &other)
const;
267 size_type pos2, size_type count2 = npos)
const;
268 int compare(size_type pos1, size_type count1,
269 const std::basic_string<CharT> &other, size_type pos2,
270 size_type count2 = npos)
const;
271 int compare(
const CharT *s)
const;
272 int compare(size_type pos, size_type count,
const CharT *s)
const;
273 int compare(size_type pos, size_type count1,
const CharT *s,
274 size_type count2)
const;
277 static const size_type npos = static_cast<size_type>(-1);
321 static constexpr size_type _sso_mask = 1ULL
322 << (std::numeric_limits<size_type>::digits - 1);
325 bool is_sso_used()
const;
329 typename Enable =
typename std::enable_if<
331 size_type
get_size(InputIt first, InputIt last)
const;
332 size_type
get_size(size_type count, value_type ch)
const;
334 template <
typename... Args>
336 template <
typename... Args>
341 typename Enable =
typename std::enable_if<
348 typename Enable =
typename std::enable_if<
367 non_sso_data()
const;
380 template <
typename CharT,
typename Traits>
387 initialize(0U, value_type(
'\0'));
404 template <
typename CharT,
typename Traits>
411 initialize(count, ch);
431 template <
typename CharT,
typename Traits>
433 size_type pos, size_type count)
438 if (pos > other.
size())
439 throw std::out_of_range(
"Index out of range.");
441 if (count == npos || pos + count > other.
size())
442 count = other.
size() - pos;
444 auto first = static_cast<difference_type>(pos);
445 auto last = first + static_cast<difference_type>(count);
448 initialize(other.
cbegin() + first, other.
cbegin() + last);
469 template <
typename CharT,
typename Traits>
471 size_type pos, size_type count)
476 if (pos > other.size())
477 throw std::out_of_range(
"Index out of range.");
479 if (count == npos || pos + count > other.size())
480 count = other.size() - pos;
482 auto first = static_cast<difference_type>(pos);
483 auto last = first + static_cast<difference_type>(count);
486 initialize(other.cbegin() + first, other.cbegin() + last);
504 template <
typename CharT,
typename Traits>
511 initialize(s, s + count);
527 template <
typename CharT,
typename Traits>
533 auto length = traits_type::length(s);
536 initialize(s, s + length);
555 template <
typename CharT,
typename Traits>
556 template <
typename InputIt,
typename Enable>
559 auto len = std::distance(first, last);
565 allocate(static_cast<size_type>(len));
566 initialize(first, last);
583 template <
typename CharT,
typename Traits>
589 allocate(other.
size());
608 template <
typename CharT,
typename Traits>
628 template <
typename CharT,
typename Traits>
634 allocate(other.size());
635 initialize(std::move(other));
637 if (other.is_sso_used())
638 other.initialize(0U, value_type(
'\0'));
655 template <
typename CharT,
typename Traits>
661 allocate(ilist.size());
662 initialize(ilist.begin(), ilist.end());
670 template <
typename CharT,
typename Traits>
674 detail::destroy<non_sso_type>(non_sso_data());
686 template <
typename CharT,
typename Traits>
690 return assign(other);
703 template <
typename CharT,
typename Traits>
707 return assign(other);
719 template <
typename CharT,
typename Traits>
723 return assign(std::move(other));
734 template <
typename CharT,
typename Traits>
749 template <
typename CharT,
typename Traits>
753 return assign(1, ch);
765 template <
typename CharT,
typename Traits>
769 return assign(ilist);
782 template <
typename CharT,
typename Traits>
786 auto pop = get_pool();
802 template <
typename CharT,
typename Traits>
809 auto pop = get_pool();
812 pop, [&] { replace_content(other.
cbegin(), other.
cend()); });
827 template <
typename CharT,
typename Traits>
831 return assign(other.cbegin(), other.cend());
846 template <
typename CharT,
typename Traits>
851 if (pos > other.
size())
852 throw std::out_of_range(
"Index out of range.");
854 if (count == npos || pos + count > other.
size())
855 count = other.
size() - pos;
857 auto pop = get_pool();
858 auto first = static_cast<difference_type>(pos);
859 auto last = first + static_cast<difference_type>(count);
862 replace_content(other.
cbegin() + first, other.
cbegin() + last);
882 template <
typename CharT,
typename Traits>
885 size_type pos, size_type count)
887 if (pos > other.size())
888 throw std::out_of_range(
"Index out of range.");
890 if (count == npos || pos + count > other.size())
891 count = other.
size() - pos;
893 return assign(other.c_str() + pos, count);
906 template <
typename CharT,
typename Traits>
910 auto pop = get_pool();
925 template <
typename CharT,
typename Traits>
929 auto pop = get_pool();
931 auto length = traits_type::length(s);
949 template <
typename CharT,
typename Traits>
950 template <
typename InputIt,
typename Enable>
954 auto pop = get_pool();
970 template <
typename CharT,
typename Traits>
977 auto pop = get_pool();
980 replace_content(std::move(other));
982 if (other.is_sso_used())
983 other.initialize(0U, value_type(
'\0'));
998 template <
typename CharT,
typename Traits>
1002 return assign(ilist.begin(), ilist.end());
1010 template <
typename CharT,
typename Traits>
1023 template <
typename CharT,
typename Traits>
1024 typename basic_string<CharT, Traits>::const_iterator
1035 template <
typename CharT,
typename Traits>
1036 typename basic_string<CharT, Traits>::const_iterator
1039 return is_sso_used() ? const_iterator(&*sso_data().
cbegin())
1040 : const_iterator(&*non_sso_data().
cbegin());
1048 template <
typename CharT,
typename Traits>
1052 return begin() + static_cast<difference_type>(size());
1061 template <
typename CharT,
typename Traits>
1062 typename basic_string<CharT, Traits>::const_iterator
1065 return cbegin() + static_cast<difference_type>(size());
1074 template <
typename CharT,
typename Traits>
1075 typename basic_string<CharT, Traits>::const_iterator
1078 return cbegin() + static_cast<difference_type>(size());
1087 template <
typename CharT,
typename Traits>
1088 typename basic_string<CharT, Traits>::reverse_iterator
1091 return reverse_iterator(
end());
1100 template <
typename CharT,
typename Traits>
1101 typename basic_string<CharT, Traits>::const_reverse_iterator
1113 template <
typename CharT,
typename Traits>
1114 typename basic_string<CharT, Traits>::const_reverse_iterator
1117 return const_reverse_iterator(
cend());
1126 template <
typename CharT,
typename Traits>
1127 typename basic_string<CharT, Traits>::reverse_iterator
1130 return reverse_iterator(
begin());
1139 template <
typename CharT,
typename Traits>
1140 typename basic_string<CharT, Traits>::const_reverse_iterator
1152 template <
typename CharT,
typename Traits>
1153 typename basic_string<CharT, Traits>::const_reverse_iterator
1156 return const_reverse_iterator(
cbegin());
1172 template <
typename CharT,
typename Traits>
1173 typename basic_string<CharT, Traits>::reference
1177 throw std::out_of_range(
"string::at");
1179 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1192 template <
typename CharT,
typename Traits>
1193 typename basic_string<CharT, Traits>::const_reference
1212 template <
typename CharT,
typename Traits>
1213 typename basic_string<CharT, Traits>::const_reference
1217 throw std::out_of_range(
"string::const_at");
1219 return is_sso_used()
1220 ? static_cast<const sso_type &>(sso_data())[n]
1221 : static_cast<const non_sso_type &>(non_sso_data())[n];
1235 template <
typename CharT,
typename Traits>
1239 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1249 template <
typename CharT,
typename Traits>
1250 typename basic_string<CharT, Traits>::const_reference
1253 return is_sso_used() ? sso_data()[n] : non_sso_data()[n];
1265 template <
typename CharT,
typename Traits>
1277 template <
typename CharT,
typename Traits>
1292 template <
typename CharT,
typename Traits>
1296 return static_cast<const basic_string &>(*
this)[0];
1308 template <
typename CharT,
typename Traits>
1312 return (*
this)[size() - 1];
1320 template <
typename CharT,
typename Traits>
1335 template <
typename CharT,
typename Traits>
1339 return static_cast<const basic_string &>(*
this)[size() - 1];
1345 template <
typename CharT,
typename Traits>
1346 typename basic_string<CharT, Traits>::size_type
1350 return get_sso_size();
1351 else if (non_sso_data().size() == 0)
1354 return non_sso_data().size() - 1;
1363 template <
typename CharT,
typename Traits>
1367 return is_sso_used() ? sso_data().range(0, get_sso_size() + 1).begin()
1368 : non_sso_data().data();
1389 template <
typename CharT,
typename Traits>
1396 throw std::out_of_range(
"Index exceeds size.");
1398 count = (std::min)(count, sz - index);
1400 auto pop = get_pool();
1402 auto first =
begin() + static_cast<difference_type>(index);
1403 auto last = first + static_cast<difference_type>(count);
1405 if (is_sso_used()) {
1407 auto move_len = sz - index - count;
1408 auto new_size = sz - count;
1410 auto range = sso_data().range(index, move_len + 1);
1412 traits_type::move(range.begin(), &*last, move_len);
1414 set_sso_size(new_size);
1416 assert(range.end() - 1 ==
1417 &sso_data()._data[index + move_len]);
1418 *(range.end() - 1) = value_type(
'\0');
1421 non_sso_data().erase(first, last);
1443 template <
typename CharT,
typename Traits>
1447 return erase(pos, pos + 1);
1468 template <
typename CharT,
typename Traits>
1473 static_cast<size_type>(std::distance(
cbegin(), first));
1474 size_type len = static_cast<size_type>(std::distance(first, last));
1478 return begin() + static_cast<difference_type>(index);
1491 template <
typename CharT,
typename Traits>
1495 erase(size() - 1, 1);
1517 template <
typename CharT,
typename Traits>
1522 auto new_size = sz + count;
1524 if (new_size > max_size())
1525 throw std::length_error(
"Size exceeds max size.");
1527 if (is_sso_used()) {
1528 auto pop = get_pool();
1531 if (new_size > sso_capacity) {
1532 sso_to_large(new_size);
1534 non_sso_data().insert(
1535 non_sso_data().
cbegin() +
1536 static_cast<difference_type>(
1540 add_sso_to_tx(sz, count + 1);
1541 traits_type::assign(&sso_data()._data[sz],
1544 assert(new_size == sz + count);
1545 set_sso_size(new_size);
1546 sso_data()._data[new_size] = value_type(
'\0');
1550 non_sso_data().insert(non_sso_data().
cbegin() +
1551 static_cast<difference_type>(sz),
1576 template <
typename CharT,
typename Traits>
1580 return append(str.
data(), str.
size());
1608 template <
typename CharT,
typename Traits>
1613 auto sz = str.
size();
1616 throw std::out_of_range(
"Index out of range.");
1618 count = (std::min)(count, sz - pos);
1620 append(str.
data() + pos, count);
1644 template <
typename CharT,
typename Traits>
1648 return append(s, s + count);
1670 template <
typename CharT,
typename Traits>
1674 return append(s, traits_type::length(s));
1698 template <
typename CharT,
typename Traits>
1699 template <
typename InputIt,
typename Enable>
1704 auto count = static_cast<size_type>(std::distance(first, last));
1705 auto new_size = sz + count;
1707 if (new_size > max_size())
1708 throw std::length_error(
"Size exceeds max size.");
1710 if (is_sso_used()) {
1711 auto pop = get_pool();
1714 if (new_size > sso_capacity) {
1723 std::vector<value_type> str(first, last);
1725 sso_to_large(new_size);
1726 non_sso_data().insert(
1727 non_sso_data().
cbegin() +
1728 static_cast<difference_type>(
1730 str.begin(), str.end());
1732 add_sso_to_tx(sz, count + 1);
1733 std::copy(first, last, &sso_data()._data[sz]);
1735 assert(new_size == sz + count);
1736 set_sso_size(new_size);
1737 sso_data()._data[new_size] = value_type(
'\0');
1741 non_sso_data().insert(non_sso_data().
cbegin() +
1742 static_cast<difference_type>(sz),
1767 template <
typename CharT,
typename Traits>
1771 return append(ilist.begin(), ilist.end());
1790 template <
typename CharT,
typename Traits>
1794 append(static_cast<size_type>(1), ch);
1815 template <
typename CharT,
typename Traits>
1841 template <
typename CharT,
typename Traits>
1864 template <
typename CharT,
typename Traits>
1891 template <
typename CharT,
typename Traits>
1895 return append(ilist);
1919 template <
typename CharT,
typename Traits>
1924 throw std::out_of_range(
"Index out of range.");
1926 auto pos =
cbegin() + static_cast<difference_type>(index);
1928 insert(pos, count, ch);
1954 template <
typename CharT,
typename Traits>
1958 return insert(index, s, traits_type::length(s));
1982 template <
typename CharT,
typename Traits>
1988 throw std::out_of_range(
"Index out of range.");
1990 auto pos =
cbegin() + static_cast<difference_type>(index);
1992 insert(pos, s, s + count);
2017 template <
typename CharT,
typename Traits>
2021 return insert(index, str.
data(), str.
size());
2046 template <
typename CharT,
typename Traits>
2049 size_type index2, size_type count)
2051 auto sz = str.
size();
2053 if (index1 > size() || index2 > sz)
2054 throw std::out_of_range(
"Index out of range.");
2056 count = (std::min)(count, sz - index2);
2058 return insert(index1, str.
data() + index2, count);
2083 template <
typename CharT,
typename Traits>
2087 return insert(pos, 1, ch);
2114 template <
typename CharT,
typename Traits>
2121 if (sz + count > max_size())
2122 throw std::length_error(
"Count exceeds max size.");
2124 auto new_size = sz + count;
2126 auto pop = get_pool();
2128 auto index = static_cast<size_type>(std::distance(
cbegin(), pos));
2131 if (is_sso_used() && new_size <= sso_capacity) {
2132 auto len = sz - index;
2134 add_sso_to_tx(index, len + count + 1);
2136 traits_type::move(&sso_data()._data[index + count],
2137 &sso_data()._data[index], len);
2138 traits_type::assign(&sso_data()._data[index], count,
2141 assert(new_size == index + len + count);
2142 set_sso_size(new_size);
2143 sso_data()._data[new_size] = value_type(
'\0');
2146 sso_to_large(new_size);
2148 non_sso_data().insert(
2149 non_sso_data().
begin() +
2150 static_cast<difference_type>(index),
2155 return iterator(&data()[static_cast<difference_type>(index)]);
2182 template <
typename CharT,
typename Traits>
2183 template <
typename InputIt,
typename Enable>
2190 auto count = static_cast<size_type>(std::distance(first, last));
2192 if (sz + count > max_size())
2193 throw std::length_error(
"Count exceeds max size.");
2195 auto pop = get_pool();
2197 auto new_size = sz + count;
2199 auto index = static_cast<size_type>(std::distance(
cbegin(), pos));
2202 if (is_sso_used() && new_size <= sso_capacity) {
2203 auto len = sz - index;
2205 add_sso_to_tx(index, len + count + 1);
2207 traits_type::move(&sso_data()._data[index + count],
2208 &sso_data()._data[index], len);
2209 std::copy(first, last, &sso_data()._data[index]);
2211 assert(new_size == index + len + count);
2212 set_sso_size(new_size);
2213 sso_data()._data[new_size] = value_type(
'\0');
2215 if (is_sso_used()) {
2224 std::vector<value_type> str(first, last);
2226 sso_to_large(new_size);
2227 non_sso_data().insert(
2228 non_sso_data().
begin() +
2229 static_cast<difference_type>(
2231 str.begin(), str.end());
2233 non_sso_data().insert(
2234 non_sso_data().
begin() +
2235 static_cast<difference_type>(
2242 return iterator(&data()[static_cast<difference_type>(index)]);
2268 template <
typename CharT,
typename Traits>
2271 std::initializer_list<CharT> ilist)
2273 return insert(pos, ilist.begin(), ilist.end());
2298 template <
typename CharT,
typename Traits>
2303 return replace(index, count, str.
data(), str.
size());
2326 template <
typename CharT,
typename Traits>
2331 return replace(first, last, str.
data(), str.
data() + str.
size());
2360 template <
typename CharT,
typename Traits>
2366 auto sz = str.
size();
2369 throw std::out_of_range(
"Index out of range.");
2371 count2 = (std::min)(count2, sz - index2);
2373 return replace(index, count, str.
data() + index2, count2);
2401 template <
typename CharT,
typename Traits>
2402 template <
typename InputIt,
typename Enable>
2405 InputIt first2, InputIt last2)
2408 auto index = static_cast<size_type>(std::distance(
cbegin(), first));
2409 auto count = static_cast<size_type>(std::distance(first, last));
2410 auto count2 = static_cast<size_type>(std::distance(first2, last2));
2412 count = (std::min)(count, sz - index);
2414 if (sz - count + count2 > max_size())
2415 throw std::length_error(
"Count exceeds max size.");
2417 auto new_size = sz - count + count2;
2419 auto pop = get_pool();
2422 if (is_sso_used() && new_size <= sso_capacity) {
2423 add_sso_to_tx(index, new_size - index + 1);
2425 assert(count2 < new_size + 1);
2426 traits_type::move(&sso_data()._data[index + count2],
2427 &sso_data()._data[index + count],
2428 sz - index - count);
2429 std::copy(first2, last2, &sso_data()._data[index]);
2431 set_sso_size(new_size);
2432 sso_data()._data[new_size] = value_type(
'\0');
2442 std::vector<value_type> str(first2, last2);
2444 if (is_sso_used()) {
2445 sso_to_large(new_size);
2449 begin() + static_cast<difference_type>(index);
2450 auto end = beg + static_cast<difference_type>(count);
2451 non_sso_data().erase(beg,
end);
2452 non_sso_data().insert(beg, str.begin(), str.end());
2455 if (!is_sso_used() && new_size <= sso_capacity)
2484 template <
typename CharT,
typename Traits>
2487 const CharT *s, size_type count2)
2489 return replace(first, last, s, s + count2);
2515 template <
typename CharT,
typename Traits>
2518 const CharT *s, size_type count2)
2521 throw std::out_of_range(
"Index out of range.");
2523 auto first =
cbegin() + static_cast<difference_type>(index);
2524 auto last = first + static_cast<difference_type>(count);
2526 return replace(first, last, s, s + count2);
2552 template <
typename CharT,
typename Traits>
2557 return replace(index, count, s, traits_type::length(s));
2583 template <
typename CharT,
typename Traits>
2586 size_type count2, CharT ch)
2589 throw std::out_of_range(
"Index out of range.");
2591 auto first =
cbegin() + static_cast<difference_type>(index);
2592 auto last = first + static_cast<difference_type>(count);
2594 return replace(first, last, count2, ch);
2619 template <
typename CharT,
typename Traits>
2622 size_type count2, CharT ch)
2625 auto index = static_cast<size_type>(std::distance(
cbegin(), first));
2626 auto count = static_cast<size_type>(std::distance(first, last));
2628 count = (std::min)(count, sz - index);
2630 if (sz - count + count2 > max_size())
2631 throw std::length_error(
"Count exceeds max size.");
2633 auto new_size = sz - count + count2;
2635 auto pop = get_pool();
2638 if (is_sso_used() && new_size <= sso_capacity) {
2639 add_sso_to_tx(index, new_size - index + 1);
2641 assert(count2 < new_size + 1);
2642 traits_type::move(&sso_data()._data[index + count2],
2643 &sso_data()._data[index + count],
2644 sz - index - count);
2645 traits_type::assign(&sso_data()._data[index], count2,
2648 set_sso_size(new_size);
2649 sso_data()._data[new_size] = value_type(
'\0');
2651 if (is_sso_used()) {
2652 sso_to_large(new_size);
2656 begin() + static_cast<difference_type>(index);
2657 auto end = beg + static_cast<difference_type>(count);
2658 non_sso_data().erase(beg,
end);
2659 non_sso_data().insert(beg, count2, ch);
2662 if (!is_sso_used() && new_size <= sso_capacity)
2690 template <
typename CharT,
typename Traits>
2695 return replace(first, last, s, traits_type::length(s));
2720 template <
typename CharT,
typename Traits>
2723 std::initializer_list<CharT> ilist)
2725 return replace(first, last, ilist.begin(), ilist.end());
2741 template <
typename CharT,
typename Traits>
2742 typename basic_string<CharT, Traits>::size_type
2744 size_type index)
const 2749 throw std::out_of_range(
"Index out of range.");
2751 auto len = (std::min)(count, sz - index);
2753 traits_type::copy(s, data() + index, len);
2775 template <
typename CharT,
typename Traits>
2778 const CharT *s, size_type count2)
const 2781 throw std::out_of_range(
"Index out of range.");
2783 if (count1 > size() - pos)
2784 count1 = size() - pos;
2786 auto ret = traits_type::compare(cdata() + pos, s,
2787 std::min<size_type>(count1, count2));
2792 if (count1 < count2)
2794 else if (count1 == count2)
2808 template <
typename CharT,
typename Traits>
2812 return compare(0, size(), other.
cdata(), other.
size());
2823 template <
typename CharT,
typename Traits>
2826 const std::basic_string<CharT> &other)
const 2828 return compare(0, size(), other.data(), other.size());
2844 template <
typename CharT,
typename Traits>
2849 return compare(pos, count, other.
cdata(), other.
size());
2866 template <
typename CharT,
typename Traits>
2869 size_type pos, size_type count,
2870 const std::basic_string<CharT> &other)
const 2872 return compare(pos, count, other.data(), other.size());
2893 template <
typename CharT,
typename Traits>
2897 size_type count2)
const 2899 if (pos2 > other.
size())
2900 throw std::out_of_range(
"Index out of range.");
2902 if (count2 > other.
size() - pos2)
2903 count2 = other.
size() - pos2;
2905 return compare(pos1, count1, other.
cdata() + pos2, count2);
2926 template <
typename CharT,
typename Traits>
2929 const std::basic_string<CharT> &other,
2930 size_type pos2, size_type count2)
const 2932 if (pos2 > other.size())
2933 throw std::out_of_range(
"Index out of range.");
2935 if (count2 > other.size() - pos2)
2936 count2 = other.size() - pos2;
2938 return compare(pos1, count1, other.data() + pos2, count2);
2949 template <
typename CharT,
typename Traits>
2953 return compare(0, size(), s, traits_type::length(s));
2969 template <
typename CharT,
typename Traits>
2972 const CharT *s)
const 2974 return compare(pos, count, s, traits_type::length(s));
2980 template <
typename CharT,
typename Traits>
2984 return is_sso_used() ? sso_data().cdata() : non_sso_data().cdata();
2990 template <
typename CharT,
typename Traits>
3000 template <
typename CharT,
typename Traits>
3010 template <
typename CharT,
typename Traits>
3011 typename basic_string<CharT, Traits>::size_type
3020 template <
typename CharT,
typename Traits>
3021 typename basic_string<CharT, Traits>::size_type
3024 return PMEMOBJ_MAX_ALLOC_SIZE /
sizeof(CharT) - 1;
3031 template <
typename CharT,
typename Traits>
3032 typename basic_string<CharT, Traits>::size_type
3035 return is_sso_used() ? sso_capacity : non_sso_data().capacity() - 1;
3057 template <
typename CharT,
typename Traits>
3061 if (count > max_size())
3062 throw std::length_error(
"Count exceeds max size.");
3066 auto pop = get_pool();
3070 append(count - sz, ch);
3071 }
else if (is_sso_used()) {
3072 set_sso_size(count);
3073 sso_data()[count] = value_type(
'\0');
3075 non_sso_data().resize(count + 1, ch);
3076 non_sso_data().back() = value_type(
'\0');
3099 template <
typename CharT,
typename Traits>
3103 resize(count, CharT());
3126 template <
typename CharT,
typename Traits>
3130 if (new_cap > max_size())
3131 throw std::length_error(
"New capacity exceeds max size.");
3133 if (new_cap < capacity() || new_cap <= sso_capacity)
3136 if (is_sso_used()) {
3137 auto pop = get_pool();
3141 non_sso_data().reserve(new_cap + 1);
3158 template <
typename CharT,
typename Traits>
3165 if (size() <= sso_capacity) {
3166 auto pop = get_pool();
3170 non_sso_data().shrink_to_fit();
3183 template <
typename CharT,
typename Traits>
3193 template <
typename CharT,
typename Traits>
3200 template <
typename CharT,
typename Traits>
3204 return (sso._size & _sso_mask) != 0;
3207 template <
typename CharT,
typename Traits>
3209 basic_string<CharT, Traits>::destroy_data()
3211 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3213 if (is_sso_used()) {
3214 add_sso_to_tx(0, get_sso_size() + 1);
3217 non_sso_data().free_data();
3218 detail::destroy<non_sso_type>(non_sso_data());
3228 template <
typename CharT,
typename Traits>
3229 template <
typename InputIt,
typename Enable>
3230 typename basic_string<CharT, Traits>::size_type
3233 return static_cast<size_type>(std::distance(first, last));
3242 template <
typename CharT,
typename Traits>
3243 typename basic_string<CharT, Traits>::size_type
3255 template <
typename CharT,
typename Traits>
3256 typename basic_string<CharT, Traits>::size_type
3259 return other.
size();
3269 template <
typename CharT,
typename Traits>
3270 template <
typename... Args>
3271 typename basic_string<CharT, Traits>::pointer
3274 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3276 auto new_size = get_size(std::forward<Args>(args)...);
3279 if (!is_sso_used() && new_size <= capacity())
3280 return assign_large_data(std::forward<Args>(args)...);
3285 return initialize(std::forward<Args>(args)...);
3299 template <
typename CharT,
typename Traits>
3300 template <
typename... Args>
3301 typename basic_string<CharT, Traits>::pointer
3304 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3306 auto size = get_size(std::forward<Args>(args)...);
3308 if (is_sso_used()) {
3309 auto ptr = assign_sso_data(std::forward<Args>(args)...);
3314 return assign_large_data(std::forward<Args>(args)...);
3327 template <
typename CharT,
typename Traits>
3331 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3333 if (capacity <= sso_capacity) {
3343 if (!is_sso_used()) {
3344 detail::conditional_add_to_tx(&non_sso_data(), 1,
3345 POBJ_XADD_NO_SNAPSHOT);
3346 detail::create<non_sso_type>(&non_sso_data());
3347 non_sso_data().reserve(capacity + 1);
3354 template <
typename CharT,
typename Traits>
3355 template <
typename InputIt,
typename Enable>
3356 typename basic_string<CharT, Traits>::pointer
3359 auto size = static_cast<size_type>(std::distance(first, last));
3361 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3362 assert(size <= sso_capacity);
3364 add_sso_to_tx(0, size + 1);
3365 std::copy(first, last, &sso_data()._data[0]);
3367 sso_data()._data[size] = value_type(
'\0');
3369 return &sso_data()[0];
3375 template <
typename CharT,
typename Traits>
3376 typename basic_string<CharT, Traits>::pointer
3379 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3380 assert(count <= sso_capacity);
3382 add_sso_to_tx(0, count + 1);
3383 traits_type::assign(&sso_data()._data[0], count, ch);
3385 sso_data()._data[count] = value_type(
'\0');
3387 return &sso_data()[0];
3393 template <
typename CharT,
typename Traits>
3394 typename basic_string<CharT, Traits>::pointer
3397 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3399 return assign_sso_data(other.cbegin(), other.cend());
3406 template <
typename CharT,
typename Traits>
3407 template <
typename InputIt,
typename Enable>
3408 typename basic_string<CharT, Traits>::pointer
3411 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3413 auto size = static_cast<size_type>(std::distance(first, last));
3415 non_sso_data().reserve(size + 1);
3416 non_sso_data().assign(first, last);
3417 non_sso_data().push_back(value_type(
'\0'));
3419 return non_sso_data().data();
3426 template <
typename CharT,
typename Traits>
3427 typename basic_string<CharT, Traits>::pointer
3430 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3432 non_sso_data().reserve(count + 1);
3433 non_sso_data().assign(count, ch);
3434 non_sso_data().push_back(value_type(
'\0'));
3436 return non_sso_data().data();
3443 template <
typename CharT,
typename Traits>
3444 typename basic_string<CharT, Traits>::pointer
3447 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3449 if (other.is_sso_used())
3450 return assign_large_data(other.cbegin(), other.cend());
3452 non_sso_data() = std::move(other.non_sso_data());
3454 return non_sso_data().data();
3460 template <
typename CharT,
typename Traits>
3464 auto pop = pmemobj_pool_by_ptr(
this);
3465 assert(pop !=
nullptr);
3473 template <
typename CharT,
typename Traits>
3477 if (pmemobj_pool_by_ptr(
this) ==
nullptr)
3484 template <
typename CharT,
typename Traits>
3488 if (pmemobj_tx_stage() != TX_STAGE_WORK)
3490 "Call made out of transaction scope.");
3497 template <
typename CharT,
typename Traits>
3502 check_tx_stage_work();
3508 template <
typename CharT,
typename Traits>
3511 size_type num)
const 3513 assert(idx_first + num <= sso_capacity + 1);
3514 assert(is_sso_used());
3516 auto initialized_num = get_sso_size() + 1 - idx_first;
3519 detail::conditional_add_to_tx(&sso_data()._data[0] + idx_first,
3520 (std::min)(initialized_num, num));
3522 if (num > initialized_num) {
3524 detail::conditional_add_to_tx(
3525 &sso_data()._data[0] + get_sso_size() + 1,
3526 num - initialized_num, POBJ_XADD_NO_SNAPSHOT);
3533 template <
typename CharT,
typename Traits>
3534 typename basic_string<CharT, Traits>::size_type
3537 return sso._size & ~_sso_mask;
3543 template <
typename CharT,
typename Traits>
3549 sso._size |= (size_type)(_sso_mask);
3555 template <
typename CharT,
typename Traits>
3559 sso._size &= ~_sso_mask;
3565 template <
typename CharT,
typename Traits>
3569 sso._size = new_size | _sso_mask;
3583 template <
typename CharT,
typename Traits>
3587 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3588 assert(new_capacity > sso_capacity);
3589 assert(is_sso_used());
3595 tmp[sz] = value_type(
'\0');
3598 allocate(new_capacity);
3600 auto begin = tmp.cbegin();
3605 assert(!is_sso_used());
3617 template <
typename CharT,
typename Traits>
3621 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
3622 assert(!is_sso_used());
3626 assert(sz <= sso_capacity);
3630 tmp[sz] = value_type(
'\0');
3635 auto begin = tmp.cbegin();
3640 assert(is_sso_used());
3643 template <
typename CharT,
typename Traits>
3647 assert(!is_sso_used());
3648 return non_sso._data;
3651 template <
typename CharT,
typename Traits>
3652 typename basic_string<CharT, Traits>::sso_type &
3653 basic_string<CharT, Traits>::sso_data()
3655 assert(is_sso_used());
3659 template <
typename CharT,
typename Traits>
3660 const typename basic_string<CharT, Traits>::non_sso_type &
3661 basic_string<CharT, Traits>::non_sso_data()
const 3663 assert(!is_sso_used());
3664 return non_sso._data;
3667 template <
typename CharT,
typename Traits>
3668 const typename basic_string<CharT, Traits>::sso_type &
3669 basic_string<CharT, Traits>::sso_data()
const 3671 assert(is_sso_used());
3679 template <
typename CharT,
typename Traits>
3680 template <
typename T,
typename Enable>
3681 basic_string<CharT, Traits> &
3684 return erase(static_cast<size_type>(param));
3691 template <
typename CharT,
typename Traits>
3692 template <
typename T,
typename Enable>
3696 return erase(static_cast<const_iterator>(param));
3704 template <
typename CharT,
typename Traits>
3705 template <
typename T,
typename Enable>
3709 return insert(static_cast<size_type>(param), count, ch);
3717 template <
typename CharT,
typename Traits>
3718 template <
typename T,
typename Enable>
3722 return insert(static_cast<const_iterator>(param), count, ch);
3728 template <
class CharT,
class Traits>
3739 template <
class CharT,
class Traits>
3750 template <
class CharT,
class Traits>
3761 template <
class CharT,
class Traits>
3772 template <
class CharT,
class Traits>
3783 template <
class CharT,
class Traits>
3794 template <
class CharT,
class Traits>
3804 template <
class CharT,
class Traits>
3814 template <
class CharT,
class Traits>
3824 template <
class CharT,
class Traits>
3834 template <
class CharT,
class Traits>
3844 template <
class CharT,
class Traits>
3854 template <
class CharT,
class Traits>
3864 template <
class CharT,
class Traits>
3874 template <
class CharT,
class Traits>
3884 template <
class CharT,
class Traits>
3894 template <
class CharT,
class Traits>
3904 template <
class CharT,
class Traits>
3914 template <
class CharT,
class Traits>
3925 template <
class CharT,
class Traits>
3936 template <
class CharT,
class Traits>
3947 template <
class CharT,
class Traits>
3958 template <
class CharT,
class Traits>
3969 template <
class CharT,
class Traits>
3980 template <
class CharT,
class Traits>
3983 const std::basic_string<CharT, Traits> &rhs)
3991 template <
class CharT,
class Traits>
3994 const std::basic_string<CharT, Traits> &rhs)
4002 template <
class CharT,
class Traits>
4005 const std::basic_string<CharT, Traits> &rhs)
4013 template <
class CharT,
class Traits>
4016 const std::basic_string<CharT, Traits> &rhs)
4024 template <
class CharT,
class Traits>
4027 const std::basic_string<CharT, Traits> &rhs)
4035 template <
class CharT,
class Traits>
4038 const std::basic_string<CharT, Traits> &rhs)
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:402
void check_tx_stage_work() const
Definition: basic_string.hpp:3486
int compare(const basic_string &other) const
Compares this string to other.
Definition: basic_string.hpp:2810
void resize(size_type count, CharT ch)
Resize the string to count characters transactionally.
Definition: basic_string.hpp:3059
iterator end()
Return an iterator to past the end.
Definition: basic_string.hpp:1050
pointer initialize(Args &&... args)
Generic function which initializes memory based on provided parameters - forwards parameters to initi...
Definition: basic_string.hpp:3302
const CharT * cdata() const noexcept
Definition: basic_string.hpp:2982
void allocate(size_type capacity)
Allocate storage for container of capacity bytes.
Definition: basic_string.hpp:3329
size_type max_size() const noexcept
Definition: basic_string.hpp:3022
size_type get_size(InputIt first, InputIt last) const
Overload of generic get_size method used to calculate size based on provided parameters.
Definition: basic_string.hpp:3231
pmem::obj::array< T, N >::const_reverse_iterator crend(const pmem::obj::array< T, N > &a)
Non-member crend.
Definition: array.hpp:823
reference at(size_type n)
Access element at specific index with bounds checking and snapshot it if there is an active transacti...
Definition: basic_string.hpp:1174
The non-template pool base class.
Definition: pool.hpp:67
size_type capacity() const noexcept
Definition: basic_string.hpp:3033
void disable_sso()
Disable sso string.
Definition: basic_string.hpp:3557
void clear()
Remove all characters from the string transactionally.
Definition: basic_string.hpp:3185
void large_to_sso()
Resize large string to sso string of size() size.
Definition: basic_string.hpp:3619
basic_string & assign(size_type count, CharT ch)
Replace the contents with count copies of character ch transactionally.
Definition: basic_string.hpp:784
Custom pool error class.
Definition: pexceptions.hpp:72
void shrink_to_fit()
Remove unused capacity transactionally.
Definition: basic_string.hpp:3160
basic_string & replace(size_type index, size_type count, const basic_string &str)
Replace range [index, index + count) with the content of str string transactionally.
Definition: basic_string.hpp:2300
const CharT * c_str() const noexcept
Definition: basic_string.hpp:3002
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less than operator.
Definition: array.hpp:752
pointer assign_sso_data(InputIt first, InputIt last)
Initialize sso data.
Definition: basic_string.hpp:3357
T * data()
Returns raw pointer to the underlying data and adds entire array to a transaction.
Definition: array.hpp:273
C++ pmemobj transactions.
Convenience extensions for the resides on pmem property template.
Functions for destroying arrays.
reverse_iterator rend()
Return a reverse iterator to the end.
Definition: basic_string.hpp:1128
basic_string & append(size_type count, CharT ch)
Append count copies of character ch to the string transactionally.
Definition: basic_string.hpp:1519
Commonly used functionality.
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less or equal operator.
Definition: array.hpp:783
void reserve(size_type new_cap=0)
Increase the capacity of the string to new_cap transactionally.
Definition: basic_string.hpp:3128
void enable_sso()
Enable sso string.
Definition: basic_string.hpp:3545
Iterators for contiguous persistent containers.
pmem::obj::array< T, N >::const_reverse_iterator crbegin(const pmem::obj::array< T, N > &a)
Non-member crbegin.
Definition: array.hpp:813
const_reverse_iterator crbegin() const noexcept
Return a const reverse iterator to the beginning.
Definition: basic_string.hpp:1115
void check_pmem_tx() const
Definition: basic_string.hpp:3499
basic_string & erase(size_type index=0, size_type count=npos)
Remove characters from string starting at index transactionally.
Definition: basic_string.hpp:1391
reverse_iterator rbegin()
Return a reverse iterator to the beginning.
Definition: basic_string.hpp:1089
Array container with std::array compatible interface.
reference operator[](size_type n)
Access element at specific index and snapshot it if there is an active transaction.
Definition: basic_string.hpp:1237
void sso_to_large(size_t new_capacity)
Resize sso string to large string.
Definition: basic_string.hpp:3585
void check_pmem() const
Definition: basic_string.hpp:3475
pmem::obj::array< T, N >::iterator end(pmem::obj::array< T, N > &a)
Non-member end.
Definition: array.hpp:853
size_type length() const noexcept
Definition: basic_string.hpp:3012
Default non-const iterator which adds element to a transaction on every access.
Definition: contiguous_iterator.hpp:359
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:833
const_iterator cbegin() const noexcept
Return const iterator to the beginning.
Definition: basic_string.hpp:1037
void add_sso_to_tx(size_type first, size_type num) const
Snapshot sso data.
Definition: basic_string.hpp:3510
pointer replace_content(Args &&... args)
Generic function which replace_content current content based on provided parameters.
Definition: basic_string.hpp:3272
void pop_back()
Remove the last character from the string transactionally.
Definition: basic_string.hpp:1493
basic_string()
Default constructor.
Definition: basic_string.hpp:381
basic_string & operator=(const basic_string &other)
Copy assignment operator.
Definition: basic_string.hpp:688
bool empty() const noexcept
Definition: basic_string.hpp:3195
const CharT & cback() const
Access last element.
Definition: basic_string.hpp:1337
CharT & front()
Access first element and snapshot it if there is an active transaction.
Definition: basic_string.hpp:1267
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:763
basic_string & insert(size_type index, size_type count, CharT ch)
Insert count copies of ch character at index transactionally.
Definition: basic_string.hpp:1921
iterator begin()
Return an iterator to the beginning.
Definition: basic_string.hpp:1012
Vector container with std::vector compatible interface.
Persistent smart pointer.
void set_sso_size(size_type new_size)
Set size for sso.
Definition: basic_string.hpp:3567
Iterface to access sequence of objects.
void push_back(CharT ch)
Append character ch at the end of the string transactionally.
Definition: basic_string.hpp:1792
pmem::obj::array< T, N >::const_iterator cbegin(const pmem::obj::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:793
~basic_string()
Destructor.
Definition: basic_string.hpp:671
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:518
size_type get_sso_size() const
Return size of sso string.
Definition: basic_string.hpp:3535
Custom transaction error class.
Definition: pexceptions.hpp:185
A persistent version of concurrent hash map implementation Ref: https://arxiv.org/abs/1509....
Definition: allocation_flag.hpp:43
size_type size() const noexcept
Definition: basic_string.hpp:1347
pmem::obj::string - persistent container with std::basic_string compatible interface.
Definition: basic_string.hpp:69
CharT & back()
Access last element and snapshot it if there is an active transaction.
Definition: basic_string.hpp:1310
const CharT & cfront() const
Access first element.
Definition: basic_string.hpp:1294
pool_base get_pool() const
Return pool_base instance and assert that object is on pmem.
Definition: basic_string.hpp:3462
const_iterator cend() const noexcept
Return const iterator to past the end.
Definition: basic_string.hpp:1076
CharT * data()
Definition: basic_string.hpp:1365
basic_string & operator+=(const basic_string &str)
Append string str transactionally.
Definition: basic_string.hpp:1817
pointer assign_large_data(InputIt first, InputIt last)
Initialize non_sso.data - call constructor of non_sso.data.
Definition: basic_string.hpp:3409
pmem::obj::array< T, N >::const_iterator cend(const pmem::obj::array< T, N > &a)
Non-member cend.
Definition: array.hpp:803
const_reference const_at(size_type n) const
Access element at specific index with bounds checking.
Definition: basic_string.hpp:1214
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:773
static void run(pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:403
const_reverse_iterator crend() const noexcept
Return a const reverse iterator to the end.
Definition: basic_string.hpp:1154
size_type copy(CharT *s, size_type count, size_type index=0) const
Copy [index, index + count) substring of *this to C-style string.
Definition: basic_string.hpp:2743