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
14NEFORCE_BEGIN_NAMESPACE__
15
21
31template <typename CharT, typename IntT>
33 using char_type = CharT;
34 using int_type = IntT;
35
36 static_assert(sizeof(int_type) >= sizeof(char_type),
37 "int_type must be able to represent all char_type values plus EOF");
38
46 static constexpr char_type* copy(char_type* dest, const char_type* srcs, const size_t count) noexcept {
47 _NEFORCE memory_copy(dest, srcs, count * sizeof(char_type));
48 return dest;
49 }
50
58 static constexpr char_type* move(char_type* dest, const char_type* srcs, const size_t count) noexcept {
59 _NEFORCE memory_move(dest, srcs, count * sizeof(char_type));
60 return dest;
61 }
62
70 NEFORCE_NODISCARD static constexpr int compare(const char_type* lhs, const char_type* rhs, size_t count) noexcept {
71 return _NEFORCE string_compare(lhs, rhs, count);
72 }
73
79 NEFORCE_NODISCARD static constexpr size_t length(const char_type* str) noexcept {
80 return _NEFORCE string_length(str);
81 }
82
90 NEFORCE_NODISCARD static constexpr const char_type* find(const char_type* str, const size_t count,
91 const char_type target) noexcept {
92 return _NEFORCE string_find<char_type>(str, target, count);
93 }
94
102 static constexpr char_type* assign(char_type* const str, const size_t count, const char_type chr) noexcept {
103 return _NEFORCE string_set<char_type>(str, chr, count);
104 }
105
111 static constexpr void assign(char_type& lhs, const char_type rhs) noexcept { lhs = rhs; }
112
119 NEFORCE_NODISCARD static constexpr bool eq(const char_type lhs, const char_type rhs) noexcept { return lhs == rhs; }
120
127 NEFORCE_NODISCARD static constexpr bool lt(const char_type lhs, const char_type rhs) noexcept { return lhs < rhs; }
128
134 NEFORCE_NODISCARD static constexpr int_type not_eof(const int_type rsc) noexcept {
135 return rsc == eof() ? static_cast<int_type>(0) : rsc;
136 }
137
142 NEFORCE_NODISCARD static constexpr int_type eof() noexcept { return static_cast<int_type>(-1); }
143};
144
153template <typename CharT, typename IntT>
154struct narrow_char_traits : private base_char_traits<CharT, IntT> {
155 static_assert(sizeof(CharT) == sizeof(byte_t), "size of CharT must be the same as byte type");
156
157private:
158 using base_type = base_char_traits<CharT, IntT>;
159
160public:
161 using char_type = CharT;
162 using int_type = IntT;
163
164 using base_type::copy;
165 using base_type::eof;
166 using base_type::eq;
167 using base_type::length;
168 using base_type::lt;
169 using base_type::move;
170 using base_type::not_eof;
171
172public:
180 NEFORCE_NODISCARD static constexpr int compare(const char_type* lhs, const char_type* rhs,
181 const size_t n) noexcept {
182 return _NEFORCE memory_compare(lhs, rhs, n);
183 }
184
192 NEFORCE_NODISCARD static constexpr const char_type* find(const char_type* str, const size_t n,
193 const char_type chr) noexcept {
194 return static_cast<const char_type*>(_NEFORCE memory_find(str, chr, n));
195 }
196
204 static constexpr char_type* assign(char_type* str, size_t n, const char_type chr) noexcept {
205 return static_cast<char_type*>(_NEFORCE memory_set(str, chr, n));
206 }
207
213 static constexpr void assign(char_type& lhs, const char_type& rhs) noexcept { lhs = rhs; }
214};
215
216
224template <typename CharT>
225struct char_traits : base_char_traits<CharT, int64_t> {};
226
228template <>
229struct char_traits<char> : narrow_char_traits<char, int32_t> {};
230
232template <>
233struct char_traits<wchar_t> : base_char_traits<wchar_t, uint32_t> {};
234
235#if defined(NEFORCE_STANDARD_20) || defined(NEXUSFORCE_ENABLE_DOXYGEN)
237template <>
238struct char_traits<char8_t> : narrow_char_traits<char8_t, uint32_t> {};
239#endif
240
242template <>
243struct char_traits<char16_t> : base_char_traits<char16_t, uint32_t> {};
244
246template <>
247struct char_traits<char32_t> : base_char_traits<char32_t, uint32_t> {};
248
249
254template <typename Traits>
255using char_traits_char_t = typename Traits::char_type;
256
261template <typename Traits>
262using char_traits_ptr_t = const typename Traits::char_type*;
263
264
266NEFORCE_BEGIN_INNER__
267
276template <typename CharT, bool IsChar = is_character_v<CharT>>
277class __string_bitmap {
278private:
279 bool matches_[numeric_traits<byte_t>::max() + 1] = {};
280
281public:
285 constexpr __string_bitmap() = default;
286
293 constexpr bool mark(const CharT* first, const CharT* const last) noexcept {
294 for (; first != last; ++first) {
295 matches_[static_cast<byte_t>(*first)] = true;
296 }
297 return true;
298 }
299
305 constexpr bool match(const CharT chr) const noexcept { return matches_[static_cast<byte_t>(chr)]; }
306};
307
308template <typename CharT>
309class __string_bitmap<CharT, false> {};
310
311NEFORCE_END_INNER__
313
323template <typename Traits>
324constexpr bool char_traits_equal(const char_traits_ptr_t<Traits> lhs, const size_t lh_size,
325 const char_traits_ptr_t<Traits> rhs, const size_t rh_size) noexcept {
326 if (lh_size != rh_size) {
327 return false;
328 }
329 if (lh_size == 0u) {
330 return true;
331 }
332
333 return Traits::compare(lhs, rhs, lh_size) == 0;
334}
335
345template <typename Traits>
346constexpr int char_traits_compare(const char_traits_ptr_t<Traits> lhs, const size_t lh_size,
347 const char_traits_ptr_t<Traits> rhs, const size_t rh_size) noexcept {
348 const int state = Traits::compare(lhs, rhs, _NEFORCE min(lh_size, rh_size));
349 if (state != 0) {
350 return state;
351 }
352
353 if (lh_size < rh_size) {
354 return -1;
355 }
356 if (lh_size > rh_size) {
357 return 1;
358 }
359 return 0;
360}
361
372template <typename Traits>
373constexpr size_t char_traits_find(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
374 const char_traits_ptr_t<Traits> rsc, const size_t rsc_size) noexcept {
375 if (rsc_size > dest_size || start > dest_size - rsc_size) {
376 return static_cast<size_t>(-1);
377 }
378 if (rsc_size == 0) {
379 return start;
380 }
381
382 const auto may_match_end = dest + (dest_size - rsc_size) + 1;
383 for (auto if_match = dest + start;; ++if_match) {
384 if_match = Traits::find(if_match, static_cast<size_t>(may_match_end - if_match), *rsc);
385 if (!if_match) {
386 return static_cast<size_t>(-1);
387 }
388
389 if (Traits::compare(if_match, rsc, rsc_size) == 0) {
390 return static_cast<size_t>(if_match - dest);
391 }
392 }
393}
394
404template <typename Traits>
405constexpr size_t char_traits_find_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
406 const char_traits_char_t<Traits> chr) noexcept {
407 if (start < dest_size) {
408 const auto found = Traits::find(dest + start, dest_size - start, chr);
409 if (found) {
410 return static_cast<size_t>(found - dest);
411 }
412 }
413 return static_cast<size_t>(-1);
414}
415
426template <typename Traits>
427constexpr size_t char_traits_rfind(const char_traits_ptr_t<Traits> dest, const size_t dest_size, const size_t start,
428 const char_traits_ptr_t<Traits> rsc, const size_t rsc_size) noexcept {
429 if (rsc_size == 0) {
430 return _NEFORCE min(start, dest_size);
431 }
432
433 if (rsc_size <= dest_size) {
434 for (auto if_match = dest + _NEFORCE min(start, dest_size - rsc_size);; --if_match) {
435 if (Traits::eq(*if_match, *rsc) && Traits::compare(if_match, rsc, rsc_size) == 0) {
436 return static_cast<size_t>(if_match - dest);
437 }
438
439 if (if_match == dest) {
440 break;
441 }
442 }
443 }
444 return static_cast<size_t>(-1);
445}
446
456template <typename Traits>
457constexpr size_t char_traits_rfind_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
458 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
459 if (dest_size != 0) {
460 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
461 if (Traits::eq(*if_match, chr)) {
462 return static_cast<size_t>(if_match - dest);
463 }
464
465 if (if_match == dest) {
466 break;
467 }
468 }
469 }
470 return static_cast<size_t>(-1);
471}
472
483template <typename Traits, enable_if_t<
484#ifdef NEFORCE_STANDARD_17
486#else
488#endif
489 ,
490 int> = 0>
491constexpr size_t char_traits_find_first_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
492 const size_t start, const char_traits_ptr_t<Traits> rsc,
493 const size_t rsc_size) noexcept {
494 if (rsc_size != 0 && start < dest_size) {
495 inner::__string_bitmap<char_traits_char_t<Traits>> match;
496 if (!match.mark(rsc, rsc + rsc_size)) {
497 return (char_traits_find_first_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
498 }
499 const auto end = dest + dest_size;
500 for (auto if_match = dest + start; if_match < end; ++if_match) {
501 if (match.match(*if_match)) {
502 return static_cast<size_t>(if_match - dest);
503 }
504 }
505 }
506 return static_cast<size_t>(-1);
507}
508
519template <typename Traits, enable_if_t<
520#ifdef NEFORCE_STANDARD_17
522#else
524#endif
525 ,
526 int> = 0>
527constexpr size_t char_traits_find_first_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
528 const size_t start, const char_traits_ptr_t<Traits> rsc,
529 const size_t rsc_size) noexcept {
530 if (rsc_size != 0 && start < dest_size) {
531 const auto end = dest + dest_size;
532 for (auto if_match = dest + start; if_match < end; ++if_match) {
533 if (Traits::find(rsc, rsc_size, *if_match)) {
534 return static_cast<size_t>(if_match - dest);
535 }
536 }
537 }
538 return static_cast<size_t>(-1);
539}
540
551template <typename Traits, enable_if_t<
552#ifdef NEFORCE_STANDARD_17
554#else
556#endif
557 ,
558 int> = 0>
559constexpr size_t char_traits_find_last_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
560 const size_t start, const char_traits_ptr_t<Traits> rsc,
561 const size_t rsc_size) noexcept {
562 if (rsc_size != 0 && dest_size != 0) {
563 inner::__string_bitmap<char_traits_char_t<Traits>> match;
564 if (!match.mark(rsc, rsc + rsc_size)) {
565 return (char_traits_find_last_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
566 }
567
568 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
569 if (match.match(*if_match)) {
570 return static_cast<size_t>(if_match - dest);
571 }
572
573 if (if_match == dest) {
574 break;
575 }
576 }
577 }
578 return static_cast<size_t>(-1);
579}
580
591template <typename Traits, enable_if_t<
592#ifdef NEFORCE_STANDARD_17
594#else
596#endif
597 ,
598 int> = 0>
599constexpr size_t char_traits_find_last_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
600 const size_t start, const char_traits_ptr_t<Traits> rsc,
601 const size_t rsc_size) noexcept {
602 if (rsc_size != 0 && dest_size != 0) {
603 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
604 if (Traits::find(rsc, rsc_size, *if_match)) {
605 return static_cast<size_t>(if_match - dest);
606 }
607
608 if (if_match == dest) {
609 break;
610 }
611 }
612 }
613 return static_cast<size_t>(-1);
614}
615
626template <typename Traits, enable_if_t<
627#ifdef NEFORCE_STANDARD_17
629#else
631#endif
632 ,
633 int> = 0>
634constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
635 const size_t start, const char_traits_ptr_t<Traits> rsc,
636 const size_t rsc_size) noexcept {
637 if (start < dest_size) {
638 inner::__string_bitmap<char_traits_char_t<Traits>> match;
639 if (!match.mark(rsc, rsc + rsc_size)) {
640 return (char_traits_find_first_not_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
641 }
642
643 const auto end = dest + dest_size;
644 for (auto if_match = dest + start; if_match < end; ++if_match) {
645 if (!match.match(*if_match)) {
646 return static_cast<size_t>(if_match - dest);
647 }
648 }
649 }
650 return static_cast<size_t>(-1);
651}
652
663template <typename Traits, enable_if_t<
664#ifdef NEFORCE_STANDARD_17
666#else
668#endif
669 ,
670 int> = 0>
671constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
672 const size_t start, const char_traits_ptr_t<Traits> rsc,
673 const size_t rsc_size) noexcept {
674 if (start < dest_size) {
675 const auto end = dest + dest_size;
676 for (auto if_match = dest + start; if_match < end; ++if_match) {
677 if (!Traits::find(rsc, rsc_size, *if_match)) {
678 return static_cast<size_t>(if_match - dest);
679 }
680 }
681 }
682 return static_cast<size_t>(-1);
683}
684
694template <typename Traits>
695constexpr size_t char_traits_find_not_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
696 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
697 if (start < dest_size) {
698 const auto end = dest + dest_size;
699 for (auto if_match = dest + start; if_match < end; ++if_match) {
700 if (!Traits::eq(*if_match, chr)) {
701 return static_cast<size_t>(if_match - dest);
702 }
703 }
704 }
705 return static_cast<size_t>(-1);
706}
707
718template <typename Traits, enable_if_t<
719#ifdef NEFORCE_STANDARD_17
721#else
723#endif
724 ,
725 int> = 0>
726constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
727 const size_t start, const char_traits_ptr_t<Traits> rsc,
728 const size_t rsc_size) noexcept {
729 if (dest_size != 0) {
730 inner::__string_bitmap<char_traits_char_t<Traits>> match;
731 if (!match.mark(rsc, rsc + rsc_size)) {
732 return (char_traits_find_last_not_of<Traits, false>) (dest, dest_size, start, rsc, rsc_size);
733 }
734
735 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
736 if (!match.match(*if_match)) {
737 return static_cast<size_t>(if_match - dest);
738 }
739
740 if (if_match == dest) {
741 break;
742 }
743 }
744 }
745 return static_cast<size_t>(-1);
746}
747
758template <typename Traits, enable_if_t<
759#ifdef NEFORCE_STANDARD_17
761#else
763#endif
764 ,
765 int> = 0>
766constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
767 const size_t start, const char_traits_ptr_t<Traits> rsc,
768 const size_t rsc_size) noexcept {
769 if (dest_size != 0) {
770 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
771 if (!Traits::find(rsc, rsc_size, *if_match)) {
772 return static_cast<size_t>(if_match - dest);
773 }
774
775 if (if_match == dest) {
776 break;
777 }
778 }
779 }
780 return static_cast<size_t>(-1);
781}
782
792template <typename Traits>
793constexpr size_t char_traits_rfind_not_char(const char_traits_ptr_t<Traits> dest, const size_t dest_size,
794 const size_t start, const char_traits_char_t<Traits> chr) noexcept {
795 if (dest_size != 0) {
796 for (auto if_match = dest + _NEFORCE min(start, dest_size - 1);; --if_match) {
797 if (!Traits::eq(*if_match, chr)) {
798 return static_cast<size_t>(if_match - dest);
799 }
800
801 if (if_match == dest) {
802 break;
803 }
804 }
805 }
806 return static_cast<size_t>(-1);
807}
808 // CharTraits
810
811#define __NEFORCE_BUILD_CHAR_PTR_HASH(OPT) \
812 template <> \
813 struct hash<OPT*> { \
814 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
815 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
816 } \
817 }; \
818 template <> \
819 struct hash<const OPT*> { \
820 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
821 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
822 } \
823 }; \
824 template <size_t N> \
825 struct hash<OPT[N]> { \
826 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
827 return FNV_hash_string(str, N - 1); \
828 } \
829 }; \
830 template <size_t N> \
831 struct hash<const OPT[N]> { \
832 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
833 return FNV_hash_string(str, N - 1); \
834 } \
835 };
836
837NEFORCE_MACRO_RANGE_CHARS(__NEFORCE_BUILD_CHAR_PTR_HASH)
838#undef __NEFORCE_BUILD_CHAR_PTR_HASH
839
840NEFORCE_END_NAMESPACE__
841#endif // NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
static NEFORCE_NODISCARD 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)
统计范围内等于指定值的元素数量
NEFORCE_CONSTEXPR14 void * memory_copy(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 const void * memory_find(const void *dest, const byte_t value, size_t count) noexcept
在内存中搜索特定字节
NEFORCE_CONSTEXPR14 void * memory_move(void *dest, const void *src, size_t count) noexcept
从源内存移动数据到目标内存
NEFORCE_CONSTEXPR14 void * memory_set(void *dest, const byte_t value, size_t count) noexcept
使用指定字节填充内存区域
NEFORCE_PURE_FUNCTION constexpr size_t string_length(const CharT *str) noexcept
计算字符串长度
NEFORCE_PURE_FUNCTION constexpr const CharT * string_find(const CharT *str, const CharT chr) noexcept
查找字符在字符串中首次出现的位置
NEFORCE_PURE_FUNCTION constexpr int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
NEFORCE_INLINE17 constexpr bool is_specialization_v
is_specialization的便捷变量模板
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE 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 NEFORCE_NODISCARD constexpr bool eq(const char_type lhs, const char_type rhs) noexcept
相等比较
static constexpr char_type * assign(char_type *const str, const size_t count, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值
CharT char_type
字符类型
static NEFORCE_NODISCARD constexpr int_type eof() noexcept
返回EOF值
static NEFORCE_NODISCARD constexpr bool lt(const char_type lhs, const char_type rhs) noexcept
小于比较
static NEFORCE_NODISCARD constexpr int compare(const char_type *lhs, const char_type *rhs, size_t count) noexcept
比较两个字符序列
static constexpr char_type * move(char_type *dest, const char_type *srcs, const size_t count) noexcept
移动字符序列
static constexpr char_type * copy(char_type *dest, const char_type *srcs, const size_t count) noexcept
复制字符序列
static NEFORCE_NODISCARD constexpr int_type not_eof(const int_type rsc) noexcept
如果不是EOF则返回原值,否则返回0
static NEFORCE_NODISCARD constexpr size_t length(const char_type *str) noexcept
计算字符串长度
IntT int_type
整数类型
static NEFORCE_NODISCARD constexpr const char_type * find(const char_type *str, const size_t count, const char_type target) noexcept
在字符序列中查找指定字符
static constexpr void assign(char_type &lhs, const char_type rhs) noexcept
赋值单个字符
字符特征模板
窄字符特征模板
static constexpr void assign(char_type &lhs, const char_type &rhs) noexcept
赋值单个字符
CharT char_type
字符类型
static NEFORCE_NODISCARD 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
将字符序列中的每个字符设置为指定值(内存优化版本)
static NEFORCE_NODISCARD constexpr const char_type * find(const char_type *str, const size_t n, const char_type chr) noexcept
在字符序列中查找指定字符(内存优化版本)
IntT int_type
整数类型