1#ifndef NEFORCE_CORE_STRING_BASIC_STRING_HPP__
2#define NEFORCE_CORE_STRING_BASIC_STRING_HPP__
17NEFORCE_BEGIN_NAMESPACE__
33template <
bool IsConst,
typename String>
34struct basic_string_iterator :
iiterator<basic_string_iterator<IsConst, String>> {
38 using size_type =
typename container_type::size_type;
42 typename container_type::reference>;
44 typename container_type::pointer>;
51 NEFORCE_CONSTEXPR20 basic_string_iterator() noexcept = default;
52 NEFORCE_CONSTEXPR20 ~basic_string_iterator() = default;
54 NEFORCE_CONSTEXPR20 basic_string_iterator(const basic_string_iterator&) noexcept = default;
55 NEFORCE_CONSTEXPR20 basic_string_iterator& operator=(const basic_string_iterator&) noexcept = default;
56 NEFORCE_CONSTEXPR20 basic_string_iterator(basic_string_iterator&&) noexcept = default;
57 NEFORCE_CONSTEXPR20 basic_string_iterator& operator=(basic_string_iterator&&) noexcept = default;
73 NEFORCE_DEBUG_VERIFY(current_ && str_,
"Attempting to dereference on a null pointer");
74 NEFORCE_DEBUG_VERIFY(str_->data() <= current_ && current_ <= str_->
data() + str_->size(),
75 "Attempting to dereference out of boundary");
83 NEFORCE_DEBUG_VERIFY(current_ && str_,
"Attempting to increment a null pointer");
84 NEFORCE_DEBUG_VERIFY(current_ < str_->
data() + str_->size(),
"Attempting to increment out of boundary");
92 NEFORCE_DEBUG_VERIFY(current_ && str_,
"Attempting to decrement a null pointer");
93 NEFORCE_DEBUG_VERIFY(str_->data() < current_,
"Attempting to decrement out of boundary");
102 NEFORCE_DEBUG_VERIFY((current_ && str_) || off == 0,
"Attempting to advance a null pointer");
103 NEFORCE_DEBUG_VERIFY((off < 0 ? off >= str_->data() - current_ : off <= str_->
data() + str_->size() - current_),
104 "Attempting to advance out of boundary");
115 NEFORCE_DEBUG_VERIFY(str_ == other.str_,
"Attempting to distance to a different container");
133 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal_to(
const basic_string_iterator& rhs)
const noexcept {
134 NEFORCE_DEBUG_VERIFY(str_ == rhs.str_,
"Attempting to equal to a different container");
135 return current_ == rhs.current_;
143 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool less_than(
const basic_string_iterator& rhs)
const noexcept {
144 NEFORCE_DEBUG_VERIFY(str_ == rhs.str_,
"Attempting to less than a different container");
145 return current_ < rhs.current_;
152 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
pointer base() const noexcept {
return current_; }
172template <
typename CharT,
typename Traits =
char_traits<CharT>,
typename Alloc = allocator<CharT>>
178 "basic string only contains non-array trivial standard-layout types.");
201#ifdef NEFORCE_USING_SSO
203 static constexpr size_type sso_buffer_bytes = MEMORY_ALIGN_THRESHHOLD;
205 static constexpr size_type sso_buffer_size = (sso_buffer_bytes +
sizeof(CharT) - 1) /
sizeof(CharT);
207 static constexpr size_type sso_capacity = sso_buffer_size - 1;
215 struct long_pointer {
219 CharT short_[sso_buffer_size];
225 compressed_pair<allocator_type, size_type> capacity_pair_{default_construct_tag{}, 0};
229#ifdef NEFORCE_USING_SSO
234 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool is_long() const noexcept {
return (size_pair_.value & long_flag) != 0; }
240 NEFORCE_CONSTEXPR20
void set_size(
size_type new_size)
noexcept {
241 size_pair_.value = (is_long() ? (new_size | long_flag) : new_size);
248 NEFORCE_CONSTEXPR20
void switch_to_long(
size_type new_cap) {
249 NEFORCE_DEBUG_VERIFY(new_cap >= sso_buffer_size,
"switch_to_long: new_cap too small");
250 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
252 traits_type::copy(new_ptr, storage_.short_, old_size);
253 traits_type::assign(new_ptr + old_size, 1,
value_type());
255 storage_.long_.ptr = new_ptr;
256 storage_.long_.cap = new_cap;
257 size_pair_.value = old_size | long_flag;
263 NEFORCE_CONSTEXPR20
void destroy_long() noexcept {
264 if (storage_.long_.ptr) {
265 size_pair_.get_base().deallocate(storage_.long_.ptr, storage_.long_.cap);
266 storage_.long_.ptr =
nullptr;
267 storage_.long_.cap = 0;
278 template <
typename Iterator>
279 NEFORCE_CONSTEXPR20
void construct_from_iter(Iterator first, Iterator last) {
282#ifdef NEFORCE_USING_SSO
283 if (n < sso_capacity) {
284 pointer dest = storage_.short_;
288 traits_type::assign(dest + n, 1,
value_type());
289 size_pair_.value = n;
291 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
292 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
297 traits_type::assign(new_ptr + n, 1,
value_type());
299 storage_.long_.ptr = new_ptr;
300 storage_.long_.cap = init_cap;
301 size_pair_.value = n | long_flag;
304 const size_type init_size = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
307 temp_data = capacity_pair_.
get_base().allocate(init_size);
309 capacity_pair_.
value = init_size;
314 capacity_pair_.
value = init_size;
315 traits_type::assign(data_ + size_, 1,
value_type());
318 _NEFORCE
destroy(temp_data, temp_data + n);
319 capacity_pair_.
get_base().deallocate(temp_data, capacity_pair_.
value);
334#ifdef NEFORCE_USING_SSO
335 if (n < sso_capacity) {
336 traits_type::copy(storage_.short_, str + position, n);
337 traits_type::assign(storage_.short_ + n, 1,
value_type());
338 size_pair_.value = n;
340 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
341 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
342 traits_type::copy(new_ptr, str + position, n);
343 traits_type::assign(new_ptr + n, 1,
value_type());
345 storage_.long_.ptr = new_ptr;
346 storage_.long_.cap = init_cap;
347 size_pair_.value = n | long_flag;
353 temp_capacity = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
354 temp_data = capacity_pair_.
get_base().allocate(temp_capacity);
355 traits_type::copy(temp_data, str + position, n);
359 capacity_pair_.
value = temp_capacity;
360 traits_type::assign(data_ + size_, 1,
value_type());
363 capacity_pair_.
get_base().deallocate(temp_data, capacity_pair_.
value);
367 capacity_pair_.
value = 0;
376 NEFORCE_CONSTEXPR20
void destroy_buffer() noexcept {
377#ifdef NEFORCE_USING_SSO
381 size_pair_.value = 0;
382 traits_type::assign(storage_.short_, 1,
value_type());
385 if (capacity_pair_.
value > 0) {
386 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
390 capacity_pair_.
value = 0;
405#ifdef NEFORCE_USING_SSO
408 const size_type actual_n1 = _NEFORCE
min(n1, old_size - offset);
409 if (actual_n1 == 0 && n2 == 0) {
413 const size_type new_size = old_size - actual_n1 + n2;
415 if (!is_long() && new_size < sso_capacity) {
416 pointer p = storage_.short_ + offset;
418 traits_type::move(p + n2, p + actual_n1, old_size - offset - actual_n1);
420 traits_type::assign(p, n2, value);
421 size_pair_.value = new_size;
422 traits_type::assign(storage_.short_ + new_size, 1,
value_type());
426 size_type new_cap = is_long() ? storage_.long_.cap : sso_buffer_size;
427 if (new_cap < new_size + 1) {
428 new_cap = _NEFORCE
max(new_size + 1, new_cap + (new_cap >> 1));
431 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
434 dest = traits_type::copy(dest,
data(), offset) + offset;
435 dest = traits_type::assign(dest, n2, value) + n2;
436 traits_type::copy(dest,
data() + offset + actual_n1, old_size - offset - actual_n1);
441 storage_.long_.ptr = new_ptr;
442 storage_.long_.cap = new_cap;
443 size_pair_.value = new_size | long_flag;
444 traits_type::assign(storage_.long_.ptr + new_size, 1,
value_type());
454 NEFORCE_DEBUG_VERIFY(size_ + diff <
max_size(),
"basic_string index out of range.");
455 if (size_ > capacity_pair_.
value - diff) {
460 traits_type::move(raw_ptr + n2, raw_ptr + n1,
end() - (first + n1));
461 traits_type::assign(raw_ptr, n2, value);
465 traits_type::move(raw_ptr + n2, raw_ptr + n1,
end() - (first + n1));
466 traits_type::assign(raw_ptr, n2, value);
470 traits_type::assign(data_ + size_, 1,
value_type());
484 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
491#ifdef NEFORCE_USING_SSO
494 const size_type new_size = old_size - len1 + len2;
496 if (!is_long() && new_size < sso_capacity) {
497 pointer p = storage_.short_ + offset;
499 traits_type::move(p + len2, p + len1, old_size - offset - len1);
504 size_pair_.value = new_size;
505 traits_type::assign(storage_.short_ + new_size, 1,
value_type());
509 size_type new_cap = is_long() ? storage_.long_.cap : sso_buffer_size;
510 if (new_cap < new_size + 1) {
511 new_cap = _NEFORCE
max(new_size + 1, new_cap + (new_cap >> 1));
514 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
517 dest = traits_type::copy(dest,
data(), offset) + offset;
519 traits_type::copy(dest,
data() + offset + len1, old_size - offset - len1);
524 storage_.long_.ptr = new_ptr;
525 storage_.long_.cap = new_cap;
526 size_pair_.value = new_size | long_flag;
527 traits_type::assign(storage_.long_.ptr + new_size, 1,
value_type());
533 NEFORCE_DEBUG_VERIFY(size_ + diff <
max_size(),
"basic_string replace_copy index out of range.");
534 if (size_ > capacity_pair_.
value - diff) {
539 traits_type::move(raw_ptr + len2, raw_ptr + len1,
end() - (first1 + len1));
540 traits_type::copy(raw_ptr, &*first2, len2);
544 traits_type::move(raw_ptr + len2, raw_ptr + len1,
end() - (first1 + len1));
545 traits_type::copy(raw_ptr, &*first2, len2);
546 size_ -= len1 - len2;
549 traits_type::assign(data_ + size_, 1,
value_type());
563 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
566 return replace_copy(first1, first1 + n1, first2, _NEFORCE
next(first2, n2));
573 NEFORCE_CONSTEXPR20
void reallocate(
size_type n) {
574#ifdef NEFORCE_USING_SSO
577 switch_to_long(new_cap);
581 const size_type old_cap = storage_.long_.cap;
583 const size_type new_cap = _NEFORCE
max(min_new_cap, old_cap + (old_cap >> 1));
585 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
586 traits_type::move(new_ptr, storage_.long_.ptr,
size());
590 storage_.long_.ptr = new_ptr;
591 storage_.long_.cap = new_cap;
595 const size_t new_cap =
596 _NEFORCE
max(capacity_pair_.
value + n, capacity_pair_.
value + (capacity_pair_.
value >> 1)) + 1;
597 new_buffer = capacity_pair_.
get_base().allocate(new_cap);
598 traits_type::move(new_buffer, data_, size_);
600 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
602 capacity_pair_.
value = new_cap;
603 traits_type::assign(data_ + size_, 1,
value_type());
606 capacity_pair_.
get_base().deallocate(new_buffer, capacity_pair_.
value);
621#ifdef NEFORCE_USING_SSO
623 if (!is_long() &&
size() + n < sso_buffer_size) {
624 pointer p = storage_.short_ + offset;
625 traits_type::move(p + n, p,
size() - offset);
626 traits_type::assign(p, n, value);
627 size_pair_.value = (
size() + n);
629 return iterator(storage_.short_ + offset,
this);
633 const size_type new_cap = _NEFORCE
max((is_long() ? storage_.long_.cap : sso_buffer_size) + n,
634 (is_long() ? storage_.long_.cap : sso_buffer_size) +
635 ((is_long() ? storage_.long_.cap : sso_buffer_size) >> 1)) +
638 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
641 dest = traits_type::copy(dest,
data(), offset) + offset;
642 dest = traits_type::assign(dest, n, value) + n;
643 traits_type::copy(dest,
data() + offset, old_size - offset);
648 storage_.long_.ptr = new_ptr;
649 storage_.long_.cap = new_cap;
650 size_pair_.value = (old_size + n) | long_flag;
651 traits_type::assign(storage_.long_.ptr +
size(), 1,
value_type());
653 return iterator(storage_.long_.ptr + offset,
this);
656 const size_t old_cap = capacity_pair_.
value;
657 const size_t new_cap = _NEFORCE
max(old_cap + n, old_cap + (old_cap >> 1));
659 pointer end1 = traits_type::move(new_buffer, data_, diff) + diff;
660 pointer end2 = traits_type::assign(end1, n, value) + n;
661 traits_type::move(end2, data_ + diff, size_ - diff);
662 capacity_pair_.
get_base().deallocate(data_, old_cap);
665 capacity_pair_.
value = new_cap;
666 traits_type::assign(data_ + size_, 1,
value_type());
667 return iterator(data_ + diff,
this);
679 template <
typename Iterator>
680 NEFORCE_CONSTEXPR20
iterator reallocate_copy(
iterator position, Iterator first, Iterator last) {
681#ifdef NEFORCE_USING_SSO
686 if (!is_long() && old_size + n < sso_buffer_size) {
687 pointer p = storage_.short_ + offset;
688 traits_type::move(p + n, p, old_size - offset);
692 size_pair_.value = old_size + n;
694 return iterator(storage_.short_ + offset,
this);
697 const size_type new_cap = _NEFORCE
max((is_long() ? storage_.long_.cap : sso_buffer_size) + n,
698 (is_long() ? storage_.long_.cap : sso_buffer_size) +
699 ((is_long() ? storage_.long_.cap : sso_buffer_size) >> 1)) +
702 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
705 dest = traits_type::copy(dest,
data(), offset) + offset;
707 traits_type::copy(dest,
data() + offset, old_size - offset);
712 storage_.long_.ptr = new_ptr;
713 storage_.long_.cap = new_cap;
714 size_pair_.value = (old_size + n) | long_flag;
715 traits_type::assign(storage_.long_.ptr +
size(), 1,
value_type());
717 return iterator(storage_.long_.ptr + offset,
this);
722 const size_t new_cap = _NEFORCE
max(old_cap + n, old_cap + (old_cap >> 1));
724 pointer end1 = traits_type::move(new_buffer, data_, diff) + diff;
726 traits_type::move(end2, data_ + diff, size_ - diff);
727 capacity_pair_.
get_base().deallocate(data_, old_cap);
730 capacity_pair_.
value = new_cap;
731 traits_type::assign(data_ + size_, 1,
value_type());
732 return iterator(data_ + diff,
this);
743#ifdef NEFORCE_USING_SSO
745 size_pair_.value = 0;
780#ifdef NEFORCE_USING_SSO
781 if (n < sso_capacity) {
784 size_pair_.value = n;
786 const size_type init_cap = _NEFORCE
max(sso_buffer_size, n + 1);
787 pointer new_ptr = size_pair_.get_base().allocate(init_cap);
791 storage_.long_.ptr = new_ptr;
792 storage_.long_.cap = init_cap;
793 size_pair_.value = n | long_flag;
796 const size_type init_size = _NEFORCE
max(MEMORY_ALIGN_THRESHHOLD, n + 1);
797 data_ = capacity_pair_.
get_base().allocate(init_size);
800 capacity_pair_.
value = init_size;
810#ifdef NEFORCE_USING_SSO
812 if (len < sso_capacity) {
815 size_pair_.value = len;
817 const size_type cap = other.is_long() ? other.storage_.long_.cap : (len + 1);
818 pointer new_ptr = size_pair_.get_base().allocate(cap);
822 storage_.long_.ptr = new_ptr;
823 storage_.long_.cap = cap;
824 size_pair_.value = len | long_flag;
827 construct_from_ptr(other.
data(), 0, other.
size());
841#ifdef NEFORCE_USING_SSO
844 if (len < sso_capacity) {
850 size_pair_.value = len;
853 if (storage_.long_.cap >= len + 1) {
856 size_pair_.value = len | long_flag;
862 const size_type cap = other.is_long() ? other.storage_.long_.cap : (len + 1);
863 pointer new_ptr = size_pair_.get_base().allocate(cap);
867 storage_.long_.ptr = new_ptr;
868 storage_.long_.cap = cap;
869 size_pair_.value = len | long_flag;
873 construct_from_ptr(other.
data(), 0, other.
size());
883#ifdef NEFORCE_USING_SSO
885 size_pair_(_NEFORCE
move(other.size_pair_)) {
886 if (other.is_long()) {
887 storage_.long_.ptr = other.storage_.long_.ptr;
888 storage_.long_.cap = other.storage_.long_.cap;
889 size_pair_.value = other.size_pair_.value;
891 other.storage_.long_.ptr =
nullptr;
892 other.storage_.long_.cap = 0;
893 other.size_pair_.value = 0;
896 size_pair_.value = other.size();
898 other.size_pair_.value = 0;
904 capacity_pair_(_NEFORCE
move(other.capacity_pair_)) {
905 other.data_ =
nullptr;
907 other.capacity_pair_.
value = 0;
921#ifdef NEFORCE_USING_SSO
924 size_pair_ = _NEFORCE
move(other.size_pair_);
926 if (other.is_long()) {
927 storage_.long_.ptr = other.storage_.long_.ptr;
928 storage_.long_.cap = other.storage_.long_.cap;
929 size_pair_.value = other.size_pair_.value;
931 other.storage_.long_.ptr =
nullptr;
932 other.storage_.long_.cap = 0;
933 other.size_pair_.value = 0;
936 size_pair_.value = other.size();
938 other.size_pair_.value = 0;
941 pointer new_data = other.data_;
943 auto new_capacity_pair = _NEFORCE
move(other.capacity_pair_);
945 other.data_ =
nullptr;
947 other.capacity_pair_.value = 0;
952 capacity_pair_ = _NEFORCE
move(new_capacity_pair);
979#ifdef NEFORCE_USING_SSO
980 if (len < sso_capacity) {
986 size_pair_.value = len;
988 if (is_long() && storage_.long_.cap >= len + 1) {
991 size_pair_.value = len | long_flag;
999 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1003 storage_.long_.ptr = new_ptr;
1004 storage_.long_.cap = new_cap;
1005 size_pair_.value = len | long_flag;
1008 if (capacity_pair_.
value < len) {
1010 capacity_pair_.
get_base().deallocate(data_);
1012 capacity_pair_.
value = len + 1;
1028 NEFORCE_DEBUG_VERIFY(position <= other.
size(),
"basic_string index out of range");
1029 construct_from_ptr(other.
data(), position, other.
size() - position);
1039 NEFORCE_DEBUG_VERIFY(position <= other.
size(),
"basic_string index out of range");
1040 n = _NEFORCE
min(n, other.
size() - position);
1041 construct_from_ptr(other.
data(), position, n);
1064#ifdef NEFORCE_USING_SSO
1065 if (len < sso_capacity) {
1071 size_pair_.value = len;
1073 if (is_long() && storage_.long_.cap >= len + 1) {
1076 size_pair_.value = len | long_flag;
1084 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1088 storage_.long_.ptr = new_ptr;
1089 storage_.long_.cap = new_cap;
1090 size_pair_.value = len | long_flag;
1093 if (capacity_pair_.
value < len) {
1095 capacity_pair_.
get_base().deallocate(data_);
1097 capacity_pair_.
value = len + 1;
1112 template <
typename Iterator, enable_if_t<!is_convertible_v<Iterator, value_type>,
int> = 0>
1114 construct_from_iter(first, last);
1121 NEFORCE_CONSTEXPR20
basic_string(std::initializer_list<value_type> ilist) :
1221#ifdef NEFORCE_USING_SSO
1222 return size_pair_.value & ~long_flag;
1239#ifdef NEFORCE_USING_SSO
1240 return is_long() ? storage_.long_.cap : sso_buffer_size;
1242 return capacity_pair_.
value;
1256 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool empty() const noexcept {
return size() == 0; }
1263 NEFORCE_DEBUG_VERIFY(n <
max_size(),
"basic_string reserve index out of range.");
1269#ifdef NEFORCE_USING_SSO
1271 switch_to_long(new_cap);
1273 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1277 storage_.long_.ptr = new_ptr;
1278 storage_.long_.cap = new_cap;
1283 capacity_pair_.
get_base().deallocate(data_, capacity_pair_.
value);
1286 capacity_pair_.
value = new_cap;
1297 NEFORCE_DEBUG_VERIFY(n <=
size(),
"basic_string [] index out of range.");
1298 return *(
data() + n);
1307 NEFORCE_DEBUG_VERIFY(n <=
size(),
"basic_string [] index out of range.");
1308 return *(
data() + n);
1330 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty basic_string");
1339 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty basic_string");
1348 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty basic_string");
1357 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty basic_string");
1366#ifdef NEFORCE_USING_SSO
1368 return storage_.short_;
1370 return storage_.long_.ptr;
1381#ifdef NEFORCE_USING_SSO
1383 return storage_.short_;
1385 return storage_.long_.ptr;
1398#ifdef NEFORCE_USING_SSO
1400 if (!is_long() &&
size() + 1 < sso_buffer_size) {
1401 pointer p = storage_.short_ + offset;
1408 return basic_string::reallocate_fill(position, 1, value);
1410 if (size_ == capacity_pair_.
value) {
1411 return basic_string::reallocate_fill(position, 1, value);
1417 if (chars_after > 0) {
1445#ifdef NEFORCE_USING_SSO
1446 if (!is_long() &&
size() + n < sso_buffer_size) {
1448 pointer p = storage_.short_ + offset;
1449 traits_type::move(p + n, p,
size() - offset);
1450 traits_type::assign(p, n, value);
1451 size_pair_.value =
size() + n;
1456 return basic_string::reallocate_fill(position, n, value);
1458 if (capacity_pair_.
value - size_ < n) {
1459 return basic_string::reallocate_fill(position, n, value);
1464 const size_type chars_after = size_ - offset;
1466 if (chars_after > 0) {
1467 traits_type::move(p + n, p, chars_after);
1469 traits_type::assign(p, n, value);
1472 traits_type::assign(data_ + size_, 1,
value_type());
1485 template <
typename Iterator>
1492#ifdef NEFORCE_USING_SSO
1493 if (!is_long() &&
size() + len < sso_buffer_size) {
1495 pointer p = storage_.short_ + offset;
1500 size_pair_.value =
size() + len;
1504 return basic_string::reallocate_copy(position, first, last);
1506 if (capacity_pair_.
value - size_ < len) {
1507 return basic_string::reallocate_copy(position, first, last);
1512 const size_type chars_after = size_ - offset;
1514 if (chars_after > 0) {
1518 for (Iterator it = first; it != last; ++it, ++curr) {
1538 NEFORCE_DEBUG_VERIFY(!
empty(),
"pop_back called on empty basic_string");
1539#ifdef NEFORCE_USING_SSO
1542 size_pair_.value = new_size | long_flag;
1545 size_pair_.value = new_size;
1561 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1566#ifdef NEFORCE_USING_SSO
1567 if (!is_long() &&
size() + n < sso_buffer_size) {
1570 size_pair_.value =
size() + n;
1576 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1577 pointer p = storage_.long_.ptr + old_size;
1579 size_pair_.value = (old_size + n) | long_flag;
1587 size_pair_.value = (old_size + n) | (is_long() ? long_flag : 0);
1590 if (capacity_pair_.
value - size_ <= n) {
1615 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1619 n = _NEFORCE
min(n, other.
size() - position);
1637 return append(other, position, other.
size() - position);
1648 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1652 n = _NEFORCE
min(n, other.size() - position);
1701 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1706#ifdef NEFORCE_USING_SSO
1708 if (!is_long() && old_size + n < sso_buffer_size) {
1710 size_pair_.value = old_size + n;
1715 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1717 size_pair_.value = (old_size + n) | long_flag;
1724 size_pair_.value = (old_size + n) | long_flag;
1727 if (capacity_pair_.
value - size_ <= n) {
1751 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1754 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1759#ifdef NEFORCE_USING_SSO
1761 if (!is_long() && old_size + n < sso_buffer_size) {
1762 pointer p = storage_.short_ + old_size;
1766 size_pair_.value = old_size + n;
1771 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1772 pointer p = storage_.long_.ptr + old_size;
1776 size_pair_.value = (old_size + n) | long_flag;
1786 size_pair_.value = (old_size + n) | long_flag;
1789 if (capacity_pair_.
value - size_ <= n) {
1805 return append(ilist.begin(), ilist.end());
1880 template <
typename Iterator>
1883 return append(first, last);
1891 NEFORCE_CONSTEXPR20
basic_string&
assign(std::initializer_list<value_type> ilist) {
return *
this = ilist; }
1906 NEFORCE_DEBUG_VERIFY(position !=
end(),
"erase: cannot erase end() iterator");
1908#ifdef NEFORCE_USING_SSO
1912 if (chars_after > 0) {
1916 size_pair_.value = (
size() - 1) | long_flag;
1919 size_pair_.value =
size() - 1;
1925 if (chars_after > 0) {
1942 if (position >=
size()) {
1945 n = _NEFORCE
min(n,
size() - position);
1961 return erase(first, last);
1971 if (first == last) {
1975 const size_type erase_count = last - first;
1977#ifdef NEFORCE_USING_SSO
1981 if (chars_after > 0) {
1985 size_pair_.value = (
size() - erase_count) | long_flag;
1988 size_pair_.value =
size() - erase_count;
1994 if (chars_after > 0) {
2000 size_ -= erase_count;
2029 NEFORCE_CONSTEXPR20
void clear() noexcept {
2030#ifdef NEFORCE_USING_SSO
2034 size_pair_.value = 0;
2037 size_pair_.value = 0;
2049#ifdef NEFORCE_USING_SSO
2054 if (len < sso_capacity) {
2055 CharT tmp[sso_buffer_size];
2060 size_pair_.value = len;
2062 if (storage_.long_.cap > len + 1) {
2063 pointer new_ptr = size_pair_.get_base().allocate(len + 1);
2067 storage_.long_.ptr = new_ptr;
2068 storage_.long_.cap = len + 1;
2069 size_pair_.value = len | long_flag;
2074 if (new_cap >= capacity_pair_.
value) {
2096 return _NEFORCE
move(result);
2107 NEFORCE_DEBUG_VERIFY(off <=
size(),
"basic_string index out of ranges.");
2141 NEFORCE_DEBUG_VERIFY(off <=
size(),
"basic_string index out of ranges.");
2154 NEFORCE_DEBUG_VERIFY(position <=
size(),
"basic_string copy position out of range");
2200 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
int compare(
const CharT* str)
const noexcept {
2244 for (
size_type i = 0; i < min_len; ++i) {
2248 return (lc < rc) ? -1 : 1;
2280 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2281 return replace_copy(
begin() + position, n, other.
data(), other.
size());
2286 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2287 "basic_string replace iterator out of ranges.");
2288 return replace_copy(first, last - first, other.
data(), other.
size());
2293 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2299 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2300 "basic_string replace iterator out of ranges.");
2307 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2308 return replace_copy({
data() + position,
this}, n1, str, n2);
2313 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2314 "basic_string replace iterator out of ranges.");
2315 return replace_copy(first, last - first, str, n);
2321 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2322 return replace_fill({
data() + position,
this}, n1, n2, value);
2328 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2329 "basic_string replace iterator out of ranges.");
2330 return replace_fill(first,
static_cast<size_type>(last - first), n, value);
2336 NEFORCE_DEBUG_VERIFY(position1 <
size(),
"basic_string index out of ranges.");
2337 NEFORCE_DEBUG_VERIFY(position2 <
size(),
"basic_string index out of ranges.");
2338 return replace_copy({
data() + position1,
this}, n1, str.
data() + position2, n2);
2342 template <
typename Iterator>
2344 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2345 "basic_string replace iterator out of ranges.");
2346 return replace_copy(first, last, first2, last2);
2392 const size_type off = 0) const noexcept {
2432 const size_type off = 0) const noexcept {
2438 const size_type off = 0) const noexcept {
2450 const size_type off = 0) const noexcept {
2462 const size_type off = 0) const noexcept {
2504 const size_type off = 0) const noexcept {
2510 const size_type off = 0) const noexcept {
2522 const size_type off = 0) const noexcept {
2534 const size_type off = 0) const noexcept {
2581 const size_type position = 0) const noexcept {
2584 if (*(
data() + idx) == value) {
2613 const size_type other_size = other.size();
2614 return other_size <=
size() &&
2676 template <
typename Pred>
2683 while (it !=
end() && pred(*it)) {
2686 if (it !=
begin()) {
2699 template <
typename Pred>
2706 while (rit !=
rend() && pred(*rit)) {
2722 template <
typename Predicate>
2750 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal_to(
const CharT* str)
const noexcept {
2777 if (_NEFORCE
addressof(other) ==
this) {
2780#ifdef NEFORCE_USING_SSO
2781 _NEFORCE
swap(storage_, other.storage_);
2782 _NEFORCE
swap(size_pair_, other.size_pair_);
2784 _NEFORCE
swap(data_, other.data_);
2785 _NEFORCE
swap(size_, other.size_);
2786 _NEFORCE
swap(capacity_pair_, other.capacity_pair_);
2796 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
size_t to_hash() const noexcept {
2801#ifdef NEFORCE_STANDARD_17
2802template <
typename Iterator,
typename Alloc = allocator<iter_value_t<Iterator>>>
2806template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
2809template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
2814template <
typename CharT,
typename Traits,
typename Alloc>
2819 return _NEFORCE
move(tmp);
2822template <
typename CharT,
typename Traits,
typename Alloc>
2827 return _NEFORCE
move(tmp);
2829template <
typename CharT,
typename Traits,
typename Alloc>
2834 return _NEFORCE
move(tmp);
2837template <
typename CharT,
typename Traits,
typename Alloc>
2842 return _NEFORCE
move(tmp);
2844template <
typename CharT,
typename Traits,
typename Alloc>
2846 const basic_string_view<CharT, Traits>& rhs) {
2849 return _NEFORCE
move(tmp);
2852template <
typename CharT,
typename Traits,
typename Alloc>
2857 return _NEFORCE
move(tmp);
2859template <
typename CharT,
typename Traits,
typename Alloc>
2864 return _NEFORCE
move(tmp);
2867template <
typename CharT,
typename Traits,
typename Alloc>
2872template <
typename CharT,
typename Traits,
typename Alloc>
2876 tmp.append(_NEFORCE
move(rhs));
2877 return _NEFORCE
move(tmp);
2880template <
typename CharT,
typename Traits,
typename Alloc>
2885 tmp.append(_NEFORCE
move(rhs));
2889 return _NEFORCE
move(tmp);
2892template <
typename CharT,
typename Traits,
typename Alloc>
2896 tmp.append(_NEFORCE
move(rhs));
2897 return _NEFORCE
move(tmp);
2899template <
typename CharT,
typename Traits,
typename Alloc>
2902 return _NEFORCE
move(lhs.append(rhs));
2905template <
typename CharT,
typename Traits,
typename Alloc>
2908 tmp.append(_NEFORCE
move(rhs));
2909 return _NEFORCE
move(tmp);
2911template <
typename CharT,
typename Traits,
typename Alloc>
2913 return _NEFORCE
move(lhs.append(rhs));
2916template <
typename CharT,
typename Traits,
typename Alloc>
2917NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const CharT*
const lhs,
2919 return rhs.equal_to(lhs);
2921template <
typename CharT,
typename Traits,
typename Alloc>
2923 const CharT*
const rhs)
noexcept {
2924 return lhs.equal_to(rhs);
2926template <
typename CharT,
typename Traits,
typename Alloc>
2927NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const basic_string_view<CharT, Traits>& lhs,
2929 return rhs.equal_to(lhs);
2931template <
typename CharT,
typename Traits,
typename Alloc>
2933 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2934 return lhs.equal_to(rhs);
2937template <
typename CharT,
typename Traits,
typename Alloc>
2938NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const CharT*
const lhs,
2940 return !(lhs == rhs);
2942template <
typename CharT,
typename Traits,
typename Alloc>
2944 const CharT*
const rhs)
noexcept {
2945 return !(lhs == rhs);
2947template <
typename CharT,
typename Traits,
typename Alloc>
2948NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const basic_string_view<CharT, Traits>& lhs,
2950 return !(lhs == rhs);
2952template <
typename CharT,
typename Traits,
typename Alloc>
2954 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2955 return !(lhs == rhs);
2958template <
typename CharT,
typename Traits,
typename Alloc>
2959NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const CharT*
const lhs,
2961 return 0 < rhs.compare(lhs);
2963template <
typename CharT,
typename Traits,
typename Alloc>
2965 const CharT*
const rhs)
noexcept {
2966 return lhs.compare(rhs) < 0;
2968template <
typename CharT,
typename Traits,
typename Alloc>
2969NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const basic_string_view<CharT, Traits>& lhs,
2971 return 0 < rhs.compare(lhs);
2973template <
typename CharT,
typename Traits,
typename Alloc>
2975 const basic_string_view<CharT, Traits>& rhs)
noexcept {
2976 return lhs.compare(rhs) < 0;
2979template <
typename CharT,
typename Traits,
typename Alloc>
2980NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const CharT*
const lhs,
2984template <
typename CharT,
typename Traits,
typename Alloc>
2986 const CharT*
const rhs)
noexcept {
2989template <
typename CharT,
typename Traits,
typename Alloc>
2990NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const basic_string_view<CharT, Traits>& lhs,
2994template <
typename CharT,
typename Traits,
typename Alloc>
2996 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3000template <
typename CharT,
typename Traits,
typename Alloc>
3001NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const CharT*
const lhs,
3003 return !(lhs > rhs);
3005template <
typename CharT,
typename Traits,
typename Alloc>
3007 const CharT*
const rhs)
noexcept {
3008 return !(lhs > rhs);
3010template <
typename CharT,
typename Traits,
typename Alloc>
3011NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const basic_string_view<CharT, Traits>& lhs,
3013 return !(lhs > rhs);
3015template <
typename CharT,
typename Traits,
typename Alloc>
3017 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3018 return !(lhs > rhs);
3021template <
typename CharT,
typename Traits,
typename Alloc>
3022NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const CharT*
const lhs,
3024 return !(rhs < lhs);
3026template <
typename CharT,
typename Traits,
typename Alloc>
3028 const CharT*
const rhs)
noexcept {
3029 return !(rhs < lhs);
3031template <
typename CharT,
typename Traits,
typename Alloc>
3032NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const basic_string_view<CharT, Traits>& lhs,
3034 return !(rhs < lhs);
3036template <
typename CharT,
typename Traits,
typename Alloc>
3038 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3039 return !(rhs < lhs);
3042#ifndef NEFORCE_STANDARD_17
3043# ifdef NEFORCE_USING_SSO
3044template <
typename CharT,
typename Traits,
typename Alloc>
3046template <
typename CharT,
typename Traits,
typename Alloc>
3048template <
typename CharT,
typename Traits,
typename Alloc>
3050template <
typename CharT,
typename Traits,
typename Alloc>
3053template <
typename CharT,
typename Traits,
typename Alloc>
3058#ifndef NEFORCE_COMPILER_CLANG_CL
3061# ifdef NEFORCE_STANDARD_20
3070NEFORCE_END_NAMESPACE__
static constexpr auto npos
constexpr int compare(const basic_string_view view) const noexcept
比较字符串视图
constexpr bool contains(view_type view) const noexcept
检查是否包含字符串视图
constexpr bool starts_with(view_type view) const noexcept
检查是否以字符串视图开头
constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
constexpr basic_string & append(basic_string &&other, size_type position, size_type n)
追加移动字符串的子串
constexpr basic_string & append(const basic_string &other, size_type position)
追加另一个字符串的子串
constexpr bool empty() const noexcept
检查是否为空
constexpr basic_string & operator+=(basic_string &&other)
追加移动字符串
constexpr size_type find_last_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找最后一个出现在字符串视图中的字符
constexpr basic_string(std::initializer_list< value_type > ilist)
从初始化列表构造
constexpr basic_string & operator+=(const_pointer str)
追加C风格字符串
constexpr size_type find_first_not_of(const view_type &view, const size_type off=0) const noexcept
查找第一个不在字符串视图中的字符
constexpr size_type size() const noexcept
获取字符数
constexpr basic_string & replace(iterator first, iterator last, const size_type n, const value_type value)
替换迭代器范围为多个相同字符
constexpr const_reference front() const noexcept
常量访问第一个字符
constexpr size_type rfind(const basic_string &other, const size_type off=npos) const noexcept
从后向前查找子串
constexpr size_type find_last_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个等于指定字符的位置
constexpr const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
constexpr size_type rfind(const view_type &view, const size_type off=npos) const noexcept
从后向前查找字符串视图
constexpr basic_string & append(basic_string &&other, size_type position)
追加移动字符串的子串
constexpr basic_string & trim() noexcept
去除两侧空白字符
constexpr basic_string & trim_left() noexcept
去除左侧空白字符
constexpr size_type find_first_of(const view_type &view, const size_type off=0) const noexcept
查找第一个出现在字符串视图中的字符
constexpr basic_string(size_type n, value_type value)
构造函数,指定大小和填充字符
constexpr bool ends_with(view_type view) const noexcept
检查是否以字符串视图结尾
constexpr int compare_ignore_case(const_pointer str) const noexcept
忽略大小写比较另一个字符串
constexpr const_pointer data() const noexcept
获取常量数据指针
constexpr basic_string & assign(const view_type &view)
赋值字符串视图
constexpr basic_string & append(const_pointer str, size_type n)
追加字符数组的指定长度
constexpr basic_string & append(size_type n, value_type value)
追加多个相同字符
constexpr basic_string & append(basic_string &&other)
追加移动字符串
ptrdiff_t difference_type
差值类型
constexpr size_type find_first_of(const CharT value, const size_type off=0) const noexcept
查找第一个等于指定字符的位置
constexpr basic_string(size_type n, int64_t value)
构造函数,指定大小和64位整数值
constexpr size_type find(const CharT value, const size_type n=0) const noexcept
查找字符
constexpr basic_string & trim_right() noexcept
去除右侧空白字符
constexpr basic_string(size_type n)
构造函数,指定大小
constexpr basic_string & replace(const size_type position, const size_type n, const basic_string &other)
替换子串为另一个字符串
constexpr bool contains(const_pointer str) const noexcept
检查是否包含C风格字符串
const CharT * const_pointer
常量指针类型
constexpr bool ends_with(const basic_string &other) const noexcept
检查是否以另一个字符串结尾
constexpr size_type find_first_not_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个不在字符集合中的字符
constexpr void resize(size_type n, value_type value)
调整大小
constexpr basic_string & assign(Iterator first, Iterator last)
赋值迭代器范围
constexpr basic_string(view_type view)
从字符串视图构造
constexpr basic_string & uppercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_uppercase< CharT >)))
转换为大写
constexpr basic_string & assign(basic_string &&other)
赋值移动字符串
constexpr basic_string(const basic_string &other)
拷贝构造函数
constexpr basic_string & lowercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_lowercase< CharT >)))
转换为小写
constexpr iterator insert(iterator position, value_type value)
插入单个字符
constexpr size_type find_first_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个出现在字符串视图中的字符
constexpr basic_string(const_pointer str, const size_type n)
从字符数组构造(指定长度)
constexpr basic_string & operator+=(std::initializer_list< value_type > ilist)
追加初始化列表
constexpr size_type capacity() const noexcept
获取容量
constexpr bool equal_to(const CharT *str) const noexcept
与C风格字符串相等比较
constexpr basic_string head(const size_type count=npos) const
获取头部子串
constexpr void resize(const size_type n)
调整大小(默认填充0)
constexpr reference operator[](const size_type n) noexcept
下标访问操作符
constexpr basic_string & trim_right_if(Pred pred)
根据谓词去除右侧字符
constexpr int compare(const basic_string &other) const noexcept
比较另一个字符串
constexpr basic_string & assign(const_pointer str)
赋值C风格字符串
constexpr size_type find_first_not_of(const CharT *str, const size_type off=0) const noexcept
查找第一个不在C风格字符串中的字符
constexpr size_type find(const view_type &view, const size_type off, const size_type count) const noexcept
查找指定长度的字符串视图
basic_string_view< CharT, Traits > view_type
字符串视图类型
constexpr const_iterator cbegin() const noexcept
获取常量起始迭代器
constexpr size_type find_last_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个出现在指定字符数组中的字符
constexpr basic_string & trim_if(Predicate pred)
根据谓词去除两侧字符
constexpr size_type count(value_type value, const size_type position=0) const noexcept
constexpr ~basic_string()
析构函数
constexpr pointer data() noexcept
获取数据指针
constexpr basic_string & replace(const size_type position1, const size_type n1, const basic_string &str, const size_type position2, const size_type n2=npos)
替换子串为另一个字符串的子串
constexpr size_type find_first_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个不在字符串视图中的字符
constexpr basic_string substr(const size_type off=0, const size_type count=npos) const
获取子串
constexpr reference back() noexcept
访问最后一个字符
constexpr void push_back(value_type value)
在末尾插入字符
constexpr const_reference at(const size_type n) const noexcept
带边界检查的常量访问
constexpr const_iterator end() const noexcept
获取常量结束迭代器
constexpr void reverse() noexcept
反转字符串
constexpr void shrink_to_fit()
收缩容量以适应当前大小
constexpr size_type find_last_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个出现在C风格字符串中的字符
constexpr basic_string(const basic_string &other, size_type position)
从子串构造
constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
constexpr basic_string & erase(size_type position=0, size_type n=npos) noexcept
删除指定范围内的字符
constexpr int compare(const size_type off, const size_type n, const CharT *str) const
比较子串与C风格字符串
constexpr basic_string & operator=(std::initializer_list< value_type > ilist)
初始化列表赋值运算符
constexpr bool equal_to(const basic_string &other) const noexcept
相等比较
constexpr basic_string & assign(std::initializer_list< value_type > ilist)
赋值初始化列表
constexpr int compare(const CharT *str) const noexcept
比较C风格字符串
constexpr const_reference operator[](const size_type n) const noexcept
常量下标访问操作符
constexpr int compare(const size_type off, const size_type n, const CharT *str, size_type count) const
比较子串与指定长度的字符数组
constexpr size_type find_last_not_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个不在C风格字符串中的字符
constexpr basic_string & replace(iterator first, iterator last, Iterator first2, Iterator last2)
替换迭代器范围为另一个迭代器范围
constexpr bool starts_with(const basic_string &other) const noexcept
检查是否以另一个字符串开头
constexpr view_type view(const size_type off, size_type count=npos) const noexcept
获取子串视图
constexpr size_type find_last_not_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个不等于指定字符的位置
constexpr reference at(const size_type n) noexcept
带边界检查的访问
constexpr basic_string & replace(const size_type position, const size_type n, const_pointer str)
替换子串为C风格字符串
constexpr basic_string & append(Iterator first, Iterator last)
追加迭代器范围
constexpr iterator erase(iterator first, const size_type n) noexcept
删除指定数量的字符
constexpr bool ends_with(const_pointer str) const noexcept
检查是否以C风格字符串结尾
constexpr bool contains(value_type value) const noexcept
检查是否包含指定字符
constexpr basic_string & append(std::initializer_list< value_type > ilist)
追加初始化列表
constexpr void pop_back() noexcept
删除末尾字符
constexpr iterator end() noexcept
获取结束迭代器
constexpr bool contains(const basic_string &other) const noexcept
检查是否包含另一个字符串
constexpr basic_string(size_type n, int32_t value)
构造函数,指定大小和32位整数值
constexpr bool equal_to(const view_type view) const noexcept
与字符串视图相等比较
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr basic_string & append(const basic_string &other)
追加另一个字符串
constexpr basic_string tail(const size_type off=0) const
获取尾部子串
constexpr const_reference back() const noexcept
常量访问最后一个字符
constexpr void clear() noexcept
清空字符串
constexpr basic_string & assign(const size_type n, value_type value)
赋值多个相同字符
constexpr basic_string & append(view_type view, size_type n)
追加字符串视图的指定长度
constexpr const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
constexpr size_type rfind(const CharT *str, const size_type off=npos) const noexcept
从后向前查找C风格字符串
constexpr size_type max_size() const noexcept
获取最大可能大小
constexpr iterator insert(iterator position, Iterator first, Iterator last)
插入迭代器范围
constexpr size_type find_last_of(const basic_string &other, const size_type off=npos) const noexcept
查找最后一个出现在字符集合中的字符
constexpr bool less_than(const basic_string &rhs) const noexcept
小于比较操作符
constexpr basic_string & trim_left_if(Pred pred)
根据谓词去除左侧字符
constexpr size_type find_last_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找最后一个不在字符串视图中的字符
constexpr basic_string(view_type view, const size_type n)
从字符串视图构造(指定长度)
constexpr basic_string & replace(const size_type position, const size_type n1, const size_type n2, const value_type value)
替换子串为多个相同字符
constexpr void reserve(const size_type n)
预留容量
constexpr size_type copy(pointer dest, const size_type count, size_type position=0) const
复制字符到目标缓冲区
constexpr basic_string & append(const_pointer str)
追加C风格字符串
constexpr basic_string(const basic_string &other, size_type position, size_type n)
从子串构造(指定长度)
basic_string_iterator< false, basic_string > iterator
迭代器类型
constexpr size_type find_last_not_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个不在字符串视图中的字符
constexpr int compare(const view_type &view) const noexcept
比较字符串视图
constexpr iterator erase(iterator first, iterator last) noexcept
删除迭代器范围
constexpr reference front() noexcept
访问第一个字符
constexpr size_type find_first_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个出现在指定字符数组中的字符
constexpr basic_string & insert(size_type position, size_type n, value_type value)
在指定位置插入多个相同字符
constexpr basic_string(Iterator first, Iterator last)
从迭代器范围构造
constexpr basic_string & operator=(basic_string &&other) noexcept
移动赋值运算符
constexpr basic_string & operator+=(const basic_string &other)
追加另一个字符串
constexpr basic_string & replace(const size_type position, const size_type n1, const_pointer str, const size_type n2)
替换子串为指定长度的字符数组
constexpr basic_string(basic_string &&other) noexcept
移动构造函数
constexpr size_type find_first_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个出现在字符集合中的字符
constexpr int compare(const size_type off, const size_type n, const basic_string &other) const
比较子串与另一个字符串
constexpr int compare(const size_type off, const size_type n, const basic_string &other, const size_type roff, const size_type count) const
比较子串与另一个字符串的子串
constexpr size_type find_first_of(const CharT *str, const size_type off=0) const noexcept
查找第一个出现在C风格字符串中的字符
constexpr size_type rfind(const CharT *str, const size_type off, const size_type n) const noexcept
从后向前查找指定长度的子串
constexpr size_type find_last_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个不在指定字符数组中的字符
constexpr size_type find_last_not_of(const basic_string &other, const size_type off=npos) const noexcept
查找最后一个不在字符集合中的字符
constexpr bool starts_with(const value_type value) const noexcept
检查是否以指定字符开头
const CharT & const_reference
常量引用类型
constexpr int compare_ignore_case(const basic_string &str) const noexcept
忽略大小写与C风格字符串三路比较
constexpr basic_string & operator+=(const value_type value)
追加单个字符
constexpr basic_string & append(value_type value)
追加单个字符
constexpr size_type length() const noexcept
获取字符串长度
constexpr size_type find(const CharT *str, const size_type off=0) const noexcept
查找C风格字符串
constexpr basic_string & operator=(view_type view)
字符串视图赋值运算符
constexpr size_type find(const view_type &view, const size_type off=0) const noexcept
查找字符串视图
constexpr basic_string & replace(iterator first, iterator last, const_pointer str, const size_type n)
替换迭代器范围为指定长度的字符数组
constexpr size_type find(const basic_string &other, const size_type n=0) const noexcept
查找子串
constexpr basic_string & assign(const basic_string &other)
赋值另一个字符串
constexpr basic_string(const_pointer str)
从C风格字符串构造
basic_string_iterator< true, basic_string > const_iterator
常量迭代器类型
constexpr basic_string & replace(iterator first, iterator last, const_pointer str)
替换迭代器范围为C风格字符串
constexpr size_type find(const CharT *str, const size_type off, const size_type count) const noexcept
查找指定长度的子串
constexpr basic_string & operator=(const_pointer str)
C风格字符串赋值运算符
constexpr basic_string & assign(const_pointer str, const size_type n)
赋值字符数组的指定长度
constexpr view_type view() const noexcept
constexpr const_iterator begin() const noexcept
获取常量起始迭代器
constexpr size_type rfind(const CharT value, const size_type n=npos) const noexcept
从后向前查找字符
constexpr basic_string & operator=(const basic_string &other)
拷贝赋值运算符
constexpr int compare_ignore_case(const view_type view) const noexcept
忽略大小写三路比较
static constexpr size_type npos
constexpr size_type find_first_not_of(const CharT value, const size_type off=0) const noexcept
查找第一个不等于指定字符的位置
constexpr basic_string & operator+=(view_type view)
追加字符串视图
constexpr basic_string & append(view_type view)
追加字符串视图
constexpr basic_string & append(const basic_string &other, size_type position, size_type n)
追加另一个字符串的子串
constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
constexpr const_iterator cend() const noexcept
获取常量结束迭代器
constexpr bool ends_with(value_type value) const noexcept
检查是否以指定字符结尾
constexpr void swap(basic_string &other) noexcept
交换两个字符串
constexpr size_type find_last_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个出现在字符串视图中的字符
constexpr iterator erase(iterator position) noexcept
删除指定位置的字符
constexpr basic_string repeat(size_type n) const noexcept
重复当前字符串n次
constexpr bool starts_with(const_pointer str) const noexcept
检查是否以C风格字符串开头
constexpr iterator begin() noexcept
获取起始迭代器
constexpr size_type find_first_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个不在指定字符数组中的字符
constexpr basic_string & replace(iterator first, iterator last, const basic_string &other)
替换迭代器范围为另一个字符串
constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
Alloc allocator_type
分配器类型
constexpr size_type rfind(const view_type &view, const size_type off, const size_type count) const noexcept
从后向前查找指定长度的字符串视图
constexpr basic_string()
默认构造函数
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr bool is_standard_layout_v
is_standard_layout的便捷变量模板
constexpr bool is_array_v
is_array的便捷变量模板
constexpr CharT to_lowercase(const CharT c) noexcept
将字符转换为小写
constexpr CharT to_uppercase(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
比较两个字符序列是否相等
constexpr 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 T clamp(const T &value, const T &lower, const T &upper, Compare comp) noexcept(noexcept(comp(value, lower)))
将值限制在指定范围内
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
long long int64_t
64位有符号整数类型
constexpr size_t FNV_hash_string(const CharT *str, const size_t len) noexcept
字符串类型的FNV哈希
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
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)
计算两个迭代器之间的距离
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重载
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
constexpr bool is_trivial_v
is_trivial的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
constexpr Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
constexpr Iterator2 uninitialized_copy_n(Iterator1 first, size_t count, Iterator2 result)
复制指定数量的元素到未初始化内存
typename real_size< Alloc, difference_type >::type size_type
大小类型
static constexpr int compare(const char_type *lhs, const char_type *rhs, size_t count) noexcept
比较两个字符序列
static constexpr char_type * assign(char_type *const str, const size_t count, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值
static constexpr bool eq(const char_type lhs, const char_type rhs) 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 constexpr size_t length(const char_type *str) noexcept
计算字符串长度
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
constexpr void advance(difference_type off) noexcept
前进操作
constexpr const container_type * container() const noexcept
获取关联容器
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
constexpr reference dereference() const noexcept
解引用操作
contiguous_iterator_tag iterator_category
迭代器类别
constexpr void decrement() noexcept
递减操作
constexpr bool equal_to(const basic_string_iterator &rhs) const noexcept
相等比较
typename container_type::size_type size_type
大小类型
constexpr pointer base() const noexcept
获取底层指针
constexpr difference_type distance_to(const basic_string_iterator &other) const noexcept
计算距离操作
constexpr void increment() noexcept
递增操作
typename container_type::value_type value_type
值类型
String container_type
容器类型
constexpr bool less_than(const basic_string_iterator &rhs) const noexcept
小于比较
constexpr reference operator[](difference_type n) const noexcept
下标访问操作符
typename container_type::difference_type difference_type
差值类型
constexpr compressed_pair & get_base() &noexcept
获取基类引用
constexpr bool operator<=(const T &rhs) const noexcept(noexcept(!(rhs.less_than(derived()))))
小于等于比较运算符
constexpr bool operator>=(const T &rhs) const noexcept(noexcept(!(derived().less_than(rhs))))
大于等于比较运算符
constexpr bool operator==(const T &rhs) const noexcept(noexcept(derived().equal_to(rhs)))
相等比较运算符
constexpr bool operator!=(const T &rhs) const noexcept(noexcept(!(derived().equal_to(rhs))))
不等比较运算符
constexpr bool operator>(const T &rhs) const noexcept(noexcept(rhs.less_than(derived())))
大于比较运算符
constexpr bool operator<(const T &rhs) const noexcept(noexcept(derived().less_than(rhs)))
小于比较运算符