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");
113 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type
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];
222 pointer data_ =
nullptr;
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);
251 const size_type old_size =
size();
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) {
280 const size_type n = _NEFORCE
distance(first, last);
282#ifdef NEFORCE_USING_SSO
283 if (n < sso_capacity) {
284 pointer dest = storage_.short_;
285 for (size_type i = 0; i < n; ++i) {
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);
293 pointer dest = new_ptr;
294 for (size_type i = 0; i < n; ++i) {
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);
305 pointer temp_data =
nullptr;
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);
333 NEFORCE_CONSTEXPR20
void construct_from_ptr(const_pointer str, size_type position, size_type n) {
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;
350 pointer temp_data =
nullptr;
351 size_type temp_capacity = 0;
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;
403 NEFORCE_CONSTEXPR20 basic_string& replace_fill(iterator first, size_type n1,
const size_type n2,
404 const value_type value) {
405#ifdef NEFORCE_USING_SSO
406 const difference_type offset = first -
begin();
407 const size_type old_size =
size();
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;
417 if (
static_cast<difference_type
>(old_size - offset - actual_n1) > 0) {
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);
432 pointer dest = new_ptr;
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());
448 if (
static_cast<size_type
>(
end() - first) < n1) {
449 n1 =
static_cast<size_type
>(
end() - first);
453 const size_type diff = n2 - n1;
454 NEFORCE_DEBUG_VERIFY(size_ + diff < max_size(),
"basic_string index out of range.");
455 if (size_ > capacity_pair_.value - diff) {
459 pointer raw_ptr = &*first;
460 traits_type::move(raw_ptr + n2, raw_ptr + n1,
end() - (first + n1));
461 traits_type::assign(raw_ptr, n2, value);
464 pointer raw_ptr = &*first;
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>
485 NEFORCE_CONSTEXPR20 basic_string&
replace_copy(iterator first1, iterator last1, Iterator first2, Iterator last2) {
486 static_assert(is_iter_v<Iterator> && is_same_v<iter_value_t<Iterator>, value_type>,
"Iterator type mismatch.");
488 size_type len1 = _NEFORCE
distance(first1, last1);
489 size_type len2 = _NEFORCE
distance(first2, last2);
491#ifdef NEFORCE_USING_SSO
492 const difference_type offset = first1 -
begin();
493 const size_type old_size =
size();
494 const size_type new_size = old_size - len1 + len2;
496 if (!is_long() && new_size < sso_capacity) {
497 pointer p = storage_.short_ + offset;
498 if (
static_cast<difference_type
>(old_size - offset - len1) > 0) {
499 traits_type::move(p + len2, p + len1, old_size - offset - len1);
501 for (size_type i = 0; i < len2; ++i) {
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);
515 pointer dest = new_ptr;
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());
532 const size_type diff = len2 - len1;
533 NEFORCE_DEBUG_VERIFY(size_ + diff < max_size(),
"basic_string replace_copy index out of range.");
534 if (size_ > capacity_pair_.value - diff) {
538 pointer raw_ptr = &*first1;
539 traits_type::move(raw_ptr + len2, raw_ptr + len1,
end() - (first1 + len1));
540 traits_type::copy(raw_ptr, &*first2, len2);
543 pointer raw_ptr = &*first1;
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>
564 NEFORCE_CONSTEXPR20 basic_string&
replace_copy(iterator first1,
const size_type n1, Iterator first2,
565 const size_type n2) {
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
576 const size_type new_cap = _NEFORCE
max(sso_buffer_size,
size() + n + 1);
577 switch_to_long(new_cap);
581 const size_type old_cap = storage_.long_.cap;
582 const size_type min_new_cap =
size() + n + 1;
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());
587 traits_type::assign(new_ptr +
size(), 1, value_type());
590 storage_.long_.ptr = new_ptr;
591 storage_.long_.cap = new_cap;
593 pointer new_buffer =
nullptr;
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);
620 NEFORCE_CONSTEXPR20 iterator reallocate_fill(iterator position, size_type n, value_type value) {
621#ifdef NEFORCE_USING_SSO
622 const size_type offset = position -
begin();
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);
628 traits_type::assign(storage_.short_ +
size(), 1, value_type());
629 return iterator(storage_.short_ + offset,
this);
632 const size_type old_size =
size();
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);
639 pointer dest = new_ptr;
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);
655 const difference_type diff = (&*position) - data_;
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));
658 pointer new_buffer = capacity_pair_.get_base().allocate(new_cap);
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
682 const size_type offset = position -
begin();
683 const size_type n = _NEFORCE
distance(first, last);
684 const size_type old_size =
size();
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);
689 for (size_type i = 0; i < n; ++i) {
692 size_pair_.
value = old_size + n;
693 traits_type::assign(storage_.short_ +
size(), 1, value_type());
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);
703 pointer dest = new_ptr;
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);
719 const difference_type diff = position -
begin();
720 const size_type old_cap = capacity_pair_.value;
721 const size_type n = _NEFORCE
distance(first, last);
722 const size_t new_cap = _NEFORCE
max(old_cap + n, old_cap + (old_cap >> 1));
723 pointer new_buffer = capacity_pair_.get_base().allocate(new_cap);
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) {
1009 pointer new_buffer = capacity_pair_.get_base().allocate(len + 1);
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);
1068#ifdef NEFORCE_USING_SSO
1069 if (len < sso_capacity) {
1075 size_pair_.value = len;
1077 if (is_long() && storage_.long_.cap >= len + 1) {
1080 size_pair_.value = len | long_flag;
1088 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1092 storage_.long_.ptr = new_ptr;
1093 storage_.long_.cap = new_cap;
1094 size_pair_.value = len | long_flag;
1097 if (capacity_pair_.value < len) {
1098 pointer new_buffer = capacity_pair_.get_base().allocate(len + 1);
1099 capacity_pair_.get_base().deallocate(data_);
1101 capacity_pair_.value = len + 1;
1116 template <
typename Iterator, enable_if_t<!is_convertible_v<Iterator, value_type>,
int> = 0>
1118 construct_from_iter(first, last);
1125 NEFORCE_CONSTEXPR20
basic_string(std::initializer_list<value_type> ilist) :
1225#ifdef NEFORCE_USING_SSO
1226 return size_pair_.value & ~long_flag;
1237#ifdef NEFORCE_USING_SSO
1238 constexpr size_type flag_mask = ~long_flag;
1239 const size_type alloc_max = size_pair_.get_base().max_size();
1242 const size_type alloc_max = capacity_pair_.get_base().max_size();
1244 return _NEFORCE
min(alloc_max - 1,
npos & flag_mask);
1252#ifdef NEFORCE_USING_SSO
1253 return is_long() ? storage_.long_.cap : sso_buffer_size;
1255 return capacity_pair_.value;
1269 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool empty() const noexcept {
return size() == 0; }
1276 NEFORCE_DEBUG_VERIFY(n <
max_size(),
"basic_string reserve index out of range.");
1282#ifdef NEFORCE_USING_SSO
1284 switch_to_long(new_cap);
1286 pointer new_ptr = size_pair_.get_base().allocate(new_cap);
1290 storage_.long_.ptr = new_ptr;
1291 storage_.long_.cap = new_cap;
1294 pointer new_buffer = capacity_pair_.get_base().allocate(new_cap);
1296 capacity_pair_.get_base().deallocate(data_, capacity_pair_.value);
1299 capacity_pair_.value = new_cap;
1310 NEFORCE_DEBUG_VERIFY(n <=
size(),
"basic_string [] index out of range.");
1311 return *(
data() + n);
1320 NEFORCE_DEBUG_VERIFY(n <=
size(),
"basic_string [] index out of range.");
1321 return *(
data() + n);
1343 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty basic_string");
1352 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty basic_string");
1361 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty basic_string");
1370 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty basic_string");
1379#ifdef NEFORCE_USING_SSO
1381 return storage_.short_;
1383 return storage_.long_.ptr;
1394#ifdef NEFORCE_USING_SSO
1396 return storage_.short_;
1398 return storage_.long_.ptr;
1411#ifdef NEFORCE_USING_SSO
1413 if (!is_long() &&
size() + 1 < sso_buffer_size) {
1414 pointer p = storage_.short_ + offset;
1421 return basic_string::reallocate_fill(position, 1, value);
1423 if (size_ == capacity_pair_.value) {
1424 return basic_string::reallocate_fill(position, 1, value);
1430 if (chars_after > 0) {
1453 NEFORCE_CONSTEXPR20
iterator insert(
iterator position, size_type n, value_type value) {
1458#ifdef NEFORCE_USING_SSO
1459 if (!is_long() && size() + n < sso_buffer_size) {
1460 const size_type offset = position - begin();
1461 pointer p = storage_.short_ + offset;
1462 traits_type::move(p + n, p, size() - offset);
1463 traits_type::assign(p, n, value);
1464 size_pair_.
value = size() + n;
1465 traits_type::assign(storage_.short_ + size(), 1, value_type());
1466 return iterator(p,
this);
1469 return basic_string::reallocate_fill(position, n, value);
1471 if (capacity_pair_.value - size_ < n) {
1472 return basic_string::reallocate_fill(position, n, value);
1475 const size_type offset = position -
begin();
1476 pointer p = data_ + offset;
1477 const size_type chars_after = size_ - offset;
1479 if (chars_after > 0) {
1480 traits_type::move(p + n, p, chars_after);
1482 traits_type::assign(p, n, value);
1485 traits_type::assign(data_ + size_, 1, value_type());
1486 return iterator(p,
this);
1498 template <
typename Iterator>
1505#ifdef NEFORCE_USING_SSO
1506 if (!is_long() &&
size() + len < sso_buffer_size) {
1508 pointer p = storage_.short_ + offset;
1513 size_pair_.value =
size() + len;
1517 return basic_string::reallocate_copy(position, first, last);
1519 if (capacity_pair_.value - size_ < len) {
1520 return basic_string::reallocate_copy(position, first, last);
1525 const size_type chars_after = size_ - offset;
1527 if (chars_after > 0) {
1531 for (Iterator it = first; it != last; ++it, ++curr) {
1551 NEFORCE_DEBUG_VERIFY(!
empty(),
"pop_back called on empty basic_string");
1552#ifdef NEFORCE_USING_SSO
1555 size_pair_.value = new_size | long_flag;
1558 size_pair_.value = new_size;
1574 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1579#ifdef NEFORCE_USING_SSO
1580 if (!is_long() &&
size() + n < sso_buffer_size) {
1583 size_pair_.value =
size() + n;
1589 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1590 pointer p = storage_.long_.ptr + old_size;
1592 size_pair_.value = (old_size + n) | long_flag;
1600 size_pair_.value = (old_size + n) | (is_long() ? long_flag : 0);
1603 if (capacity_pair_.value - size_ <= n) {
1628 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1632 n = _NEFORCE
min(n, other.
size() - position);
1650 return append(other, position, other.
size() - position);
1661 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1665 n = _NEFORCE
min(n, other.size() - position);
1714 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1719#ifdef NEFORCE_USING_SSO
1721 if (!is_long() && old_size + n < sso_buffer_size) {
1723 size_pair_.value = old_size + n;
1728 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1730 size_pair_.value = (old_size + n) | long_flag;
1737 size_pair_.value = (old_size + n) | long_flag;
1740 if (capacity_pair_.value - size_ <= n) {
1766 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1769 NEFORCE_DEBUG_VERIFY(
size() + n <
max_size(),
"basic_string append iterator out of ranges.");
1774#ifdef NEFORCE_USING_SSO
1776 if (!is_long() && old_size + n < sso_buffer_size) {
1777 pointer p = storage_.short_ + old_size;
1781 size_pair_.value = old_size + n;
1786 if (is_long() && storage_.long_.cap >= old_size + n + 1) {
1787 pointer p = storage_.long_.ptr + old_size;
1791 size_pair_.value = (old_size + n) | long_flag;
1801 size_pair_.value = (old_size + n) | long_flag;
1804 if (capacity_pair_.value - size_ <= n) {
1820 return append(ilist.begin(), ilist.end());
1895 template <
typename Iterator>
1898 return append(first, last);
1906 NEFORCE_CONSTEXPR20
basic_string&
assign(std::initializer_list<value_type> ilist) {
return *
this = ilist; }
1921 NEFORCE_DEBUG_VERIFY(position !=
end(),
"erase: cannot erase end() iterator");
1923#ifdef NEFORCE_USING_SSO
1927 if (chars_after > 0) {
1931 size_pair_.value = (
size() - 1) | long_flag;
1934 size_pair_.value =
size() - 1;
1940 if (chars_after > 0) {
1957 if (position >=
size()) {
1960 n = _NEFORCE
min(n,
size() - position);
1976 return erase(first, last);
1986 if (first == last) {
1990 const size_type erase_count = last - first;
1992#ifdef NEFORCE_USING_SSO
1996 if (chars_after > 0) {
2000 size_pair_.value = (
size() - erase_count) | long_flag;
2003 size_pair_.value =
size() - erase_count;
2009 if (chars_after > 0) {
2015 size_ -= erase_count;
2044 NEFORCE_CONSTEXPR20
void clear() noexcept {
2045#ifdef NEFORCE_USING_SSO
2049 size_pair_.value = 0;
2052 size_pair_.value = 0;
2064#ifdef NEFORCE_USING_SSO
2069 if (len < sso_capacity) {
2070 CharT tmp[sso_buffer_size];
2075 size_pair_.value = len;
2077 if (storage_.long_.cap > len + 1) {
2078 pointer new_ptr = size_pair_.get_base().allocate(len + 1);
2082 storage_.long_.ptr = new_ptr;
2083 storage_.long_.cap = len + 1;
2084 size_pair_.value = len | long_flag;
2089 if (new_cap >= capacity_pair_.value) {
2111 return _NEFORCE
move(result);
2122 NEFORCE_DEBUG_VERIFY(off <=
size(),
"basic_string index out of ranges.");
2156 NEFORCE_DEBUG_VERIFY(off <=
size(),
"basic_string index out of ranges.");
2169 NEFORCE_DEBUG_VERIFY(position <=
size(),
"basic_string copy position out of range");
2193 return view(off, n).compare(other.
view());
2215 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
int compare(
const CharT* str)
const noexcept {
2259 for (
size_type i = 0; i < min_len; ++i) {
2263 return (lc < rc) ? -1 : 1;
2295 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2296 return replace_copy(
begin() + position, n, other.
data(), other.
size());
2301 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2302 "basic_string replace iterator out of ranges.");
2303 return replace_copy(first, last - first, other.
data(), other.
size());
2308 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2314 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2315 "basic_string replace iterator out of ranges.");
2322 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2323 return replace_copy({
data() + position,
this}, n1, str, n2);
2328 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2329 "basic_string replace iterator out of ranges.");
2330 return replace_copy(first, last - first, str, n);
2336 NEFORCE_DEBUG_VERIFY(position <
size(),
"basic_string index out of ranges.");
2337 return replace_fill({
data() + position,
this}, n1, n2, value);
2343 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2344 "basic_string replace iterator out of ranges.");
2345 return replace_fill(first,
static_cast<size_type>(last - first), n, value);
2351 NEFORCE_DEBUG_VERIFY(position1 <
size(),
"basic_string index out of ranges.");
2352 NEFORCE_DEBUG_VERIFY(position2 <
size(),
"basic_string index out of ranges.");
2353 return replace_copy({
data() + position1,
this}, n1, str.
data() + position2, n2);
2357 template <
typename Iterator>
2359 NEFORCE_DEBUG_VERIFY(
begin() <= first && last <=
end() && first <= last,
2360 "basic_string replace iterator out of ranges.");
2361 return replace_copy(first, last, first2, last2);
2407 const size_type off = 0) const noexcept {
2447 const size_type off = 0) const noexcept {
2453 const size_type off = 0) const noexcept {
2465 const size_type off = 0) const noexcept {
2477 const size_type off = 0) const noexcept {
2519 const size_type off = 0) const noexcept {
2525 const size_type off = 0) const noexcept {
2537 const size_type off = 0) const noexcept {
2549 const size_type off = 0) const noexcept {
2591 const size_type off = 0) const noexcept {
2603 const size_type off = 0) const noexcept {
2620 const size_type position = 0) const noexcept {
2623 if (*(
data() + idx) == value) {
2652 const size_type other_size = other.size();
2653 return other_size <=
size() &&
2711 template <
typename Pred>
2718 while (it !=
end() && pred(*it)) {
2721 if (it !=
begin()) {
2734 template <
typename Pred>
2741 while (rit !=
rend() && pred(*rit)) {
2762 while (it !=
end() && cs.contains(*it)) {
2765 if (it !=
begin()) {
2783 while (rit !=
rend() && cs.contains(*rit)) {
2806 template <
typename Predicate>
2820 const bool skip_empty =
true)
const {
2830 if (delimiters.
empty()) {
2840 if (!skip_empty || !token.
empty()) {
2847 const auto last_token =
tail(start);
2848 if (!skip_empty || !last_token.empty()) {
2862 const bool skip_empty =
true)
const {
2872 if (delimiters.
empty()) {
2882 if (!skip_empty || !token.
empty()) {
2889 const auto last_token =
tail(start);
2890 if (!skip_empty || !last_token.empty()) {
2911 size_t total_length = 0;
2912 for (
const auto& s: vec) {
2913 total_length += s.length();
2915 total_length += delimiter.
length() * (vec.
size() - 1);
2920 for (
size_t i = 0; i < vec.
size(); ++i) {
2922 result.
append(delimiter);
2944 size_t total_length = 0;
2945 for (
const auto& s: vec) {
2946 total_length += s.length();
2948 total_length += delimiter.
length() * (vec.
size() - 1);
2953 for (
size_t i = 0; i < vec.
size(); ++i) {
2955 result.
append(delimiter);
2986 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal_to(
const CharT* str)
const noexcept {
3031 if (_NEFORCE
addressof(other) ==
this) {
3034#ifdef NEFORCE_USING_SSO
3035 _NEFORCE
swap(storage_, other.storage_);
3036 _NEFORCE
swap(size_pair_, other.size_pair_);
3038 _NEFORCE
swap(data_, other.data_);
3039 _NEFORCE
swap(size_, other.size_);
3040 _NEFORCE
swap(capacity_pair_, other.capacity_pair_);
3050 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
size_t to_hash() const noexcept {
3051 const size_t byte_len =
length() *
sizeof(CharT);
3052#ifdef NEFORCE_ARCH_BITS_64
3053 return static_cast<size_t>(_NEFORCE
XXH64(
data(), byte_len));
3055 return static_cast<size_t>(_NEFORCE
XXH32(
data(), byte_len));
3060#ifdef NEFORCE_STANDARD_17
3061template <
typename Iterator,
typename Alloc = allocator<iter_value_t<Iterator>>>
3062basic_string(Iterator, Iterator, Alloc = Alloc())
3063 -> basic_string<iter_value_t<Iterator>, char_traits<iter_value_t<Iterator>>, Alloc>;
3065template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
3066explicit basic_string(basic_string_view<CharT, Traits>,
const Alloc& = Alloc()) -> basic_string<CharT, Traits, Alloc>;
3068template <
typename CharT,
typename Traits,
typename Alloc = allocator<CharT>>
3069basic_string(basic_string_view<CharT, Traits>,
typename allocator_traits<Alloc>::size_type,
3070 typename allocator_traits<Alloc>::size_type,
const Alloc& = Alloc()) -> basic_string<CharT, Traits, Alloc>;
3073template <
typename CharT,
typename Traits,
typename Alloc>
3074NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc> operator+(
const basic_string<CharT, Traits, Alloc>& lhs,
3075 const basic_string<CharT, Traits, Alloc>& rhs) {
3076 basic_string<CharT, Traits, Alloc> tmp(lhs);
3078 return _NEFORCE move(tmp);
3081template <
typename CharT,
typename Traits,
typename Alloc>
3082NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const CharT* lhs,
3083 const basic_string<CharT, Traits, Alloc>& rhs) {
3084 basic_string<CharT, Traits, Alloc> tmp(lhs);
3086 return _NEFORCE
move(tmp);
3088template <
typename CharT,
typename Traits,
typename Alloc>
3089NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const basic_string<CharT, Traits, Alloc>& lhs,
3091 basic_string<CharT, Traits, Alloc> tmp(lhs);
3093 return _NEFORCE
move(tmp);
3096template <
typename CharT,
typename Traits,
typename Alloc>
3097NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const basic_string_view<CharT, Traits>& lhs,
3098 const basic_string<CharT, Traits, Alloc>& rhs) {
3099 basic_string<CharT, Traits, Alloc> tmp(lhs);
3101 return _NEFORCE
move(tmp);
3103template <
typename CharT,
typename Traits,
typename Alloc>
3104NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const basic_string<CharT, Traits, Alloc>& lhs,
3105 const basic_string_view<CharT, Traits>& rhs) {
3106 basic_string<CharT, Traits, Alloc> tmp(lhs);
3108 return _NEFORCE
move(tmp);
3111template <
typename CharT,
typename Traits,
typename Alloc>
3112NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(CharT lhs,
3113 const basic_string<CharT, Traits, Alloc>& rhs) {
3114 basic_string<CharT, Traits, Alloc> tmp(1, lhs);
3116 return _NEFORCE
move(tmp);
3118template <
typename CharT,
typename Traits,
typename Alloc>
3119NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const basic_string<CharT, Traits, Alloc>& lhs,
3121 basic_string<CharT, Traits, Alloc> tmp(lhs);
3123 return _NEFORCE
move(tmp);
3126template <
typename CharT,
typename Traits,
typename Alloc>
3127NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(basic_string<CharT, Traits, Alloc>&& lhs,
3128 const basic_string<CharT, Traits, Alloc>& rhs) {
3129 return _NEFORCE
move(lhs.append(rhs));
3131template <
typename CharT,
typename Traits,
typename Alloc>
3132NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const basic_string<CharT, Traits, Alloc>& lhs,
3133 basic_string<CharT, Traits, Alloc>&& rhs) {
3134 basic_string<CharT, Traits, Alloc> tmp(lhs);
3135 tmp.append(_NEFORCE
move(rhs));
3136 return _NEFORCE
move(tmp);
3139template <
typename CharT,
typename Traits,
typename Alloc>
3140NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(basic_string<CharT, Traits, Alloc>&& lhs,
3141 basic_string<CharT, Traits, Alloc>&& rhs) {
3142 basic_string<CharT, Traits, Alloc> tmp(_NEFORCE
move(lhs));
3144 tmp.append(_NEFORCE
move(rhs));
3148 return _NEFORCE
move(tmp);
3151template <
typename CharT,
typename Traits,
typename Alloc>
3152NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(
const CharT* lhs,
3153 basic_string<CharT, Traits, Alloc>&& rhs) {
3154 basic_string<CharT, Traits, Alloc> tmp(lhs);
3155 tmp.append(_NEFORCE
move(rhs));
3156 return _NEFORCE
move(tmp);
3158template <
typename CharT,
typename Traits,
typename Alloc>
3159NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(basic_string<CharT, Traits, Alloc>&& lhs,
3161 return _NEFORCE
move(lhs.append(rhs));
3164template <
typename CharT,
typename Traits,
typename Alloc>
3165NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(CharT lhs, basic_string<CharT, Traits, Alloc>&& rhs) {
3166 basic_string<CharT, Traits, Alloc> tmp(1, lhs);
3167 tmp.append(_NEFORCE
move(rhs));
3168 return _NEFORCE
move(tmp);
3170template <
typename CharT,
typename Traits,
typename Alloc>
3171NEFORCE_CONSTEXPR20 basic_string<CharT, Traits, Alloc>
operator+(basic_string<CharT, Traits, Alloc>&& lhs, CharT rhs) {
3172 return _NEFORCE
move(lhs.append(rhs));
3175template <
typename CharT,
typename Traits,
typename Alloc>
3176NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const CharT*
const lhs,
3177 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3178 return rhs.equal_to(lhs);
3180template <
typename CharT,
typename Traits,
typename Alloc>
3181NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const basic_string<CharT, Traits, Alloc>& lhs,
3182 const CharT*
const rhs)
noexcept {
3183 return lhs.equal_to(rhs);
3185template <
typename CharT,
typename Traits,
typename Alloc>
3186NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const basic_string_view<CharT, Traits>& lhs,
3187 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3188 return rhs.equal_to(lhs);
3190template <
typename CharT,
typename Traits,
typename Alloc>
3191NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator==(
const basic_string<CharT, Traits, Alloc>& lhs,
3192 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3193 return lhs.equal_to(rhs);
3196template <
typename CharT,
typename Traits,
typename Alloc>
3197NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const CharT*
const lhs,
3198 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3199 return !(lhs == rhs);
3201template <
typename CharT,
typename Traits,
typename Alloc>
3202NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const basic_string<CharT, Traits, Alloc>& lhs,
3203 const CharT*
const rhs)
noexcept {
3204 return !(lhs == rhs);
3206template <
typename CharT,
typename Traits,
typename Alloc>
3207NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const basic_string_view<CharT, Traits>& lhs,
3208 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3209 return !(lhs == rhs);
3211template <
typename CharT,
typename Traits,
typename Alloc>
3212NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator!=(
const basic_string<CharT, Traits, Alloc>& lhs,
3213 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3214 return !(lhs == rhs);
3217template <
typename CharT,
typename Traits,
typename Alloc>
3218NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const CharT*
const lhs,
3219 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3220 return 0 < rhs.compare(lhs);
3222template <
typename CharT,
typename Traits,
typename Alloc>
3223NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const basic_string<CharT, Traits, Alloc>& lhs,
3224 const CharT*
const rhs)
noexcept {
3225 return lhs.compare(rhs) < 0;
3227template <
typename CharT,
typename Traits,
typename Alloc>
3228NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const basic_string_view<CharT, Traits>& lhs,
3229 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3230 return 0 < rhs.compare(lhs);
3232template <
typename CharT,
typename Traits,
typename Alloc>
3233NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<(
const basic_string<CharT, Traits, Alloc>& lhs,
3234 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3235 return lhs.compare(rhs) < 0;
3238template <
typename CharT,
typename Traits,
typename Alloc>
3239NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const CharT*
const lhs,
3240 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3243template <
typename CharT,
typename Traits,
typename Alloc>
3244NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const basic_string<CharT, Traits, Alloc>& lhs,
3245 const CharT*
const rhs)
noexcept {
3248template <
typename CharT,
typename Traits,
typename Alloc>
3249NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const basic_string_view<CharT, Traits>& lhs,
3250 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3253template <
typename CharT,
typename Traits,
typename Alloc>
3254NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>(
const basic_string<CharT, Traits, Alloc>& lhs,
3255 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3259template <
typename CharT,
typename Traits,
typename Alloc>
3260NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const CharT*
const lhs,
3261 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3262 return !(lhs > rhs);
3264template <
typename CharT,
typename Traits,
typename Alloc>
3265NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const basic_string<CharT, Traits, Alloc>& lhs,
3266 const CharT*
const rhs)
noexcept {
3267 return !(lhs > rhs);
3269template <
typename CharT,
typename Traits,
typename Alloc>
3270NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const basic_string_view<CharT, Traits>& lhs,
3271 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3272 return !(lhs > rhs);
3274template <
typename CharT,
typename Traits,
typename Alloc>
3275NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator<=(
const basic_string<CharT, Traits, Alloc>& lhs,
3276 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3277 return !(lhs > rhs);
3280template <
typename CharT,
typename Traits,
typename Alloc>
3281NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const CharT*
const lhs,
3282 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3283 return !(rhs < lhs);
3285template <
typename CharT,
typename Traits,
typename Alloc>
3286NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const basic_string<CharT, Traits, Alloc>& lhs,
3287 const CharT*
const rhs)
noexcept {
3288 return !(rhs < lhs);
3290template <
typename CharT,
typename Traits,
typename Alloc>
3291NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const basic_string_view<CharT, Traits>& lhs,
3292 const basic_string<CharT, Traits, Alloc>& rhs)
noexcept {
3293 return !(rhs < lhs);
3295template <
typename CharT,
typename Traits,
typename Alloc>
3296NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool operator>=(
const basic_string<CharT, Traits, Alloc>& lhs,
3297 const basic_string_view<CharT, Traits>& rhs)
noexcept {
3298 return !(rhs < lhs);
3301#ifndef NEFORCE_STANDARD_17
3302# ifdef NEFORCE_USING_SSO
3303template <
typename CharT,
typename Traits,
typename Alloc>
3304constexpr size_t basic_string<CharT, Traits, Alloc>::sso_buffer_bytes;
3305template <
typename CharT,
typename Traits,
typename Alloc>
3306constexpr size_t basic_string<CharT, Traits, Alloc>::sso_buffer_size;
3307template <
typename CharT,
typename Traits,
typename Alloc>
3308constexpr size_t basic_string<CharT, Traits, Alloc>::sso_capacity;
3309template <
typename CharT,
typename Traits,
typename Alloc>
3310constexpr size_t basic_string<CharT, Traits, Alloc>::long_flag;
3312template <
typename CharT,
typename Traits,
typename Alloc>
3313constexpr size_t basic_string<CharT, Traits, Alloc>::npos;
3317#ifndef NEFORCE_COMPILER_CLANG_CL
3318extern template class basic_string<char>;
3319extern template class basic_string<wchar_t>;
3320# ifdef NEFORCE_STANDARD_20
3321extern template class basic_string<char8_t>;
3323extern template class basic_string<char16_t>;
3324extern template class basic_string<char32_t>;
3329NEFORCE_END_NAMESPACE__
constexpr size_type length() const noexcept
获取字符串长度
constexpr bool empty() const noexcept
检查是否为空
static constexpr auto npos
constexpr view_type view() const noexcept
constexpr basic_string & assign(const basic_string &other)
赋值另一个字符串
constexpr basic_string & replace(iterator first, iterator last, const basic_string &other)
替换迭代器范围为另一个字符串
constexpr basic_string(view_type view, const size_type n)
从字符串视图构造(指定长度)
constexpr bool ends_with(const_pointer str) const noexcept
检查是否以C风格字符串结尾
constexpr basic_string(const basic_string &other, size_type position, size_type n)
从子串构造(指定长度)
constexpr size_type length() const noexcept
获取字符串长度
basic_string_iterator< false, basic_string > iterator
迭代器类型
constexpr basic_string repeat(size_type n) const noexcept
重复当前字符串n次
constexpr basic_string & append(view_type view, size_type n)
追加字符串视图的指定长度
constexpr size_type rfind(const CharT *str, const size_type off, const size_type n) const noexcept
从后向前查找指定长度的子串
constexpr basic_string & assign(const view_type &view)
赋值字符串视图
constexpr iterator end() noexcept
constexpr size_type rfind(const CharT value, const size_type n=npos) const noexcept
从后向前查找字符
constexpr basic_string & operator=(std::initializer_list< value_type > ilist)
初始化列表赋值运算符
constexpr void swap(basic_string &other) noexcept
交换两个字符串
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr bool starts_with(view_type view) const noexcept
检查是否以字符串视图开头
constexpr size_type find_first_not_of(const charset &cs, const size_type off=0) const noexcept
查找第一个不在 charset 中的字符
constexpr basic_string & replace(const size_type position, const size_type n1, const_pointer str, const size_type n2)
替换子串为指定长度的字符数组
ptrdiff_t difference_type
差值类型
constexpr size_type max_size() const noexcept
获取最大可能大小
constexpr const_reference front() const noexcept
常量访问第一个字符
constexpr basic_string & append(const basic_string &other, size_type position)
追加另一个字符串的子串
constexpr basic_string & append(const basic_string &other, size_type position, size_type n)
追加另一个字符串的子串
constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
constexpr basic_string & operator=(const basic_string &other)
拷贝赋值运算符
constexpr basic_string & replace(const size_type position, const size_type n, const basic_string &other)
替换子串为另一个字符串
constexpr size_type rfind(const CharT *str, const size_type off=npos) const noexcept
从后向前查找C风格字符串
constexpr basic_string(const basic_string &other, size_type position)
从子串构造
constexpr basic_string & trim_right() noexcept
去除右侧空白字符
constexpr void resize(size_type n, value_type value)
调整大小
constexpr pointer data() noexcept
获取数据指针
constexpr void pop_back() noexcept
删除末尾字符
constexpr basic_string lowercase() const
转换为小写
constexpr basic_string(const basic_string &other)
拷贝构造函数
constexpr size_type rfind(const view_type &view, const size_type off=npos) const noexcept
从后向前查找字符串视图
constexpr int compare(const basic_string &other) const noexcept
比较另一个字符串
constexpr basic_string & trim() noexcept
去除两侧空白字符
constexpr int compare_ignore_case(const_pointer str) const noexcept
忽略大小写比较另一个字符串
constexpr basic_string(basic_string &&other) noexcept
移动构造函数
constexpr bool ends_with(view_type view) const noexcept
检查是否以字符串视图结尾
constexpr basic_string & replace(iterator first, iterator last, const_pointer str)
替换迭代器范围为C风格字符串
constexpr const_reference operator[](const size_type n) const noexcept
常量下标访问操作符
constexpr size_type find_first_of(const charset &cs, const size_type off=0) const noexcept
查找第一个出现在 charset 中的字符
constexpr size_type find(const CharT *str, const size_type off=0) const noexcept
查找C风格字符串
constexpr iterator insert(iterator position, Iterator first, Iterator last)
插入迭代器范围
constexpr size_type find(const CharT value, const size_type n=0) const noexcept
查找字符
constexpr bool contains(value_type value) const noexcept
检查是否包含指定字符
constexpr int compare(const size_type off, const size_type n, const CharT *str, size_type count) const
比较子串与指定长度的字符数组
constexpr basic_string & uppercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_uppercase< CharT >)))
转换为大写
constexpr bool equal_to(const CharT *str) const noexcept
与C风格字符串相等比较
constexpr int compare(const view_type &view) const noexcept
比较字符串视图
constexpr size_type find(const basic_string &other, const size_type n=0) const noexcept
查找子串
constexpr basic_string & assign(std::initializer_list< value_type > ilist)
赋值初始化列表
constexpr basic_string & trim_if(const charset &cs) noexcept
根据 charset 去除两侧字符
constexpr void push_back(value_type value)
在末尾插入字符
constexpr basic_string & assign(const_pointer str, const size_type n)
赋值字符数组的指定长度
constexpr basic_string & append(Iterator first, Iterator last)
追加迭代器范围
constexpr basic_string substr(const size_type off=0, const size_type count=npos) const
获取子串
constexpr size_type find_last_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个不在指定字符数组中的字符
constexpr basic_string & replace(const size_type position, const size_type n, const_pointer str)
替换子串为C风格字符串
constexpr const_reference at(const size_type n) const noexcept
带边界检查的常量访问
constexpr size_type find_last_not_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个不等于指定字符的位置
constexpr iterator begin() noexcept
constexpr bool ends_with(const basic_string &other) const noexcept
检查是否以另一个字符串结尾
constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
constexpr basic_string & operator+=(view_type view)
追加字符串视图
constexpr basic_string(size_type n, int64_t value)
构造函数,指定大小和64位整数值
constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
constexpr size_type find_last_of(const charset &cs, const size_type off=npos) const noexcept
查找最后一个出现在 charset 中的字符
constexpr void shrink_to_fit()
收缩容量以适应当前大小
constexpr basic_string & replace(iterator first, iterator last, const_pointer str, const size_type n)
替换迭代器范围为指定长度的字符数组
const CharT * const_pointer
常量指针类型
constexpr const_reference back() const noexcept
常量访问最后一个字符
constexpr basic_string(view_type view)
从字符串视图构造
constexpr basic_string & operator+=(const basic_string &other)
追加另一个字符串
constexpr basic_string & assign(const_pointer str)
赋值C风格字符串
constexpr int compare_ignore_case(const view_type view) const noexcept
忽略大小写三路比较
constexpr size_type copy(pointer dest, const size_type count, size_type position=0) const
复制字符到目标缓冲区
constexpr size_type find_first_not_of(const CharT value, const size_type off=0) const noexcept
查找第一个不等于指定字符的位置
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() noexcept
去除左侧空白字符
constexpr iterator insert(iterator position, value_type value)
constexpr basic_string & trim_left_if(Pred pred)
constexpr bool starts_with(const basic_string &other) const noexcept
检查是否以另一个字符串开头
constexpr size_type find_last_not_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个不在C风格字符串中的字符
constexpr basic_string & trim_right_if(Pred pred)
constexpr basic_string & trim_left_if(const charset &cs) noexcept
根据 charset 去除左侧字符
constexpr size_type rfind(const view_type &view, const size_type off, const size_type count) const noexcept
从后向前查找指定长度的字符串视图
constexpr bool empty() const noexcept
检查是否为空
constexpr basic_string(size_type n, int32_t value)
构造函数,指定大小和32位整数值
constexpr basic_string & append(value_type value)
追加单个字符
constexpr bool contains(view_type view) const noexcept
检查是否包含字符串视图
constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
constexpr size_type find_first_not_of(const CharT *str, const size_type off=0) const noexcept
查找第一个不在C风格字符串中的字符
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
constexpr const_reverse_iterator crend() const noexcept
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
constexpr basic_string & append(size_type n, value_type value)
constexpr iterator erase(iterator position) noexcept
删除指定位置的字符
constexpr size_type find_last_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找最后一个不在字符串视图中的字符
constexpr size_type find_last_of(const CharT value, const size_type off=npos) const noexcept
查找最后一个等于指定字符的位置
constexpr int compare(const size_type off, const size_type n, const CharT *str) const
比较子串与C风格字符串
constexpr size_type find_first_not_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个不在字符集合中的字符
constexpr const_iterator cbegin() const noexcept
basic_string_view< CharT, Traits > view_type
字符串视图类型
constexpr basic_string(Iterator first, Iterator last)
从迭代器范围构造
constexpr basic_string & operator+=(std::initializer_list< value_type > ilist)
追加初始化列表
constexpr size_type find_last_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 & assign(const size_type n, value_type value)
赋值多个相同字符
constexpr vector< basic_string > split(const charset &delimiters, const bool skip_empty=true) const
使用 charset 分割字符串
constexpr reference back() noexcept
访问最后一个字符
constexpr size_type find_first_of(const view_type &view, const size_type off=0) const noexcept
查找第一个出现在字符串视图中的字符
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_last_not_of(const charset &cs, const size_type off=npos) const noexcept
查找最后一个不在 charset 中的字符
constexpr bool equal_to(const view_type view) const noexcept
与字符串视图相等比较
constexpr basic_string & assign(basic_string &&other)
赋值移动字符串
constexpr size_type find_first_not_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个不在字符串视图中的字符
constexpr basic_string & operator=(view_type view)
字符串视图赋值运算符
constexpr bool contains(const basic_string &other) const noexcept
检查是否包含另一个字符串
constexpr basic_string & operator+=(const value_type value)
追加单个字符
constexpr size_type find_first_not_of(const view_type &view, const size_type off=0) const noexcept
查找第一个不在字符串视图中的字符
Alloc allocator_type
分配器类型
constexpr size_type capacity() const noexcept
获取容量
constexpr basic_string & operator+=(const_pointer str)
追加C风格字符串
constexpr basic_string & erase(size_type position=0, size_type n=npos) noexcept
删除指定范围内的字符
constexpr const_iterator end() const noexcept
获取常量结束迭代器
constexpr basic_string(size_type n, value_type value)
构造函数,指定大小和填充字符
constexpr const_reverse_iterator crbegin() const noexcept
constexpr basic_string & append(const basic_string &other)
追加另一个字符串
constexpr basic_string & trim_if(Predicate pred)
根据谓词去除两侧字符
constexpr size_type size() const noexcept
获取字符数
constexpr size_type find_first_of(const view_type &view, const size_type off, const size_type n) const noexcept
查找第一个出现在字符串视图中的字符
constexpr basic_string()
默认构造函数
constexpr size_type find_last_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个出现在字符串视图中的字符
constexpr basic_string head(const size_type count=npos) const
获取头部子串
constexpr size_type count(value_type value, const size_type position=0) const noexcept
constexpr basic_string & lowercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_lowercase< CharT >)))
转换为小写
constexpr basic_string(std::initializer_list< value_type > ilist)
从初始化列表构造
constexpr size_type find(const view_type &view, const size_type off, const size_type count) const noexcept
查找指定长度的字符串视图
constexpr iterator erase(iterator first, iterator last) noexcept
删除迭代器范围
const CharT & const_reference
常量引用类型
basic_string_iterator< true, basic_string > const_iterator
常量迭代器类型
constexpr size_type find_first_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个出现在指定字符数组中的字符
constexpr basic_string & append(basic_string &&other)
追加移动字符串
constexpr size_type find_first_not_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找第一个不在指定字符数组中的字符
constexpr basic_string & append(view_type view)
追加字符串视图
constexpr iterator erase(iterator first, const size_type n) 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 view_type view(const size_type off, size_type count=npos) const noexcept
获取子串视图
constexpr bool starts_with(const_pointer str) const noexcept
检查是否以C风格字符串开头
constexpr size_type find_last_of(const CharT *str, const size_type off, const size_type n) const noexcept
查找最后一个出现在指定字符数组中的字符
constexpr bool starts_with(const value_type value) const noexcept
检查是否以指定字符开头
static constexpr size_type npos
constexpr void resize(const size_type n)
调整大小(默认填充0)
constexpr size_type find_first_of(const CharT value, const size_type off=0) const noexcept
查找第一个等于指定字符的位置
constexpr size_type find_last_of(const CharT *str, const size_type off=npos) const noexcept
查找最后一个出现在C风格字符串中的字符
static constexpr basic_string join(const vector< view_type > &vec, const view_type delimiter)
连接字符串视图
constexpr const_iterator begin() const noexcept
获取常量起始迭代器
constexpr reference at(const size_type n) noexcept
带边界检查的访问
constexpr basic_string & replace(const size_type position, const size_type n1, const size_type n2, const value_type value)
替换子串为多个相同字符
constexpr basic_string & append(const_pointer str)
追加C风格字符串
constexpr void reverse() noexcept
反转字符串
constexpr basic_string & assign(Iterator first, Iterator last)
赋值迭代器范围
constexpr vector< basic_string > split(const view_type delimiters, const bool skip_empty=true) const
分割字符串
constexpr basic_string(size_type n)
构造函数,指定大小
constexpr size_type find_first_of(const CharT *str, const size_type off=0) const noexcept
查找第一个出现在C风格字符串中的字符
constexpr basic_string & operator=(basic_string &&other) noexcept
移动赋值运算符
constexpr int compare_ignore_case(const basic_string &str) const noexcept
忽略大小写与C风格字符串三路比较
constexpr size_type rfind(const basic_string &other, const size_type off=npos) const noexcept
从后向前查找子串
constexpr bool contains(const_pointer str) const noexcept
检查是否包含C风格字符串
constexpr basic_string & append(basic_string &&other, size_type position, size_type n)
追加移动字符串的子串
constexpr const_pointer data() const noexcept
获取常量数据指针
constexpr basic_string & replace(iterator first, iterator last, const size_type n, const value_type value)
替换迭代器范围为多个相同字符
constexpr size_type find_last_not_of(const basic_string &other, const size_type off=npos) const noexcept
查找最后一个不在字符集合中的字符
constexpr bool equal_to(const basic_string &other) const noexcept
相等比较
constexpr reference operator[](const size_type n) noexcept
下标访问操作符
constexpr basic_string & replace(iterator first, iterator last, Iterator first2, Iterator last2)
替换迭代器范围为另一个迭代器范围
constexpr basic_string & operator=(const_pointer str)
C风格字符串赋值运算符
constexpr basic_string & operator+=(basic_string &&other)
追加移动字符串
constexpr size_type find(const view_type &view, const size_type off=0) const noexcept
查找字符串视图
constexpr basic_string & append(std::initializer_list< value_type > ilist)
追加初始化列表
constexpr basic_string(const_pointer str)
从C风格字符串构造
constexpr size_type find_first_of(const basic_string &other, const size_type off=0) const noexcept
查找第一个出现在字符集合中的字符
constexpr size_type find(const CharT *str, const size_type off, const size_type count) const noexcept
查找指定长度的子串
constexpr basic_string & trim_right_if(const charset &cs) noexcept
根据 charset 去除右侧字符
constexpr ~basic_string()
析构函数
constexpr void clear() noexcept
constexpr bool ends_with(value_type value) const noexcept
检查是否以指定字符结尾
constexpr size_type find_last_not_of(const view_type &view, const size_type off=npos) const noexcept
查找最后一个不在字符串视图中的字符
static constexpr basic_string join(const vector< basic_string > &vec, const view_type delimiter)
连接字符串
constexpr void reserve(const size_type n)
预留容量
constexpr basic_string & append(basic_string &&other, size_type position)
追加移动字符串的子串
constexpr int compare(const CharT *str) const noexcept
比较C风格字符串
constexpr int compare(const size_type off, const size_type n, const basic_string &other) const
比较子串与另一个字符串
constexpr basic_string tail(const size_type off=0) const
获取尾部子串
constexpr basic_string uppercase() const
转换为大写
constexpr const_iterator cend() const noexcept
constexpr reference front() noexcept
访问第一个字符
constexpr basic_string & append(const_pointer str, size_type n)
追加字符数组的指定长度
constexpr basic_string & insert(size_type position, size_type n, value_type value)
在指定位置插入多个相同字符
static constexpr charset ascii_space() noexcept
ASCII 空白字符集
constexpr bool empty() const noexcept
检查字符集是否为空
constexpr bool empty() const noexcept
检查是否为空
constexpr size_type size() const noexcept
获取当前元素数量
constexpr void push_back(const T &value)
在末尾拷贝插入元素
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_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_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_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(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_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 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 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_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_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 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 const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
constexpr T clamp(const T &value, const T &lower, const T &upper, Compare comp) noexcept(noexcept(comp(value, lower)))
将值限制在指定范围内
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
constexpr uint32_t XXH32(const void *input, size_t len, uint32_t seed=0) noexcept
XXH32 哈希算法
constexpr uint64_t XXH64(const void *input, size_t len, uint64_t seed=0) noexcept
XXH64 哈希算法
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr normal_iterator< Iterator > operator+(iter_difference_t< normal_iterator< Iterator > > n, const normal_iterator< Iterator > &iter) noexcept
加法运算符
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
constexpr Iterator2 replace_copy(Iterator1 first, Iterator1 last, Iterator2 result, const T &old_value, const T &new_value)
替换并复制元素
constexpr Iterator2 transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op) noexcept(noexcept(++first) &&noexcept(++result) &&noexcept(*result=op(*first)))
对范围元素应用一元变换
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器
constexpr bool is_trivial_v
is_trivial的便捷变量模板
constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr Iterator2 uninitialized_copy_n(Iterator1 first, size_t count, Iterator2 result)
复制指定数量的元素到未初始化内存
constexpr Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
static constexpr char_type * assign(char_type *const str, const size_t count, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值
static 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 size_t length(const char_type *str) noexcept
计算字符串长度
static constexpr char_type * copy(char_type *dest, const char_type *srcs, const size_t count) noexcept
复制字符序列
static constexpr bool eq(const char_type lhs, const char_type rhs) noexcept
相等比较
typename container_type::difference_type difference_type
差值类型
typename container_type::value_type value_type
值类型
constexpr difference_type distance_to(const basic_string_iterator &other) const noexcept
计算距离操作
constexpr bool less_than(const basic_string_iterator &rhs) const noexcept
小于比较
constexpr pointer base() const noexcept
获取底层指针
constexpr void increment() noexcept
递增操作
constexpr void decrement() noexcept
递减操作
constexpr reference operator[](difference_type n) const noexcept
下标访问操作符
constexpr void advance(difference_type off) noexcept
前进操作
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
constexpr bool equal_to(const basic_string_iterator &rhs) const noexcept
相等比较
contiguous_iterator_tag iterator_category
迭代器类别
typename container_type::size_type size_type
大小类型
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
constexpr reference dereference() const noexcept
解引用操作
String container_type
容器类型
constexpr const container_type * container() const noexcept
获取关联容器
constexpr compressed_pair & get_base() &noexcept
获取基类引用