1#ifndef NEFORCE_CORE_STRING_BASIC_STRING_HPP__
2#define NEFORCE_CORE_STRING_BASIC_STRING_HPP__
16NEFORCE_BEGIN_NAMESPACE__
32template <
bool IsConst,
typename String>
33struct basic_string_iterator :
iiterator<basic_string_iterator<IsConst, String>> {
37 using size_type =
typename container_type::size_type;
41 typename container_type::reference>;
43 typename container_type::pointer>;
50 NEFORCE_CONSTEXPR20 basic_string_iterator() noexcept = default;
51 NEFORCE_CONSTEXPR20 ~basic_string_iterator() = default;
53 NEFORCE_CONSTEXPR20 basic_string_iterator(const basic_string_iterator&) noexcept = default;
54 NEFORCE_CONSTEXPR20 basic_string_iterator& operator=(const basic_string_iterator&) noexcept = default;
55 NEFORCE_CONSTEXPR20 basic_string_iterator(basic_string_iterator&&) noexcept = default;
56 NEFORCE_CONSTEXPR20 basic_string_iterator& operator=(basic_string_iterator&&) noexcept = default;
74 "Attempting to dereference out of boundary");
103 "Attempting to advance out of boundary");
132 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal(
const basic_string_iterator& rhs)
const noexcept {
134 return current_ == rhs.current_;
142 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool less_than(
const basic_string_iterator& rhs)
const noexcept {
144 return current_ < rhs.current_;
151 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
pointer base() const noexcept {
return current_; }
171template <
typename CharT,
typename Traits =
char_traits<CharT>,
typename Alloc = allocator<CharT>>
177 "basic string only contains non-array trivial standard-layout types.");
200#ifdef NEFORCE_USING_SSO
202 static constexpr size_type sso_buffer_bytes = MEMORY_ALIGN_THRESHHOLD;
204 static constexpr size_type sso_buffer_size = (sso_buffer_bytes +
sizeof(CharT) - 1) /
sizeof(CharT);
206 static constexpr size_type sso_capacity = sso_buffer_size - 1;
214 struct long_pointer {
218 CharT short_[sso_buffer_size];
224 compressed_pair<allocator_type, size_type> capacity_pair_{default_construct_tag{}, 0};
228#ifdef NEFORCE_USING_SSO
233 NEFORCE_CONSTEXPR20
bool is_long() const noexcept {
return (size_pair_.value & long_flag) != 0; }
239 NEFORCE_CONSTEXPR20
void set_size(
size_type new_size)
noexcept {
240 size_pair_.value = (is_long() ? (new_size | long_flag) : new_size);
247 NEFORCE_CONSTEXPR20
void switch_to_long(
size_type new_cap) {
249 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
251 traits_type::copy(new_ptr, storage_.short_, old_size);
252 traits_type::assign(new_ptr + old_size, 1,
value_type());
254 storage_.long_.ptr = new_ptr;
255 storage_.long_.cap = new_cap;
256 size_pair_.value = old_size | long_flag;
262 NEFORCE_CONSTEXPR20
void destroy_long() noexcept {
263 if (storage_.long_.ptr) {
264 size_pair_.get_base().deallocate(storage_.long_.ptr, storage_.long_.cap);
265 storage_.long_.ptr =
nullptr;
266 storage_.long_.cap = 0;
277 template <
typename Iterator>
278 NEFORCE_CONSTEXPR20
void construct_from_iter(Iterator first, Iterator last) {
281#ifdef NEFORCE_USING_SSO
282 if (n < sso_capacity) {
283 pointer dest = storage_.short_;
287 traits_type::assign(dest + n, 1,
value_type());
288 size_pair_.value = n;
290 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
291 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
296 traits_type::assign(new_ptr + n, 1,
value_type());
298 storage_.long_.ptr = new_ptr;
299 storage_.long_.cap = init_cap;
300 size_pair_.value = n | long_flag;
303 const size_type init_size = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
306 temp_data = capacity_pair_.
get_base().allocate(init_size);
308 capacity_pair_.
value = init_size;
313 capacity_pair_.
value = init_size;
314 traits_type::assign(data_ + size_, 1,
value_type());
317 _NEFORCE
destroy(temp_data, temp_data + n);
318 capacity_pair_.
get_base().deallocate(temp_data, capacity_pair_.
value);
333#ifdef NEFORCE_USING_SSO
334 if (n < sso_capacity) {
335 traits_type::copy(storage_.short_, str + position, n);
336 traits_type::assign(storage_.short_ + n, 1,
value_type());
337 size_pair_.value = n;
339 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
340 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
341 traits_type::copy(new_ptr, str + position, n);
342 traits_type::assign(new_ptr + n, 1,
value_type());
344 storage_.long_.ptr = new_ptr;
345 storage_.long_.cap = init_cap;
346 size_pair_.value = n | long_flag;
352 temp_capacity = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
353 temp_data = capacity_pair_.
get_base().allocate(temp_capacity);
354 traits_type::copy(temp_data, str + position, n);
358 capacity_pair_.
value = temp_capacity;
359 traits_type::assign(data_ + size_, 1,
value_type());
362 capacity_pair_.
get_base().deallocate(temp_data, capacity_pair_.
value);
366 capacity_pair_.
value = 0;
375 NEFORCE_CONSTEXPR20
void destroy_buffer() noexcept {
376#ifdef NEFORCE_USING_SSO
380 size_pair_.value = 0;
381 traits_type::assign(storage_.short_, 1,
value_type());
384 if (capacity_pair_.
value > 0) {
385 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
389 capacity_pair_.
value = 0;
404#ifdef NEFORCE_USING_SSO
407 const size_type actual_n1 = _NEFORCE
min(n1, old_size - offset);
408 if (actual_n1 == 0 && n2 == 0) {
412 const size_type new_size = old_size - actual_n1 + n2;
414 if (!is_long() && new_size < sso_capacity) {
415 pointer p = storage_.short_ + offset;
417 traits_type::move(p + n2, p + actual_n1, old_size - offset - actual_n1);
419 traits_type::assign(p, n2, value);
420 size_pair_.value = new_size;
421 traits_type::assign(storage_.short_ + new_size, 1,
value_type());
425 size_type new_cap = is_long() ? storage_.long_.cap : sso_buffer_size;
426 if (new_cap < new_size + 1) {
427 new_cap = _NEFORCE
max(new_size + 1, new_cap + (new_cap >> 1));
430 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
433 dest = traits_type::copy(dest,
data(), offset) + offset;
434 dest = traits_type::assign(dest, n2, value) + n2;
435 traits_type::copy(dest,
data() + offset + actual_n1, old_size - offset - actual_n1);
440 storage_.long_.ptr = new_ptr;
441 storage_.long_.cap = new_cap;
442 size_pair_.value = new_size | long_flag;
443 traits_type::assign(storage_.long_.ptr + new_size, 1,
value_type());
454 if (size_ > capacity_pair_.
value - diff) {
459 traits_type::move(raw_ptr + n2, raw_ptr + n1,
end() - (first + n1));
460 traits_type::assign(raw_ptr, n2, value);
464 traits_type::move(raw_ptr + n2, raw_ptr + n1,
end() - (first + n1));
465 traits_type::assign(raw_ptr, n2, value);
469 traits_type::assign(data_ + size_, 1,
value_type());
483 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
490#ifdef NEFORCE_USING_SSO
493 const size_type new_size = old_size - len1 + len2;
495 if (!is_long() && new_size < sso_capacity) {
496 pointer p = storage_.short_ + offset;
498 traits_type::move(p + len2, p + len1, old_size - offset - len1);
503 size_pair_.value = new_size;
504 traits_type::assign(storage_.short_ + new_size, 1,
value_type());
508 size_type new_cap = is_long() ? storage_.long_.cap : sso_buffer_size;
509 if (new_cap < new_size + 1) {
510 new_cap = _NEFORCE
max(new_size + 1, new_cap + (new_cap >> 1));
513 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
516 dest = traits_type::copy(dest,
data(), offset) + offset;
518 traits_type::copy(dest,
data() + offset + len1, old_size - offset - len1);
523 storage_.long_.ptr = new_ptr;
524 storage_.long_.cap = new_cap;
525 size_pair_.value = new_size | long_flag;
526 traits_type::assign(storage_.long_.ptr + new_size, 1,
value_type());
533 if (size_ > capacity_pair_.
value - diff) {
538 traits_type::move(raw_ptr + len2, raw_ptr + len1,
end() - (first1 + len1));
539 traits_type::copy(raw_ptr, &*first2, len2);
543 traits_type::move(raw_ptr + len2, raw_ptr + len1,
end() - (first1 + len1));
544 traits_type::copy(raw_ptr, &*first2, len2);
545 size_ -= len1 - len2;
548 traits_type::assign(data_ + size_, 1,
value_type());
562 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
565 return replace_copy(first1, first1 + n1, first2, _NEFORCE
next(first2, n2));
572 NEFORCE_CONSTEXPR20
void reallocate(
size_type n) {
573#ifdef NEFORCE_USING_SSO
576 switch_to_long(new_cap);
580 const size_type old_cap = storage_.long_.cap;
582 const size_type new_cap = _NEFORCE
max(min_new_cap, old_cap + (old_cap >> 1));
584 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
585 traits_type::move(new_ptr, storage_.long_.ptr,
size());
589 storage_.long_.ptr = new_ptr;
590 storage_.long_.cap = new_cap;
594 const size_t new_cap =
595 _NEFORCE
max(capacity_pair_.
value + n, capacity_pair_.
value + (capacity_pair_.
value >> 1)) + 1;
596 new_buffer = capacity_pair_.
get_base().allocate(new_cap);
597 traits_type::move(new_buffer, data_, size_);
599 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
601 capacity_pair_.
value = new_cap;
602 traits_type::assign(data_ + size_, 1,
value_type());
605 capacity_pair_.
get_base().deallocate(new_buffer, capacity_pair_.
value);
620#ifdef NEFORCE_USING_SSO
622 if (!is_long() &&
size() + n < sso_buffer_size) {
623 pointer p = storage_.short_ + offset;
624 traits_type::move(p + n, p,
size() - offset);
625 traits_type::assign(p, n, value);
626 size_pair_.value = (
size() + n);
628 return iterator(storage_.short_ + offset,
this);
632 const size_type new_cap = _NEFORCE
max((is_long() ? storage_.long_.cap : sso_buffer_size) + n,
633 (is_long() ? storage_.long_.cap : sso_buffer_size) +
634 ((is_long() ? storage_.long_.cap : sso_buffer_size) >> 1)) +
637 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
640 dest = traits_type::copy(dest,
data(), offset) + offset;
641 dest = traits_type::assign(dest, n, value) + n;
642 traits_type::copy(dest,
data() + offset, old_size - offset);
647 storage_.long_.ptr = new_ptr;
648 storage_.long_.cap = new_cap;
649 size_pair_.value = (old_size + n) | long_flag;
650 traits_type::assign(storage_.long_.ptr +
size(), 1,
value_type());
652 return iterator(storage_.long_.ptr + offset,
this);
655 const size_t old_cap = capacity_pair_.
value;
656 const size_t new_cap = _NEFORCE
max(old_cap + n, old_cap + (old_cap >> 1));
658 pointer end1 = traits_type::move(new_buffer, data_, diff) + diff;
659 pointer end2 = traits_type::assign(end1, n, value) + n;
660 traits_type::move(end2, data_ + diff, size_ - diff);
661 capacity_pair_.
get_base().deallocate(data_, old_cap);
664 capacity_pair_.
value = new_cap;
665 traits_type::assign(data_ + size_, 1,
value_type());
666 return iterator(data_ + diff,
this);
678 template <
typename Iterator>
679 NEFORCE_CONSTEXPR20
iterator reallocate_copy(
iterator position, Iterator first, Iterator last) {
680#ifdef NEFORCE_USING_SSO
685 if (!is_long() && old_size + n < sso_buffer_size) {
686 pointer p = storage_.short_ + offset;
687 traits_type::move(p + n, p, old_size - offset);
691 size_pair_.value = old_size + n;
693 return iterator(storage_.short_ + offset,
this);
696 const size_type new_cap = _NEFORCE
max((is_long() ? storage_.long_.cap : sso_buffer_size) + n,
697 (is_long() ? storage_.long_.cap : sso_buffer_size) +
698 ((is_long() ? storage_.long_.cap : sso_buffer_size) >> 1)) +
701 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
704 dest = traits_type::copy(dest,
data(), offset) + offset;
706 traits_type::copy(dest,
data() + offset, old_size - offset);
711 storage_.long_.ptr = new_ptr;
712 storage_.long_.cap = new_cap;
713 size_pair_.value = (old_size + n) | long_flag;
714 traits_type::assign(storage_.long_.ptr +
size(), 1,
value_type());
716 return iterator(storage_.long_.ptr + offset,
this);
721 const size_t new_cap = _NEFORCE
max(old_cap + n, old_cap + (old_cap >> 1));
723 pointer end1 = traits_type::move(new_buffer, data_, diff) + diff;
725 traits_type::move(end2, data_ + diff, size_ - diff);
726 capacity_pair_.
get_base().deallocate(data_, old_cap);
729 capacity_pair_.
value = new_cap;
730 traits_type::assign(data_ + size_, 1,
value_type());
731 return iterator(data_ + diff,
this);
742#ifdef NEFORCE_USING_SSO
744 size_pair_.value = 0;
779#ifdef NEFORCE_USING_SSO
780 if (n < sso_capacity) {
783 size_pair_.value = n;
785 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
786 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
790 storage_.long_.ptr = new_ptr;
791 storage_.long_.cap = init_cap;
792 size_pair_.value = n | long_flag;
795 const size_type init_size = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
796 data_ = capacity_pair_.
get_base().allocate(init_size);
799 capacity_pair_.
value = init_size;
809#ifdef NEFORCE_USING_SSO
811 if (len < sso_capacity) {
814 size_pair_.value = len;
816 const size_type cap = other.is_long() ? other.storage_.long_.cap : (len + 1);
817 pointer new_ptr = size_pair_.get_base().allocate(cap);
821 storage_.long_.ptr = new_ptr;
822 storage_.long_.cap = cap;
823 size_pair_.value = len | long_flag;
826 construct_from_ptr(other.
data(), 0, other.
size());
840#ifdef NEFORCE_USING_SSO
843 if (len < sso_capacity) {
849 size_pair_.value = len;
852 if (storage_.long_.cap >= len + 1) {
855 size_pair_.value = len | long_flag;
861 const size_type cap = other.is_long() ? other.storage_.long_.cap : (len + 1);
862 pointer new_ptr = size_pair_.get_base().allocate(cap);
866 storage_.long_.ptr = new_ptr;
867 storage_.long_.cap = cap;
868 size_pair_.value = len | long_flag;
872 construct_from_ptr(other.
data(), 0, other.
size());
882#ifdef NEFORCE_USING_SSO
884 size_pair_(_NEFORCE
move(other.size_pair_)) {
885 if (other.is_long()) {
886 storage_.long_.ptr = other.storage_.long_.ptr;
887 storage_.long_.cap = other.storage_.long_.cap;
888 size_pair_.value = other.size_pair_.value;
890 other.storage_.long_.ptr =
nullptr;
891 other.storage_.long_.cap = 0;
892 other.size_pair_.value = 0;
895 size_pair_.value = other.size();
897 other.size_pair_.value = 0;
903 capacity_pair_(_NEFORCE
move(other.capacity_pair_)) {
904 other.data_ =
nullptr;
906 other.capacity_pair_.
value = 0;
920#ifdef NEFORCE_USING_SSO
923 size_pair_ = _NEFORCE
move(other.size_pair_);
925 if (other.is_long()) {
926 storage_.long_.ptr = other.storage_.long_.ptr;
927 storage_.long_.cap = other.storage_.long_.cap;
928 size_pair_.value = other.size_pair_.value;
930 other.storage_.long_.ptr =
nullptr;
931 other.storage_.long_.cap = 0;
932 other.size_pair_.value = 0;
935 size_pair_.value = other.size();
937 other.size_pair_.value = 0;
940 pointer new_data = other.data_;
942 auto new_capacity_pair = _NEFORCE
move(other.capacity_pair_);
944 other.data_ =
nullptr;
946 other.capacity_pair_.value = 0;
951 capacity_pair_ = _NEFORCE
move(new_capacity_pair);
978#ifdef NEFORCE_USING_SSO
979 if (len < sso_capacity) {
985 size_pair_.value = len;
987 if (is_long() && storage_.long_.cap >= len + 1) {
990 size_pair_.value = len | long_flag;
998 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1002 storage_.long_.ptr = new_ptr;
1003 storage_.long_.cap = new_cap;
1004 size_pair_.value = len | long_flag;
1007 if (capacity_pair_.
value < len) {
1009 capacity_pair_.
get_base().deallocate(data_);
1011 capacity_pair_.
value = len + 1;
1028 construct_from_ptr(other.
data(), position, other.
size() - position);
1039 n = _NEFORCE
min(n, other.
size() - position);
1040 construct_from_ptr(other.
data(), position, n);
1063#ifdef NEFORCE_USING_SSO
1064 if (len < sso_capacity) {
1070 size_pair_.value = len;
1072 if (is_long() && storage_.long_.cap >= len + 1) {
1075 size_pair_.value = len | long_flag;
1083 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1087 storage_.long_.ptr = new_ptr;
1088 storage_.long_.cap = new_cap;
1089 size_pair_.value = len | long_flag;
1092 if (capacity_pair_.
value < len) {
1094 capacity_pair_.
get_base().deallocate(data_);
1096 capacity_pair_.
value = len + 1;
1111 template <
typename Iterator, enable_if_t<!is_convertible_v<Iterator, value_type>,
int> = 0>
1113 construct_from_iter(first, last);
1120 NEFORCE_CONSTEXPR20
basic_string(std::initializer_list<value_type> ilist) :
1220#ifdef NEFORCE_USING_SSO
1221 return size_pair_.value & ~long_flag;
1238#ifdef NEFORCE_USING_SSO
1239 return is_long() ? storage_.long_.cap : sso_buffer_size;
1241 return capacity_pair_.
value;
1255 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool empty() const noexcept {
return size() == 0; }
1268#ifdef NEFORCE_USING_SSO
1270 switch_to_long(new_cap);
1272 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1276 storage_.long_.ptr = new_ptr;
1277 storage_.long_.cap = new_cap;
1282 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
1285 capacity_pair_.
value = new_cap;
1297 return *(
data() + n);
1307 return *(
data() + n);
1365#ifdef NEFORCE_USING_SSO
1367 return storage_.short_;
1369 return storage_.long_.ptr;
1380#ifdef NEFORCE_USING_SSO
1382 return storage_.short_;
1384 return storage_.long_.ptr;
1397#ifdef NEFORCE_USING_SSO
1399 if (!is_long() &&
size() + 1 < sso_buffer_size) {
1400 pointer p = storage_.short_ + offset;
1407 return basic_string::reallocate_fill(position, 1, value);
1409 if (size_ == capacity_pair_.
value) {
1410 return basic_string::reallocate_fill(position, 1, value);
1416 if (chars_after > 0) {
1444#ifdef NEFORCE_USING_SSO
1445 if (!is_long() &&
size() + n < sso_buffer_size) {
1447 pointer p = storage_.short_ + offset;
1448 traits_type::move(p + n, p,
size() - offset);
1449 traits_type::assign(p, n, value);
1450 size_pair_.value =
size() + n;
1455 return basic_string::reallocate_fill(position, n, value);
1457 if (capacity_pair_.
value - size_ < n) {
1458 return basic_string::reallocate_fill(position, n, value);
1463 const size_type chars_after = size_ - offset;
1465 if (chars_after > 0) {
1466 traits_type::move(p + n, p, chars_after);
1468 traits_type::assign(p, n, value);
1471 traits_type::assign(data_ + size_, 1,
value_type());
1484 template <
typename Iterator>
1491#ifdef NEFORCE_USING_SSO
1492 if (!is_long() &&
size() + len < sso_buffer_size) {
1494 pointer p = storage_.short_ + offset;
1499 size_pair_.value =
size() + len;
1503 return basic_string::reallocate_copy(position, first, last);
1505 if (capacity_pair_.
value - size_ < len) {
1506 return basic_string::reallocate_copy(position, first, last);
1511 const size_type chars_after = size_ - offset;
1513 if (chars_after > 0) {
1517 for (Iterator it = first; it != last; ++it, ++curr) {
1538#ifdef NEFORCE_USING_SSO
1541 size_pair_.value = new_size | long_flag;
1544 size_pair_.value = new_size;
1565#ifdef NEFORCE_USING_SSO
1566 if (!is_long() &&
size() + n < sso_buffer_size) {
1569 size_pair_.value =
size() + n;
1575 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1576 pointer p = storage_.long_.ptr + old_size;
1578 size_pair_.value = (old_size + n) | long_flag;
1586 size_pair_.value = (old_size + n) | (is_long() ? long_flag : 0);
1589 if (capacity_pair_.
value - size_ <= n) {
1618 n = _NEFORCE
min(n, other.
size() - position);
1636 return append(other, position, other.
size() - position);
1651 n = _NEFORCE
min(n, other.size() - position);
1705#ifdef NEFORCE_USING_SSO
1707 if (!is_long() && old_size + n < sso_buffer_size) {
1709 size_pair_.value = old_size + n;
1714 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1716 size_pair_.value = (old_size + n) | long_flag;
1723 size_pair_.value = (old_size + n) | long_flag;
1726 if (capacity_pair_.
value - size_ <= n) {
1750 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1758#ifdef NEFORCE_USING_SSO
1760 if (!is_long() && old_size + n < sso_buffer_size) {
1761 pointer p = storage_.short_ + old_size;
1765 size_pair_.value = old_size + n;
1770 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1771 pointer p = storage_.long_.ptr + old_size;
1775 size_pair_.value = (old_size + n) | long_flag;
1785 size_pair_.value = (old_size + n) | long_flag;
1788 if (capacity_pair_.
value - size_ <= n) {
1804 return append(ilist.begin(), ilist.end());
1879 template <
typename Iterator>
1882 return append(first, last);
1890 NEFORCE_CONSTEXPR20
basic_string&
assign(std::initializer_list<value_type> ilist) {
return *
this = ilist; }
1907#ifdef NEFORCE_USING_SSO
1911 if (chars_after > 0) {
1915 size_pair_.value = (
size() - 1) | long_flag;
1918 size_pair_.value =
size() - 1;
1924 if (chars_after > 0) {
1941 if (position >=
size()) {
1944 n = _NEFORCE
min(n,
size() - position);
1960 return erase(first, last);
1970 if (first == last) {
1974 const size_type erase_count = last - first;
1976#ifdef NEFORCE_USING_SSO
1980 if (chars_after > 0) {
1984 size_pair_.value = (
size() - erase_count) | long_flag;
1987 size_pair_.value =
size() - erase_count;
1993 if (chars_after > 0) {
1999 size_ -= erase_count;
2028 NEFORCE_CONSTEXPR20
void clear() noexcept {
2029#ifdef NEFORCE_USING_SSO
2033 size_pair_.value = 0;
2036 size_pair_.value = 0;
2048#ifdef NEFORCE_USING_SSO
2053 if (len < sso_capacity) {
2054 CharT tmp[sso_buffer_size];
2059 size_pair_.value = len;
2061 if (storage_.long_.cap > len + 1) {
2062 pointer new_ptr = size_pair_.get_base().allocate(len + 1);
2066 storage_.long_.ptr = new_ptr;
2067 storage_.long_.cap = len + 1;
2068 size_pair_.value = len | long_flag;
2073 if (new_cap >= capacity_pair_.
value) {
2095 return _NEFORCE
move(result);
2182 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
int compare(
const CharT* str)
const noexcept {
2222 return replace_copy(
begin() + position, n, other.
data(), other.
size());
2228 "basic_string replace iterator out of ranges.");
2229 return replace_copy(first, last - first, other.
data(), other.
size());
2241 "basic_string replace iterator out of ranges.");
2249 return replace_copy({
data() + position,
this}, n1, str, n2);
2255 "basic_string replace iterator out of ranges.");
2256 return replace_copy(first, last - first, str, n);
2263 return replace_fill({
data() + position,
this}, n1, n2, value);
2270 "basic_string replace iterator out of ranges.");
2271 return replace_fill(first,
static_cast<size_type>(last - first), n, value);
2279 return replace_copy({
data() + position1,
this}, n1, str.
data() + position2, n2);
2283 template <
typename Iterator>
2286 "basic_string replace iterator out of ranges.");
2287 return replace_copy(first, last, first2, last2);
2333 const size_type off = 0) const noexcept {
2367 const size_type off = 0) const noexcept {
2373 const size_type off = 0) const noexcept {
2379 const size_type off = 0) const noexcept {
2391 const size_type off = 0) const noexcept {
2403 const size_type off = 0) const noexcept {
2445 const size_type off = 0) const noexcept {
2451 const size_type off = 0) const noexcept {
2463 const size_type off = 0) const noexcept {
2475 const size_type off = 0) const noexcept {
2524 if (*(
data() + idx) == value) {
2553 const size_type other_size = other.size();
2554 return other_size <=
size() &&
2616 template <
typename Pred>
2623 while (it !=
end() && pred(*it)) {
2626 if (it !=
begin()) {
2639 template <
typename Pred>
2646 while (rit !=
rend() && pred(*rit)) {
2662 template <
typename Predicate>
2713 if (_NEFORCE
addressof(other) ==
this) {
2716#ifdef NEFORCE_USING_SSO
2717 _NEFORCE
swap(storage_, other.storage_);
2718 _NEFORCE
swap(size_pair_, other.size_pair_);
2720 _NEFORCE
swap(data_, other.data_);
2721 _NEFORCE
swap(size_, other.size_);
2722 _NEFORCE
swap(capacity_pair_, other.capacity_pair_);
2737 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
size_t to_hash() const noexcept {
2742#ifdef NEFORCE_STANDARD_17
2743template <
typename Iterator,
typename Alloc = allocator<iter_value_t<Iterator>>>
2747template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
2750template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
2755template <
typename CharT,
typename Traits,
typename Alloc>
2760 return _NEFORCE
move(tmp);
2763template <
typename CharT,
typename Traits,
typename Alloc>
2768 return _NEFORCE
move(tmp);
2770template <
typename CharT,
typename Traits,
typename Alloc>
2775 return _NEFORCE
move(tmp);
2778template <
typename CharT,
typename Traits,
typename Alloc>
2783 return _NEFORCE
move(tmp);
2785template <
typename CharT,
typename Traits,
typename Alloc>
2787 const basic_string_view<CharT, Traits>& rhs) {
2790 return _NEFORCE
move(tmp);
2793template <
typename CharT,
typename Traits,
typename Alloc>
2798 return _NEFORCE
move(tmp);
2800template <
typename CharT,
typename Traits,
typename Alloc>
2805 return _NEFORCE
move(tmp);
2808template <
typename CharT,
typename Traits,
typename Alloc>
2813template <
typename CharT,
typename Traits,
typename Alloc>
2817 tmp.append(_NEFORCE
move(rhs));
2818 return _NEFORCE
move(tmp);
2821template <
typename CharT,
typename Traits,
typename Alloc>
2826 tmp.append(_NEFORCE
move(rhs));
2830 return _NEFORCE
move(tmp);
2833template <
typename CharT,
typename Traits,
typename Alloc>
2837 tmp.append(_NEFORCE
move(rhs));
2838 return _NEFORCE
move(tmp);
2840template <
typename CharT,
typename Traits,
typename Alloc>
2843 return _NEFORCE
move(lhs.append(rhs));
2846template <
typename CharT,
typename Traits,
typename Alloc>
2849 tmp.append(_NEFORCE
move(rhs));
2850 return _NEFORCE
move(tmp);
2852template <
typename CharT,
typename Traits,
typename Alloc>
2854 return _NEFORCE
move(lhs.append(rhs));
2857template <
typename CharT,
typename Traits,
typename Alloc>
2858NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const CharT*
const lhs,
2860 return rhs.equal_to(lhs);
2862template <
typename CharT,
typename Traits,
typename Alloc>
2864 const CharT*
const rhs)
noexcept {
2865 return lhs.equal_to(rhs);
2867template <
typename CharT,
typename Traits,
typename Alloc>
2868NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const basic_string_view<CharT, Traits>& lhs,
2870 return rhs.equal_to(lhs);
2872template <
typename CharT,
typename Traits,
typename Alloc>
2874 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2875 return lhs.equal_to(rhs);
2878template <
typename CharT,
typename Traits,
typename Alloc>
2879NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const CharT*
const lhs,
2881 return !(lhs == rhs);
2883template <
typename CharT,
typename Traits,
typename Alloc>
2885 const CharT*
const rhs)
noexcept {
2886 return !(lhs == rhs);
2888template <
typename CharT,
typename Traits,
typename Alloc>
2889NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const basic_string_view<CharT, Traits>& lhs,
2891 return !(lhs == rhs);
2893template <
typename CharT,
typename Traits,
typename Alloc>
2895 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2896 return !(lhs == rhs);
2899template <
typename CharT,
typename Traits,
typename Alloc>
2900NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const CharT*
const lhs,
2902 return 0 < rhs.compare(lhs);
2904template <
typename CharT,
typename Traits,
typename Alloc>
2906 const CharT*
const rhs)
noexcept {
2907 return lhs.compare(rhs) < 0;
2909template <
typename CharT,
typename Traits,
typename Alloc>
2910NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const basic_string_view<CharT, Traits>& lhs,
2912 return 0 < rhs.compare(lhs);
2914template <
typename CharT,
typename Traits,
typename Alloc>
2916 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2917 return lhs.compare(rhs) < 0;
2920template <
typename CharT,
typename Traits,
typename Alloc>
2921NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const CharT*
const lhs,
2925template <
typename CharT,
typename Traits,
typename Alloc>
2927 const CharT*
const rhs)
noexcept {
2930template <
typename CharT,
typename Traits,
typename Alloc>
2931NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const basic_string_view<CharT, Traits>& lhs,
2935template <
typename CharT,
typename Traits,
typename Alloc>
2937 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2941template <
typename CharT,
typename Traits,
typename Alloc>
2942NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const CharT*
const lhs,
2944 return !(lhs > rhs);
2946template <
typename CharT,
typename Traits,
typename Alloc>
2948 const CharT*
const rhs)
noexcept {
2949 return !(lhs > rhs);
2951template <
typename CharT,
typename Traits,
typename Alloc>
2952NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const basic_string_view<CharT, Traits>& lhs,
2954 return !(lhs > rhs);
2956template <
typename CharT,
typename Traits,
typename Alloc>
2958 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2959 return !(lhs > rhs);
2962template <
typename CharT,
typename Traits,
typename Alloc>
2963NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const CharT*
const lhs,
2965 return !(rhs < lhs);
2967template <
typename CharT,
typename Traits,
typename Alloc>
2969 const CharT*
const rhs)
noexcept {
2970 return !(rhs < lhs);
2972template <
typename CharT,
typename Traits,
typename Alloc>
2973NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const basic_string_view<CharT, Traits>& lhs,
2975 return !(rhs < lhs);
2977template <
typename CharT,
typename Traits,
typename Alloc>
2979 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2980 return !(rhs < lhs);
2986#ifdef NEFORCE_STANDARD_20
2994NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD constexpr int compare(const basic_string_view view) const noexcept
比较字符串视图
static constexpr auto npos
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const view_type &view, const size_type off, const size_type count) const noexcept
从后向前查找指定长度的字符串视图
NEFORCE_CONSTEXPR20 basic_string & uppercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_uppercase< CharT >)))
转换为大写
NEFORCE_CONSTEXPR20 basic_string & append(const_pointer str, size_type n)
追加字符数组的指定长度
NEFORCE_CONSTEXPR20 basic_string & replace(iterator first, iterator last, Iterator first2, Iterator last2)
替换迭代器范围为另一个迭代器范围
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool starts_with(const basic_string &other) const noexcept
检查是否以另一个字符串开头
NEFORCE_CONSTEXPR20 basic_string & trim_left() noexcept
去除左侧空白字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference front() noexcept
访问第一个字符
NEFORCE_CONSTEXPR20 basic_string & replace(iterator first, iterator last, const size_type n, const value_type value)
替换迭代器范围为多个相同字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool starts_with(view_type view) const noexcept
检查是否以字符串视图开头
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个出现在字符集合中的字符
NEFORCE_CONSTEXPR20 basic_string & append(const basic_string &other, size_type position)
追加另一个字符串的子串
NEFORCE_CONSTEXPR20 ~basic_string()
析构函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rend() noexcept
获取反向结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool contains(const_pointer str) const noexcept
检查是否包含C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个等于指定字符的位置
NEFORCE_CONSTEXPR20 basic_string & assign(const basic_string &other)
赋值另一个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference back() noexcept
访问最后一个字符
NEFORCE_CONSTEXPR20 void reserve(const size_type n)
预留容量
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator begin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const CharT value, const size_type n=0) const noexcept
查找字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 view_type view() const noexcept
NEFORCE_CONSTEXPR20 basic_string(const_pointer str)
从C风格字符串构造
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference at(const size_type n) const noexcept
带边界检查的常量访问
NEFORCE_CONSTEXPR20 basic_string & lowercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_lowercase< CharT >)))
转换为小写
NEFORCE_CONSTEXPR20 basic_string & assign(const_pointer str)
赋值C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference operator[](const size_type n) const noexcept
常量下标访问操作符
NEFORCE_CONSTEXPR20 basic_string(basic_string &&other) noexcept
移动构造函数
NEFORCE_CONSTEXPR20 bool equal_to(const CharT *str) const noexcept
与C风格字符串相等比较
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const size_type off, const size_type n, const CharT *str) const
比较子串与C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const basic_string &other, const size_type n=0) const noexcept
查找子串
NEFORCE_CONSTEXPR20 iterator erase(iterator first, iterator last) noexcept
删除迭代器范围
NEFORCE_CONSTEXPR20 basic_string()
默认构造函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const view_type &view, const size_type off=0) const noexcept
查找第一个不在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
ptrdiff_t difference_type
差值类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个不在字符集合中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 basic_string repeat(size_type n) const noexcept
重复当前字符串n次
NEFORCE_CONSTEXPR20 basic_string(size_type n, int32_t value)
构造函数,指定大小和32位整数值
NEFORCE_CONSTEXPR20 void swap(basic_string &other) noexcept
交换两个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool contains(const basic_string &other) const noexcept
检查是否包含另一个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool ends_with(const basic_string &other) const noexcept
检查是否以另一个字符串结尾
NEFORCE_CONSTEXPR20 basic_string & operator+=(std::initializer_list< value_type > ilist)
追加初始化列表
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个出现在指定字符数组中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const CharT *str, const size_type off, const size_type count) const noexcept
查找指定长度的子串
const CharT * const_pointer
常量指针类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const basic_string &other, const size_type off=npos) const noexcept
查找最后一个不在字符集合中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type length() const noexcept
获取字符串长度
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator end() noexcept
获取结束迭代器
NEFORCE_CONSTEXPR20 basic_string(Iterator first, Iterator last)
从迭代器范围构造
NEFORCE_CONSTEXPR20 basic_string(const basic_string &other, size_type position)
从子串构造
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
NEFORCE_CONSTEXPR20 basic_string & assign(const_pointer str, const size_type n)
赋值字符数组的指定长度
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
NEFORCE_CONSTEXPR20 basic_string & append(view_type view, size_type n)
追加字符串视图的指定长度
NEFORCE_CONSTEXPR20 basic_string & erase(size_type position=0, size_type n=npos) noexcept
删除指定范围内的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const CharT value, const size_type n=npos) const noexcept
从后向前查找字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const view_type &view, const size_type off=0) const noexcept
从后向前查找字符串视图
NEFORCE_CONSTEXPR20 basic_string(size_type n, int64_t value)
构造函数,指定大小和64位整数值
NEFORCE_CONSTEXPR20 void pop_back() noexcept
删除末尾字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_pointer data() const noexcept
获取常量数据指针
NEFORCE_CONSTEXPR20 basic_string & append(value_type value)
追加单个字符
NEFORCE_CONSTEXPR20 basic_string(size_type n, value_type value)
构造函数,指定大小和填充字符
NEFORCE_CONSTEXPR20 basic_string & operator+=(const value_type value)
追加单个字符
basic_string_view< CharT, Traits > view_type
字符串视图类型
NEFORCE_CONSTEXPR20 basic_string(std::initializer_list< value_type > ilist)
从初始化列表构造
NEFORCE_CONSTEXPR20 basic_string & append(basic_string &&other)
追加移动字符串
NEFORCE_CONSTEXPR20 iterator insert(iterator position, Iterator first, Iterator last)
插入迭代器范围
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const size_type off, const size_type n, const basic_string &other) const
比较子串与另一个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个出现在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找最后一个不在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator<(const basic_string &rhs) const noexcept
小于比较操作符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const view_type &view, const size_type off, const size_type count) const noexcept
查找指定长度的字符串视图
NEFORCE_CONSTEXPR20 basic_string & replace(const size_type position, const size_type n1, const size_type n2, const value_type value)
替换子串为多个相同字符
NEFORCE_CONSTEXPR20 basic_string & replace(const size_type position, const size_type n1, const_pointer str, const size_type n2)
替换子串为指定长度的字符数组
NEFORCE_CONSTEXPR20 basic_string & replace(const size_type position, const size_type n, const basic_string &other)
替换子串为另一个字符串
NEFORCE_CONSTEXPR20 basic_string & trim_right() noexcept
去除右侧空白字符
NEFORCE_CONSTEXPR20 bool equal_to(const view_type view) const noexcept
与字符串视图相等比较
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const CharT *str) const noexcept
比较C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const CharT *str, const size_type off, const size_type n) const noexcept
从后向前查找指定长度的子串
NEFORCE_CONSTEXPR20 basic_string & trim_left_if(Pred pred)
根据谓词去除左侧字符
NEFORCE_CONSTEXPR20 basic_string & append(size_type n, value_type value)
追加多个相同字符
NEFORCE_CONSTEXPR20 basic_string & operator=(const_pointer str)
C风格字符串赋值运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept
获取字符数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool contains(view_type view) const noexcept
检查是否包含字符串视图
NEFORCE_CONSTEXPR20 basic_string & append(view_type view)
追加字符串视图
NEFORCE_CONSTEXPR20 basic_string & operator=(view_type view)
字符串视图赋值运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找最后一个出现在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type max_size() const noexcept
获取最大可能大小
NEFORCE_CONSTEXPR20 basic_string & append(const_pointer str)
追加C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个不等于指定字符的位置
NEFORCE_CONSTEXPR20 void push_back(value_type value)
在末尾插入字符
NEFORCE_CONSTEXPR20 basic_string & operator=(basic_string &&other) noexcept
移动赋值运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个不在C风格字符串中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const size_type off, const size_type n, const CharT *str, size_type count) const
比较子串与指定长度的字符数组
NEFORCE_CONSTEXPR20 size_type copy(pointer dest, const size_type count, size_type position=0) const
复制字符到目标缓冲区
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rbegin() noexcept
获取反向起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cbegin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 basic_string substr(const size_type off=0, size_type count=npos) const
获取子串
NEFORCE_CONSTEXPR20 basic_string & assign(const view_type &view)
赋值字符串视图
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cend() const noexcept
获取常量结束迭代器
NEFORCE_CONSTEXPR20 basic_string(view_type view, const size_type n)
从字符串视图构造(指定长度)
NEFORCE_CONSTEXPR20 bool equal_to(const basic_string &other) const noexcept
相等比较
NEFORCE_CONSTEXPR20 basic_string & operator=(std::initializer_list< value_type > ilist)
初始化列表赋值运算符
NEFORCE_CONSTEXPR20 basic_string & append(basic_string &&other, size_type position)
追加移动字符串的子串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个出现在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const CharT *str, const size_type off=0) const noexcept
查找第一个出现在C风格字符串中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference at(const size_type n) noexcept
带边界检查的访问
NEFORCE_CONSTEXPR20 basic_string & trim_right_if(Pred pred)
根据谓词去除右侧字符
NEFORCE_CONSTEXPR20 basic_string & append(basic_string &&other, size_type position, size_type n)
追加移动字符串的子串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](const size_type n) noexcept
下标访问操作符
NEFORCE_CONSTEXPR20 basic_string & append(const basic_string &other, size_type position, size_type n)
追加另一个字符串的子串
NEFORCE_CONSTEXPR20 basic_string & insert(size_type position, size_type n, value_type value)
在指定位置插入多个相同字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const view_type &view, const size_type off=0) const noexcept
查找字符串视图
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const basic_string &other, const size_type off=npos) const noexcept
查找最后一个出现在字符集合中的字符
NEFORCE_CONSTEXPR20 iterator erase(iterator first, const size_type n) noexcept
删除指定数量的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool starts_with(const value_type value) const noexcept
检查是否以指定字符开头
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool ends_with(view_type view) const noexcept
检查是否以字符串视图结尾
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
NEFORCE_CONSTEXPR20 basic_string & operator+=(basic_string &&other)
追加移动字符串
NEFORCE_CONSTEXPR20 basic_string & assign(Iterator first, Iterator last)
赋值迭代器范围
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const basic_string &other) const noexcept
比较另一个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type capacity() const noexcept
获取容量
NEFORCE_CONSTEXPR20 basic_string & operator=(const basic_string &other)
拷贝赋值运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const view_type &view) const noexcept
比较字符串视图
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference back() const noexcept
常量访问最后一个字符
NEFORCE_CONSTEXPR20 basic_string & operator+=(const basic_string &other)
追加另一个字符串
basic_string_iterator< false, basic_string > iterator
迭代器类型
NEFORCE_CONSTEXPR20 basic_string & trim_if(Predicate pred)
根据谓词去除两侧字符
NEFORCE_CONSTEXPR20 basic_string & operator+=(view_type view)
追加字符串视图
NEFORCE_CONSTEXPR20 void shrink_to_fit()
收缩容量以适应当前大小
NEFORCE_CONSTEXPR20 void resize(size_type n, value_type value)
调整大小
NEFORCE_CONSTEXPR20 basic_string & replace(const size_type position, const size_type n, const_pointer str)
替换子串为C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个出现在C风格字符串中的字符
NEFORCE_CONSTEXPR20 basic_string & append(std::initializer_list< value_type > ilist)
追加初始化列表
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool ends_with(value_type value) const noexcept
检查是否以指定字符结尾
NEFORCE_CONSTEXPR20 iterator insert(iterator position, value_type value)
插入单个字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find(const CharT *str, const size_type off=0) const noexcept
查找C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const CharT *str, const size_type off=npos) const noexcept
从后向前查找C风格字符串
NEFORCE_CONSTEXPR20 basic_string & trim() noexcept
去除两侧空白字符
NEFORCE_CONSTEXPR20 basic_string & replace(iterator first, iterator last, const basic_string &other)
替换迭代器范围为另一个字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator end() const noexcept
获取常量结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个不在指定字符数组中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator==(const basic_string &rhs) const noexcept
相等比较操作符
NEFORCE_CONSTEXPR20 void reverse() noexcept
反转字符串
NEFORCE_CONSTEXPR20 basic_string & assign(basic_string &&other)
赋值移动字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const CharT *str, const size_type off=0) const noexcept
查找第一个不在C风格字符串中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const CharT value, const size_type off=0) const noexcept
查找第一个不等于指定字符的位置
NEFORCE_CONSTEXPR20 iterator erase(iterator position) noexcept
删除指定位置的字符
NEFORCE_CONSTEXPR20 basic_string & replace(iterator first, iterator last, const_pointer str)
替换迭代器范围为C风格字符串
const CharT & const_reference
常量引用类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference front() const noexcept
常量访问第一个字符
NEFORCE_CONSTEXPR20 basic_string(const_pointer str, const size_type n)
从字符数组构造(指定长度)
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个出现在指定字符数组中的字符
NEFORCE_CONSTEXPR20 basic_string & replace(const size_type position1, const size_type n1, const basic_string &str, const size_type position2, const size_type n2=npos)
替换子串为另一个字符串的子串
NEFORCE_CONSTEXPR20 basic_string & operator+=(const_pointer str)
追加C风格字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool contains(value_type value) const noexcept
检查是否包含指定字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const CharT value, const size_type off=0) const noexcept
查找第一个等于指定字符的位置
basic_string_iterator< true, basic_string > const_iterator
常量迭代器类型
NEFORCE_CONSTEXPR20 basic_string(view_type view)
从字符串视图构造
NEFORCE_CONSTEXPR20 size_type count(value_type value, const size_type position=0) const noexcept
NEFORCE_CONSTEXPR20 basic_string & assign(std::initializer_list< value_type > ilist)
赋值初始化列表
NEFORCE_CONSTEXPR20 basic_string & assign(const size_type n, value_type value)
赋值多个相同字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 int compare(const size_type off, const size_type n, const basic_string &other, const size_type roff, const size_type count) const
比较子串与另一个字符串的子串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool empty() const noexcept
检查是否为空
static constexpr size_type npos
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_t to_hash() const noexcept
计算哈希值
NEFORCE_CONSTEXPR20 basic_string & replace(iterator first, iterator last, const_pointer str, const size_type n)
替换迭代器范围为指定长度的字符数组
NEFORCE_CONSTEXPR20 basic_string & append(Iterator first, Iterator last)
追加迭代器范围
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个不在字符串视图中的字符
NEFORCE_CONSTEXPR20 basic_string(const basic_string &other)
拷贝构造函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool starts_with(const_pointer str) const noexcept
检查是否以C风格字符串开头
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer data() noexcept
获取数据指针
NEFORCE_CONSTEXPR20 void resize(const size_type n)
调整大小(默认填充0)
NEFORCE_CONSTEXPR20 void clear() noexcept
清空字符串
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个不在指定字符数组中的字符
NEFORCE_CONSTEXPR20 basic_string & append(const basic_string &other)
追加另一个字符串
NEFORCE_CONSTEXPR20 basic_string(const basic_string &other, size_type position, size_type n)
从子串构造(指定长度)
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type rfind(const basic_string &other, const size_type off=npos) const noexcept
从后向前查找子串
NEFORCE_CONSTEXPR20 basic_string(size_type n)
构造函数,指定大小
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_last_not_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个不在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type find_first_of(const view_type &view, const size_type off=0) const noexcept
查找第一个出现在字符串视图中的字符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 view_type view(const size_type off, size_type count=npos) const noexcept
获取子串视图
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
Alloc allocator_type
分配器类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool ends_with(const_pointer str) const noexcept
检查是否以C风格字符串结尾
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_INLINE17 constexpr bool is_standard_layout_v
is_standard_layout的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_array_v
is_array的便捷变量模板
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT to_uppercase(const CharT c) noexcept
将字符转换为大写
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT to_lowercase(const CharT c) noexcept
将字符转换为小写
constexpr size_t char_traits_find_first_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找第一个出现在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_rfind(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
从后向前查找子序列
constexpr size_t char_traits_find_last_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找最后一个出现在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找最后一个不在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_rfind_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
从后向前查找单个字符
constexpr size_t char_traits_rfind_not_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
查找最后一个不等于指定字符的位置
constexpr int char_traits_compare(const char_traits_ptr_t< Traits > lhs, const size_t lh_size, const char_traits_ptr_t< Traits > rhs, const size_t rh_size) noexcept
比较两个字符序列(三路比较)
constexpr size_t char_traits_find(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
在字符序列中查找子序列
constexpr size_t char_traits_find_not_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
查找第一个不等于指定字符的位置
constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找第一个不在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_find_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
在字符序列中查找单个字符
constexpr bool char_traits_equal(const char_traits_ptr_t< Traits > lhs, const size_t lh_size, const char_traits_ptr_t< Traits > rhs, const size_t rh_size) noexcept
比较两个字符序列是否相等
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 bool is_space(const CharT c) noexcept
检查字符是否为空白字符
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
long long int64_t
64位有符号整数类型
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
NEFORCE_CONSTEXPR14 size_t FNV_hash_string(const CharT *str, const size_t len) noexcept
字符串类型的FNV哈希
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
NEFORCE_INLINE17 constexpr bool is_iter_v
检查类型是否为迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
NEFORCE_NODISCARD constexpr normal_iterator< Iterator > operator+(iter_difference_t< normal_iterator< Iterator > > n, const normal_iterator< Iterator > &iter) noexcept
加法运算符
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
void swap()=delete
删除无参数的swap重载
NEFORCE_INLINE17 constexpr bool is_allocator_v
is_allocator的便捷变量模板
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
NEFORCE_INLINE17 constexpr bool is_trivial_v
is_trivial的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
NEFORCE_CONSTEXPR20 Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
NEFORCE_CONSTEXPR20 pair< Iterator1, Iterator2 > uninitialized_copy_n(Iterator1 first, size_t count, Iterator2 result)
复制指定数量的元素到未初始化内存
typename real_size< Alloc, difference_type >::type size_type
大小类型
static NEFORCE_NODISCARD constexpr bool eq(const char_type lhs, const char_type rhs) noexcept
相等比较
static constexpr char_type * assign(char_type *const str, const size_t count, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值
static NEFORCE_NODISCARD constexpr int compare(const char_type *lhs, const char_type *rhs, size_t count) noexcept
比较两个字符序列
static constexpr char_type * move(char_type *dest, const char_type *srcs, const size_t count) noexcept
移动字符序列
static constexpr char_type * copy(char_type *dest, const char_type *srcs, const size_t count) noexcept
复制字符序列
static NEFORCE_NODISCARD constexpr size_t length(const char_type *str) noexcept
计算字符串长度
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const basic_string_iterator &other) const noexcept
计算距离操作
NEFORCE_CONSTEXPR20 void decrement() noexcept
递减操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](difference_type n) const noexcept
下标访问操作符
contiguous_iterator_tag iterator_category
迭代器类别
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const container_type * container() const noexcept
获取关联容器
typename container_type::size_type size_type
大小类型
typename container_type::value_type value_type
值类型
String container_type
容器类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference dereference() const noexcept
解引用操作
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer base() const noexcept
获取底层指针
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool less_than(const basic_string_iterator &rhs) const noexcept
小于比较
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool equal(const basic_string_iterator &rhs) const noexcept
相等比较
NEFORCE_CONSTEXPR20 void increment() noexcept
递增操作
NEFORCE_CONSTEXPR20 void advance(difference_type off) noexcept
前进操作
typename container_type::difference_type difference_type
差值类型
constexpr compressed_pair & get_base() noexcept
获取基类引用
NEFORCE_NODISCARD constexpr bool operator>=(const T &rhs) const noexcept(noexcept(!(derived()< rhs)))
大于等于比较运算符
NEFORCE_NODISCARD constexpr bool operator>(const T &rhs) const noexcept(noexcept(rhs< derived()))
大于比较运算符
NEFORCE_NODISCARD constexpr bool operator!=(const T &rhs) const noexcept(noexcept(!(*this==rhs)))
不等比较运算符
NEFORCE_NODISCARD constexpr bool operator<=(const T &rhs) const noexcept(noexcept(!(derived() > rhs)))
小于等于比较运算符