NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
char_traits.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
2#define NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
3
12
15NEFORCE_BEGIN_NAMESPACE__
16
22
32template <typename CharT, typename IntT>
34 using char_type = CharT;
35 using int_type = IntT;
36
37 static_assert(sizeof(int_type) >= sizeof(char_type),
38 "int_type must be able to represent all char_type values plus EOF");
39
47 static constexpr char_type* copy(char_type* dest, const char_type* srcs, const size_t count) noexcept {
48 _NEFORCE memory_copy(dest, srcs, count * sizeof(char_type));
49 return dest;
50 }
51
59 static constexpr char_type* move(char_type* dest, const char_type* srcs, const size_t count) noexcept {
60 _NEFORCE memory_move(dest, srcs, count * sizeof(char_type));
61 return dest;
62 }
63
71 NEFORCE_NODISCARD static constexpr int compare(const char_type* lhs, const char_type* rhs, size_t count) noexcept {
72 return _NEFORCE string_compare(lhs, rhs, count);
73 }
74
80 NEFORCE_NODISCARD static constexpr size_t length(const char_type* str) noexcept {
81 return _NEFORCE string_length(str);
82 }
83
91 NEFORCE_NODISCARD static constexpr const char_type* find(const char_type* str, const size_t count,
92 const char_type target) noexcept {
93 return _NEFORCE string_find<char_type>(str, target, count);
94 }
95
103 static constexpr char_type* assign(char_type* const str, const size_t count, const char_type chr) noexcept {
104 return _NEFORCE string_set<char_type>(str, chr, count);
105 }
106
112 static constexpr void assign(char_type& lhs, const char_type rhs) noexcept { lhs = rhs; }
113
120 NEFORCE_NODISCARD static constexpr bool eq(const char_type lhs, const char_type rhs) noexcept { return lhs == rhs; }
121
128 NEFORCE_NODISCARD static constexpr bool lt(const char_type lhs, const char_type rhs) noexcept { return lhs < rhs; }
129
135 NEFORCE_NODISCARD static constexpr int_type not_eof(const int_type rsc) noexcept {
136 return rsc == eof() ? static_cast<int_type>(0) : rsc;
137 }
138
143 NEFORCE_NODISCARD static constexpr int_type eof() noexcept { return static_cast<int_type>(-1); }
144};
145
154template <typename CharT, typename IntT>
155struct narrow_char_traits : private base_char_traits<CharT, IntT> {
156 static_assert(sizeof(CharT) == sizeof(byte_t), "size of CharT must be the same as byte type");
157
158private:
159 using base_type = base_char_traits<CharT, IntT>;
160
161public:
162 using char_type = CharT;
163 using int_type = IntT;
164
165 using base_type::copy;
166 using base_type::eof;
167 using base_type::eq;
168 using base_type::length;
169 using base_type::lt;
170 using base_type::move;
171 using base_type::not_eof;
172
173public:
181 NEFORCE_NODISCARD static constexpr int compare(const char_type* lhs, const char_type* rhs,
182 const size_t n) noexcept {
183 return _NEFORCE memory_compare(lhs, rhs, n);
184 }
185
193 NEFORCE_NODISCARD static constexpr const char_type* find(const char_type* str, const size_t n,
194 const char_type chr) noexcept {
195 return static_cast<const char_type*>(_NEFORCE memory_find(str, chr, n));
196 }
197
205 static constexpr char_type* assign(char_type* str, size_t n, const char_type chr) noexcept {
206 return static_cast<char_type*>(_NEFORCE memory_set(str, chr, n));
207 }
208
214 static constexpr void assign(char_type& lhs, const char_type& rhs) noexcept { lhs = rhs; }
215};
216
217
225template <typename CharT>
226struct char_traits : base_char_traits<CharT, int64_t> {};
227
229template <>
230struct char_traits<char> : narrow_char_traits<char, int32_t> {};
231
233template <>
234struct char_traits<wchar_t> : base_char_traits<wchar_t, uint32_t> {};
235
236#ifdef NEFORCE_STANDARD_20
238template <>
239struct char_traits<char8_t> : narrow_char_traits<char8_t, uint32_t> {};
240#endif
241
243template <>
244struct char_traits<char16_t> : base_char_traits<char16_t, uint32_t> {};
245
247template <>
248struct char_traits<char32_t> : base_char_traits<char32_t, uint32_t> {};
249
250
255template <typename Traits>
256using char_traits_char_t = typename Traits::char_type;
257
262template <typename Traits>
263using char_traits_ptr_t = const typename Traits::char_type*;
264
265
267NEFORCE_BEGIN_INNER__
268
277template <typename CharT, bool IsChar = is_character_v<CharT>>
278class __string_bitmap {
279private:
280 bool matches_[numeric_traits<byte_t>::max() + 1] = {};
281
282public:
286 constexpr __string_bitmap() = default;
287
294 constexpr bool mark(const CharT* first, const CharT* const last) noexcept {
295 for (; first != last; ++first) {
296 matches_[static_cast<byte_t>(*first)] = true;
297 }
298 return true;
299 }
300
306 constexpr bool match(const CharT chr) const noexcept { return matches_[static_cast<byte_t>(chr)]; }
307};
308
309template <typename CharT>
310class __string_bitmap<CharT, false> {};
311
312NEFORCE_END_INNER__
314
324template <typename Traits>
325constexpr bool char_traits_equal(const char_traits_ptr_t<Traits> lhs, const size_t lh_size,
326 const char_traits_ptr_t<Traits> rhs, const size_t rh_size) noexcept {
327 if (lh_size != rh_size) {
328 return false;
329 }
330 if (lh_size == 0U) {
331 return true;
332 }
333
334 return Traits::compare(lhs, rhs, lh_size) == 0;
335}
336
346template <typename Traits>
347constexpr int char_traits_compare(const char_traits_ptr_t<Traits> lhs, const size_t lh_size,
348 const char_traits_ptr_t<Traits> rhs, const size_t rh_size) noexcept {
349 const int state = Traits::compare(lhs, rhs, _NEFORCE min(lh_size, rh_size));
350 if (state != 0) {
351 return state;
352 }
353
354 if (lh_size < rh_size) {
355 return -1;
356 }
357 if (lh_size > rh_size) {
358 return 1;
359 }
360 return 0;
361}
362
373template <typename Traits>
374constexpr size_t char_traits_find(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
375 const char_traits_ptr_t<Traits> rsc, const size_t rsc_size) noexcept {
376 if (rsc_size > dest_size || start > dest_size - rsc_size) {
377 return static_cast<size_t>(-1);
378 }
379 if (rsc_size == 0) {
380 return start;
381 }
382
383 const auto may_match_end = dest + (dest_size - rsc_size) + 1;
384 for (auto if_match = dest + start;; ++if_match) {
385 if_match = Traits::find(if_match, static_cast<size_t>(may_match_end - if_match), *rsc);
386 if (!if_match) {
387 return static_cast<size_t>(-1);
388 }
389
390 if (Traits::compare(if_match, rsc, rsc_size) == 0) {
391 return static_cast<size_t>(if_match - dest);
392 }
393 }
394}
395
405template <typename Traits>
406constexpr size_t char_traits_find_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
407 const char_traits_char_t<Traits> chr) noexcept {
408 if (start < dest_size) {
409 const auto found = Traits::find(dest + start, dest_size - start, chr);
410 if (found) {
411 return static_cast<size_t>(found - dest);
412 }
413 }
414 return static_cast<size_t>(-1);
415}
416
427template <typename Traits>
428constexpr size_t char_traits_rfind(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
429 const char_traits_ptr_t<Traits> rsc, const size_t rsc_size) noexcept {
430 if (rsc_size == 0) {
431 return _NEFORCE min(start, dest_size);
432 }
433
434 if (rsc_size <= dest_size) {
435 for (auto if_match = dest + _NEFORCE min(start, dest_size - rsc_size);; --if_match) {
436 if (Traits::eq(*if_match, *rsc) && Traits::compare(if_match, rsc, rsc_size) == 0) {
437 return static_cast<size_t>(if_match - dest);
438 }
439
440 if (if_match == dest) {
441 break;
442 }
443 }
444 }
445 return static_cast<size_t>(-1);
446}
447
457template <typename Traits>
458constexpr size_t char_traits_rfind_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
459 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
460 if (dest_size != 0) {
461 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
462 if (Traits::eq(*if_match, chr)) {
463 return static_cast<size_t>(if_match - dest);
464 }
465
466 if (if_match == dest) {
467 break;
468 }
469 }
470 }
471 return static_cast<size_t>(-1);
472}
473
484template <typename Traits, enable_if_t<
485#ifdef NEFORCE_STANDARD_17
487#else
489#endif
490 ,
491 int> = 0>
492constexpr size_t char_traits_find_first_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
493 const size_t start, const char_traits_ptr_t<Traits> rsc,
494 const size_t rsc_size) noexcept {
495 if (rsc_size != 0 && start < dest_size) {
496 inner::__string_bitmap<char_traits_char_t<Traits>> match;
497 if (!match.mark(rsc, rsc + rsc_size)) {
498 return (char_traits_find_first_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
499 }
500 const auto end = dest + dest_size;
501 for (auto if_match = dest + start; if_match < end; ++if_match) {
502 if (match.match(*if_match)) {
503 return static_cast<size_t>(if_match - dest);
504 }
505 }
506 }
507 return static_cast<size_t>(-1);
508}
509
520template <typename Traits, enable_if_t<
521#ifdef NEFORCE_STANDARD_17
523#else
525#endif
526 ,
527 int> = 0>
528constexpr size_t char_traits_find_first_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
529 const size_t start, const char_traits_ptr_t<Traits> rsc,
530 const size_t rsc_size) noexcept {
531 if (rsc_size != 0 && start < dest_size) {
532 const auto end = dest + dest_size;
533 for (auto if_match = dest + start; if_match < end; ++if_match) {
534 if (Traits::find(rsc, rsc_size, *if_match)) {
535 return static_cast<size_t>(if_match - dest);
536 }
537 }
538 }
539 return static_cast<size_t>(-1);
540}
541
552template <typename Traits, enable_if_t<
553#ifdef NEFORCE_STANDARD_17
555#else
557#endif
558 ,
559 int> = 0>
560constexpr size_t char_traits_find_last_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
561 const size_t start, const char_traits_ptr_t<Traits> rsc,
562 const size_t rsc_size) noexcept {
563 if (rsc_size != 0 && dest_size != 0) {
564 inner::__string_bitmap<char_traits_char_t<Traits>> match;
565 if (!match.mark(rsc, rsc + rsc_size)) {
566 return (char_traits_find_last_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
567 }
568
569 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
570 if (match.match(*if_match)) {
571 return static_cast<size_t>(if_match - dest);
572 }
573
574 if (if_match == dest) {
575 break;
576 }
577 }
578 }
579 return static_cast<size_t>(-1);
580}
581
592template <typename Traits, enable_if_t<
593#ifdef NEFORCE_STANDARD_17
595#else
597#endif
598 ,
599 int> = 0>
600constexpr size_t char_traits_find_last_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
601 const size_t start, const char_traits_ptr_t<Traits> rsc,
602 const size_t rsc_size) noexcept {
603 if (rsc_size != 0 && dest_size != 0) {
604 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
605 if (Traits::find(rsc, rsc_size, *if_match)) {
606 return static_cast<size_t>(if_match - dest);
607 }
608
609 if (if_match == dest) {
610 break;
611 }
612 }
613 }
614 return static_cast<size_t>(-1);
615}
616
627template <typename Traits, enable_if_t<
628#ifdef NEFORCE_STANDARD_17
630#else
632#endif
633 ,
634 int> = 0>
635constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
636 const size_t start, const char_traits_ptr_t<Traits> rsc,
637 const size_t rsc_size) noexcept {
638 if (start < dest_size) {
639 inner::__string_bitmap<char_traits_char_t<Traits>> match;
640 if (!match.mark(rsc, rsc + rsc_size)) {
641 return (char_traits_find_first_not_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
642 }
643
644 const auto end = dest + dest_size;
645 for (auto if_match = dest + start; if_match < end; ++if_match) {
646 if (!match.match(*if_match)) {
647 return static_cast<size_t>(if_match - dest);
648 }
649 }
650 }
651 return static_cast<size_t>(-1);
652}
653
664template <typename Traits, enable_if_t<
665#ifdef NEFORCE_STANDARD_17
667#else
669#endif
670 ,
671 int> = 0>
672constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
673 const size_t start, const char_traits_ptr_t<Traits> rsc,
674 const size_t rsc_size) noexcept {
675 if (start < dest_size) {
676 const auto end = dest + dest_size;
677 for (auto if_match = dest + start; if_match < end; ++if_match) {
678 if (!Traits::find(rsc, rsc_size, *if_match)) {
679 return static_cast<size_t>(if_match - dest);
680 }
681 }
682 }
683 return static_cast<size_t>(-1);
684}
685
695template <typename Traits>
696constexpr size_t char_traits_find_not_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
697 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
698 if (start < dest_size) {
699 const auto end = dest + dest_size;
700 for (auto if_match = dest + start; if_match < end; ++if_match) {
701 if (!Traits::eq(*if_match, chr)) {
702 return static_cast<size_t>(if_match - dest);
703 }
704 }
705 }
706 return static_cast<size_t>(-1);
707}
708
719template <typename Traits, enable_if_t<
720#ifdef NEFORCE_STANDARD_17
722#else
724#endif
725 ,
726 int> = 0>
727constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
728 const size_t start, const char_traits_ptr_t<Traits> rsc,
729 const size_t rsc_size) noexcept {
730 if (dest_size != 0) {
731 inner::__string_bitmap<char_traits_char_t<Traits>> match;
732 if (!match.mark(rsc, rsc + rsc_size)) {
733 return (char_traits_find_last_not_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
734 }
735
736 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
737 if (!match.match(*if_match)) {
738 return static_cast<size_t>(if_match - dest);
739 }
740
741 if (if_match == dest) {
742 break;
743 }
744 }
745 }
746 return static_cast<size_t>(-1);
747}
748
759template <typename Traits, enable_if_t<
760#ifdef NEFORCE_STANDARD_17
762#else
764#endif
765 ,
766 int> = 0>
767constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
768 const size_t start, const char_traits_ptr_t<Traits> rsc,
769 const size_t rsc_size) noexcept {
770 if (dest_size != 0) {
771 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
772 if (!Traits::find(rsc, rsc_size, *if_match)) {
773 return static_cast<size_t>(if_match - dest);
774 }
775
776 if (if_match == dest) {
777 break;
778 }
779 }
780 }
781 return static_cast<size_t>(-1);
782}
783
793template <typename Traits>
794constexpr size_t char_traits_rfind_not_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
795 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
796 if (dest_size != 0) {
797 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
798 if (!Traits::eq(*if_match, chr)) {
799 return static_cast<size_t>(if_match - dest);
800 }
801
802 if (if_match == dest) {
803 break;
804 }
805 }
806 }
807 return static_cast<size_t>(-1);
808}
809 // CharTraits
811
812#define __NEFORCE_BUILD_CHAR_PTR_HASH(OPT) \
813 template <> \
814 struct hash<OPT*> { \
815 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
816 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
817 } \
818 }; \
819 template <> \
820 struct hash<const OPT*> { \
821 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
822 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
823 } \
824 }; \
825 template <size_t N> \
826 struct hash<OPT[N]> { \
827 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
828 return FNV_hash_string(str, N - 1); \
829 } \
830 }; \
831 template <size_t N> \
832 struct hash<const OPT[N]> { \
833 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
834 return FNV_hash_string(str, N - 1); \
835 } \
836 };
837
838NEFORCE_MACRO_RANGE_CHARS(__NEFORCE_BUILD_CHAR_PTR_HASH)
839#undef __NEFORCE_BUILD_CHAR_PTR_HASH
840
841NEFORCE_END_NAMESPACE__
842#endif // NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
static constexpr T max() noexcept
获取类型的最大值
比较算法
const typename Traits::char_type * char_traits_ptr_t
获取字符特征中的字符指针类型
typename Traits::char_type char_traits_char_t
获取字符特征中的字符类型
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 const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
unsigned char byte_t
字节类型,定义为无符号字符
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
constexpr const void * memory_find(const void *dest, const byte_t value, size_t count) noexcept
在内存中搜索特定字节
constexpr void * memory_set(void *dest, const byte_t value, size_t count) noexcept
使用指定字节填充内存区域
constexpr void * memory_move(void *dest, const void *src, size_t count) noexcept
从源内存移动数据到目标内存
constexpr void * memory_copy(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
constexpr int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
constexpr size_t string_length(const CharT *str) noexcept
计算字符串长度
constexpr const CharT * string_find(const CharT *str, const CharT chr) noexcept
查找字符在字符串中首次出现的位置
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
constexpr bool is_specialization_v
is_specialization的便捷变量模板
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
#define NEFORCE_MACRO_RANGE_CHARS(MAC)
所有字符类型列表宏
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
数值特征
基础字符特征模板
static constexpr int_type not_eof(const int_type rsc) noexcept
如果不是EOF则返回原值,否则返回0
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
将字符序列中的每个字符设置为指定值
CharT char_type
字符类型
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 int_type eof() noexcept
返回EOF值
static constexpr const char_type * find(const char_type *str, const size_t count, const char_type target) noexcept
在字符序列中查找指定字符
IntT int_type
整数类型
static constexpr size_t length(const char_type *str) noexcept
计算字符串长度
static constexpr void assign(char_type &lhs, const char_type rhs) noexcept
赋值单个字符
static constexpr bool lt(const char_type lhs, const char_type rhs) noexcept
小于比较
字符特征模板
窄字符特征模板
static constexpr void assign(char_type &lhs, const char_type &rhs) noexcept
赋值单个字符
static constexpr const char_type * find(const char_type *str, const size_t n, const char_type chr) noexcept
在字符序列中查找指定字符(内存优化版本)
CharT char_type
字符类型
static constexpr int compare(const char_type *lhs, const char_type *rhs, const size_t n) noexcept
比较两个字符序列(内存优化版本)
static constexpr char_type * assign(char_type *str, size_t n, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值(内存优化版本)
IntT int_type
整数类型