MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
memory.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_MEMORY_MEMORY_HPP__
2#define MSTL_CORE_MEMORY_MEMORY_HPP__
3
11
14
20
29MSTL_CONSTEXPR14 void*
30memory_copy(void* MSTL_RESTRICT dest, const void* MSTL_RESTRICT src, size_t count) noexcept {
31 if (dest == nullptr || src == nullptr) return nullptr;
32 if (count == 0) return dest;
33
34 void* res = dest;
35 auto dest_v = static_cast<volatile byte_t*>(dest);
36 auto src_v = static_cast<const volatile byte_t*>(src);
37 while (count--) {
38 *dest_v = *src_v;
39 dest_v++;
40 src_v++;
41 }
42 return res;
43}
44
53template <typename T>
54MSTL_CONSTEXPR14 void*
55memory_copy(T* MSTL_RESTRICT dest, const T* MSTL_RESTRICT src) noexcept {
56 return _MSTL memory_copy(dest, src, sizeof(T));
57}
58
67MSTL_CONSTEXPR14 void*
68memory_copy_offset(void* MSTL_RESTRICT dest, const void* MSTL_RESTRICT src, size_t count) noexcept {
69 if (dest == nullptr || src == nullptr) return nullptr;
70
71 auto dest_v = static_cast<volatile byte_t*>(dest);
72 auto src_v = static_cast<const volatile byte_t*>(src);
73 while (count--) {
74 *dest_v = *src_v;
75 dest_v++;
76 src_v++;
77 }
78 return (void*) dest_v;
79}
80
89MSTL_CONSTEXPR14 void*
90memory_copy_until(void* dest, const void* src, const byte_t value, size_t count) noexcept {
91 if (dest == nullptr || src == nullptr) return nullptr;
92
93 auto dest_v = static_cast<volatile byte_t*>(dest);
94 auto src_v = static_cast<const volatile byte_t*>(src);
95
96 while (count--) {
97 const byte_t current = *src_v;
98 *dest_v = current;
99 if (current == value) {
100 return (void*) (++dest_v);
101 }
102 dest_v++;
103 src_v++;
104 }
105 return nullptr;
106}
107
118MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 int
119memory_compare(const void* lhs, const void* rhs, size_t count) noexcept {
120 if (lhs == nullptr && rhs == nullptr) return 0;
121 if (lhs == nullptr) return -1;
122 if (rhs == nullptr) return 1;
123
124 while (count--) {
125 if (*static_cast<const byte_t*>(lhs) != *static_cast<const byte_t*>(rhs))
126 return *static_cast<const byte_t*>(lhs) - *static_cast<const byte_t*>(rhs);
127 lhs = static_cast<const byte_t*>(lhs) + 1;
128 rhs = static_cast<const byte_t*>(rhs) + 1;
129 }
130 return 0;
131}
132
143template <typename T>
144MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 int
145memory_compare(const T& lhs, const T& rhs) noexcept {
146 return _MSTL memory_compare(&lhs, &rhs, sizeof(T));
147}
148
157MSTL_CONSTEXPR14 void*
158memory_move(void* dest, const void* src, size_t count) noexcept {
159 if(dest == nullptr || src == nullptr) return nullptr;
160
161 void* res = dest;
162 auto dest_v = static_cast<volatile byte_t*>(dest);
163 auto src_v = static_cast<const volatile byte_t*>(src);
164 if (dest_v < src_v) {
165 while (count--) {
166 *dest_v = *src_v;
167 dest_v = dest_v + 1;
168 src_v = src_v + 1;
169 }
170 } else if (dest_v > src_v) {
171 while (count--) {
172 *(dest_v + count) = *(src_v + count);
173 }
174 }
175 return res;
176}
177
185MSTL_CONSTEXPR14 void*
186memory_set(void* dest, const byte_t value, size_t count) noexcept {
187 if(dest == nullptr) return nullptr;
188
189 void* ret = static_cast<byte_t*>(dest);
190 auto dest_v = static_cast<volatile byte_t*>(dest);
191 while (count--) {
192 *dest_v = value;
193 dest_v = dest_v + 1;
194 }
195 return ret;
196}
197
205MSTL_CONSTEXPR14 void memory_zero(void* dest, const size_t count) noexcept {
206 if (dest == nullptr) return;
207
208 const auto dest_v = static_cast<volatile byte_t*>(dest);
209 for (size_t i = 0; i < count; ++i) {
210 dest_v[i] = static_cast<byte_t>(0);
211 }
212}
213
221template <typename T>
222MSTL_CONSTEXPR14 void memory_zero(T* dest) noexcept {
223 _MSTL memory_zero(dest, sizeof(T));
224}
225
233MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 const void*
234memory_find(const void* dest, const byte_t value, size_t count) noexcept {
235 if(dest == nullptr) return nullptr;
236 auto p = static_cast<const byte_t*>(dest);
237 while (count--) {
238 if (*p == value) {
239 return p;
240 }
241 p++;
242 }
243 return nullptr;
244}
245
254MSTL_CONSTEXPR14 const void*
255memory_find_pattern(const void* data, const size_t data_len,
256 const void* pattern, const size_t pattern_len) noexcept {
257 if (data == nullptr || pattern == nullptr ||
258 data_len == 0 || pattern_len == 0 || pattern_len > data_len) {
259 return nullptr;
260 }
261
262 const auto data_ptr = static_cast<const byte_t*>(data);
263 const auto pattern_ptr = static_cast<const byte_t*>(pattern);
264 const size_t last_possible = data_len - pattern_len + 1;
265
266 for (size_t i = 0; i < last_possible; ++i) {
267 if (data_ptr[i] == pattern_ptr[0]) {
268 bool match = true;
269 for (size_t j = 1; j < pattern_len; ++j) {
270 if (data_ptr[i + j] != pattern_ptr[j]) {
271 match = false;
272 break;
273 }
274 }
275 if (match) {
276 return data_ptr + i;
277 }
278 }
279 }
280 return nullptr;
281}
282
293template <typename To, typename From>
294MSTL_NODISCARD MSTL_CONSTEXPR20 To
295memory_cast(const From& value) noexcept {
296 static_assert(sizeof(To) == sizeof(From), "types must have the same size");
297 static_assert(is_trivially_copyable_v<To>, "To type must be trivially copyable");
298 static_assert(is_trivially_copyable_v<From>, "From type must be trivially copyable");
299
300#ifdef MSTL_STANDARD_20__
301 return __builtin_bit_cast(To, value);
302#else
303 static_assert(is_default_constructible_v<To>, "To type must be default constructible");
304
305 To result{};
306 _MSTL memory_copy(&result, &value, sizeof(To));
307 return result;
308#endif
309}
310 // MemoryFunctions
312
318
327template <typename CharT>
328MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 CharT to_lowercase(const CharT c) noexcept {
329 static_assert(is_character_v<CharT>, "character type is necessary");
330 using UT = make_unsigned_t<CharT>;
331 const auto uc = static_cast<UT>(c);
332 if (uc >= static_cast<UT>('A') && uc <= static_cast<UT>('Z')) {
333 return static_cast<CharT>(uc | 0x20);
334 }
335 return c;
336}
337
346template <typename CharT>
347MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 CharT to_uppercase(const CharT c) noexcept {
348 static_assert(is_character_v<CharT>, "character type is necessary");
349 using UT = make_unsigned_t<CharT>;
350 const auto uc = static_cast<UT>(c);
351 if (uc >= static_cast<UT>('a') && uc <= static_cast<UT>('z')) {
352 return static_cast<CharT>(uc & 0xDF);
353 }
354 return c;
355}
356 // CharCaseConversion
358
364
376template <typename CharT>
377constexpr CharT*
378string_copy(CharT* MSTL_RESTRICT dest,
379 const CharT* MSTL_RESTRICT src) noexcept {
380 if(dest == nullptr || src == nullptr) return nullptr;
381 CharT* ret = dest;
382 while (*src != static_cast<CharT>(0)) {
383 *dest = *src;
384 ++dest;
385 ++src;
386 }
387 *dest = *src;
388 return ret;
389}
390
404template <typename CharT>
405constexpr CharT*
406string_copy(CharT* MSTL_RESTRICT dest,
407 const CharT* MSTL_RESTRICT src,
408 const size_t count) noexcept {
409 if (dest == nullptr || src == nullptr) return nullptr;
410
411 CharT* ret = dest;
412 size_t i = 0;
413 while (i < count && *src != static_cast<CharT>(0)) {
414 *dest = *src;
415 ++dest;
416 ++src;
417 i++;
418 }
419
420 while (i < count) {
421 *dest = static_cast<CharT>(0);
422 ++dest;
423 i++;
424 }
425 return ret;
426}
427
436template <typename CharT>
437constexpr CharT*
438string_copy_offset(CharT* MSTL_RESTRICT dest,
439 const CharT* MSTL_RESTRICT src) noexcept {
440 if (dest == nullptr || src == nullptr) return nullptr;
441 while (*src != static_cast<CharT>(0)) {
442 *dest = *src;
443 ++dest;
444 ++src;
445 }
446 *dest = *src;
447 return dest - 1;
448}
449
459template <typename CharT>
460constexpr CharT*
461string_copy_offset(CharT* MSTL_RESTRICT dest,
462 const CharT* MSTL_RESTRICT src,
463 const size_t count) noexcept {
464 if (dest == nullptr || src == nullptr) return nullptr;
465
466 size_t i = 0;
467 while (i < count && *src != static_cast<CharT>(0)) {
468 *dest = *src;
469 ++dest;
470 ++src;
471 i++;
472 }
473
474 while (i < count) {
475 *dest = static_cast<CharT>(0);
476 ++dest;
477 i++;
478 }
479 return dest;
480}
481
492template <typename CharT>
493MSTL_PURE_FUNCTION constexpr int
494string_compare(const CharT* dest, const CharT* src) noexcept {
495 if (dest == nullptr && src == nullptr) return 0;
496 if (dest == nullptr) return -1;
497 if (src == nullptr) return 1;
498
499 while (*dest == *src) {
500 if (*dest == static_cast<CharT>(0)) {
501 return 0;
502 }
503 ++dest;
504 ++src;
505 }
506 if (*dest > *src) return 1;
507 return -1;
508}
509
518template <typename CharT>
519MSTL_PURE_FUNCTION constexpr int
520string_compare(const CharT* dest, const CharT* src, const size_t count) noexcept {
521 if (dest == nullptr && src == nullptr) return 0;
522 if (dest == nullptr) return -1;
523 if (src == nullptr) return 1;
524
525 if (count == 0) return 0;
526 size_t i = 0;
527 while (*dest == *src &&
528 *dest != static_cast<CharT>(0) &&
529 i < count - 1) {
530 ++dest;
531 ++src;
532 ++i;
533 }
534 if (i == count - 1) return 0;
535 return *dest < *src ? -1 : *dest > *src ? 1 : 0;
536}
537
548template <typename CharT>
549MSTL_PURE_FUNCTION constexpr int
550string_compare_ignore_case(const CharT* s1, const CharT* s2) {
551 if (s1 == nullptr && s2 == nullptr) return 0;
552 if (s1 == nullptr) return -1;
553 if (s2 == nullptr) return 1;
554
555 while (*s1 && *s2) {
556 const CharT c1 = _MSTL to_lowercase(*s1);
557 const CharT c2 = _MSTL to_lowercase(*s2);
558 if (c1 < c2) return -1;
559 if (c1 > c2) return 1;
560 ++s1;
561 ++s2;
562 }
563 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
564}
565
574template <typename CharT>
575MSTL_PURE_FUNCTION constexpr int
576string_compare_ignore_case(const CharT* s1, const CharT* s2, const size_t count) noexcept {
577 if ((s1 == nullptr && s2 == nullptr) || count == 0) return 0;
578 if (s1 == nullptr) return -1;
579 if (s2 == nullptr) return 1;
580
581 size_t i = 0;
582 while (*s1 && *s2 && i < count - 1) {
583 const CharT c1 = _MSTL to_lowercase(*s1);
584 const CharT c2 = _MSTL to_lowercase(*s2);
585 if (c1 < c2) return -1;
586 if (c1 > c2) return 1;
587 ++s1;
588 ++s2;
589 ++i;
590 }
591 if (i == count - 1) return 0;
592
593 const CharT c1 = _MSTL to_lowercase(*s1);
594 const CharT c2 = _MSTL to_lowercase(*s2);
595 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
596}
597
604template <typename CharT>
605MSTL_PURE_FUNCTION constexpr size_t
606string_length(const CharT* str) noexcept {
607 static_assert(is_character_v<CharT>, "CharT must be a character");
608 if (str == nullptr) return 0;
609 const CharT* p = str;
610 while (*p != static_cast<CharT>(0)) {
611 ++p;
612 }
613 return static_cast<size_t>(p - str);
614}
615
625template <typename CharT>
626MSTL_PURE_FUNCTION constexpr size_t
627string_length(const CharT* str, const size_t max_len) noexcept {
628 const CharT* p = str;
629 ptrdiff_t len = 0;
630 while (*p != static_cast<CharT>(0) && len < max_len) {
631 ++p;
632 ++len;
633 }
634 return len;
635}
636
644template <typename CharT>
645MSTL_PURE_FUNCTION constexpr const CharT*
646string_find(const CharT* str, const CharT chr) noexcept {
647 if (str == nullptr) return nullptr;
648 while (*str != static_cast<CharT>(0)) {
649 if (*str == chr) {
650 return str;
651 }
652 ++str;
653 }
654 if (*str == chr) {
655 return str;
656 }
657 return nullptr;
658}
659
668template <typename CharT>
669MSTL_PURE_FUNCTION constexpr const CharT*
670string_find(const CharT* str, const CharT chr, const size_t count) noexcept {
671 if (str == nullptr || count == 0) return nullptr;
672
673 for (size_t i = 0; i < count; ++i) {
674 if (str[i] == chr) {
675 return str + i;
676 }
677 if (str[i] == static_cast<CharT>(0)) {
678 break;
679 }
680 }
681 return nullptr;
682}
683
691template <typename CharT>
692MSTL_PURE_FUNCTION constexpr const CharT*
693string_find_last(const CharT* str, const CharT chr) noexcept {
694 if (str == nullptr) return nullptr;
695 const CharT* last = nullptr;
696
697 while (*str != static_cast<CharT>(0)) {
698 if (*str == chr) {
699 last = str;
700 }
701 ++str;
702 }
703 return last;
704}
705
713template <typename CharT>
714MSTL_PURE_FUNCTION constexpr CharT*
715string_find_any(CharT* str, const CharT* accept) noexcept {
716 if (str == nullptr || *str == static_cast<CharT>(0) ||
717 accept == nullptr || *accept == static_cast<CharT>(0))
718 return nullptr;
719
720 while (*str != static_cast<CharT>(0)) {
721 const CharT* a = accept;
722 while (*a != static_cast<CharT>(0)) {
723 if (*str == *a) {
724 return str;
725 }
726 ++a;
727 }
728 ++str;
729 }
730 return nullptr;
731}
732
740template <typename CharT>
741MSTL_PURE_FUNCTION constexpr const CharT*
742string_find_pattern(const CharT* dest, const CharT* src) noexcept {
743 if(dest == nullptr || src == nullptr) return nullptr;
744 const CharT* cur = dest;
745 while (*cur) {
746 const CharT *str1 = cur;
747 const CharT *str2 = src;
748 while (*str1 && *str2 && *str1 == *str2) {
749 ++str1;
750 ++str2;
751 }
752 if (*str2 == static_cast<CharT>(0)) return cur;
753 ++cur;
754 }
755 return nullptr;
756}
757
765template <typename CharT>
766MSTL_PURE_FUNCTION constexpr const CharT*
767string_find_pattern_ignored_case(const CharT* dest, const CharT* src) noexcept {
768 if (dest == nullptr || src == nullptr) return nullptr;
769 if (*src == static_cast<CharT>(0)) return dest;
770
771 const CharT* cur = dest;
772 while (*cur) {
773 const CharT* str1 = cur;
774 const CharT* str2 = src;
775 while (*str1 && *str2) {
776 const CharT c1 = _MSTL to_lowercase(*str1);
777 const CharT c2 = _MSTL to_lowercase(*str2);
778 if (c1 != c2) break;
779 ++str1;
780 ++str2;
781 }
782 if (*str2 == static_cast<CharT>(0)) {
783 return cur;
784 }
785 ++cur;
786 }
787 return nullptr;
788}
789
797template <typename CharT>
798MSTL_PURE_FUNCTION constexpr size_t
799string_span_in(const CharT* str, const CharT* accept) noexcept {
800 if (str == nullptr || *str == static_cast<CharT>(0) ||
801 accept == nullptr || *accept == static_cast<CharT>(0)) {
802 return 0;
803 }
804
805 const CharT* original_str = str;
806 while (*str != static_cast<CharT>(0)) {
807 const CharT* a = accept;
808 bool found = false;
809 while (*a != static_cast<CharT>(0)) {
810 if (*str == *a) {
811 found = true;
812 break;
813 }
814 ++a;
815 }
816 if (!found) {
817 return static_cast<size_t>(str - original_str);
818 }
819 ++str;
820 }
821 return static_cast<size_t>(str - original_str);
822}
823
831template <typename CharT>
832MSTL_PURE_FUNCTION constexpr size_t
833string_span_not_in(const CharT* str, const CharT* reject) noexcept {
834 if (str == nullptr || *str == static_cast<CharT>(0)) return 0;
835 if (reject == nullptr || *reject == static_cast<CharT>(0)) {
836 size_t len = 0;
837 while (str[len] != static_cast<CharT>(0)) ++len;
838 return len;
839 }
840
841 const CharT* original_str = str;
842 while (*str != static_cast<CharT>(0)) {
843 const CharT* r = reject;
844 while (*r != static_cast<CharT>(0)) {
845 if (*str == *r) {
846 return static_cast<size_t>(str - original_str);
847 }
848 ++r;
849 }
850 ++str;
851 }
852 return static_cast<size_t>(str - original_str);
853}
854
862template <typename CharT>
863constexpr CharT*
864string_set(CharT* str, const CharT value) noexcept {
865 if (str == nullptr) return nullptr;
866 CharT* original = str;
867 while (*str != static_cast<CharT>(0)) {
868 *str = value;
869 ++str;
870 }
871 return original;
872}
873
882template <typename CharT>
883constexpr CharT*
884string_set(CharT* str, const CharT value, const size_t count) noexcept {
885 if (str == nullptr || count == 0) return str;
886 CharT* original = str;
887 size_t processed = 0;
888 while (*str != static_cast<CharT>(0) && processed < count) {
889 *str = value;
890 ++str;
891 ++processed;
892 }
893 return original;
894}
895
902template <typename CharT>
903constexpr CharT*
904string_reverse(CharT* str) noexcept {
905 if (str == nullptr || *str == static_cast<CharT>(0)) return str;
906
907 CharT* end = str;
908 while (*end != static_cast<CharT>(0)) {
909 ++end;
910 }
911 --end;
912 while (str < end) {
913 const CharT temp = *str;
914 *str = *end;
915 *end = temp;
916 ++str;
917 --end;
918 }
919 return str;
920}
921
930template <typename CharT>
931constexpr CharT*
932string_concatenate(CharT* MSTL_RESTRICT dest, const CharT* MSTL_RESTRICT src) noexcept {
933 if (dest == nullptr || src == nullptr) return nullptr;
934 CharT* original_dest = dest;
935 while (*dest != static_cast<CharT>(0))
936 ++dest;
937
938 while (*src != static_cast<CharT>(0)) {
939 *dest = *src;
940 ++dest;
941 ++src;
942 }
943 *dest = static_cast<CharT>(0);
944 return original_dest;
945}
946
956template <typename CharT>
957constexpr CharT*
958string_concatenate(CharT* MSTL_RESTRICT dest,
959 const CharT* MSTL_RESTRICT src,
960 const size_t count) noexcept {
961 if (dest == nullptr || src == nullptr) return nullptr;
962
963 CharT* original_dest = dest;
964 while (*dest != static_cast<CharT>(0)) {
965 ++dest;
966 }
967
968 size_t copied = 0;
969 while (*src != static_cast<CharT>(0) && copied < count) {
970 *dest = *src;
971 ++dest;
972 ++src;
973 ++copied;
974 }
975 *dest = static_cast<CharT>(0);
976 return original_dest;
977}
978 // StringOperations
980
982#endif // MSTL_CORE_MEMORY_MEMORY_HPP__
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 CharT to_uppercase(const CharT c) noexcept
将字符转换为大写
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 CharT to_lowercase(const CharT c) noexcept
将字符转换为小写
unsigned char byte_t
字节类型,定义为无符号字符
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
MSTL_NODISCARD MSTL_CONSTEXPR20 To memory_cast(const From &value) noexcept
执行内存层的类型转换
MSTL_CONSTEXPR14 void * memory_copy(void *MSTL_RESTRICT dest, const void *MSTL_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
MSTL_CONSTEXPR14 void * memory_copy_offset(void *MSTL_RESTRICT dest, const void *MSTL_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存并返回复制结束位置
MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
MSTL_CONSTEXPR14 void * memory_copy_until(void *dest, const void *src, const byte_t value, size_t count) noexcept
从源内存复制到目标内存,直到遇到特定字节
MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 const void * memory_find(const void *dest, const byte_t value, size_t count) noexcept
在内存中搜索特定字节
MSTL_CONSTEXPR14 void memory_zero(void *dest, const size_t count) noexcept
将内存区域清零
MSTL_CONSTEXPR14 void * memory_move(void *dest, const void *src, size_t count) noexcept
从源内存移动数据到目标内存
MSTL_CONSTEXPR14 const void * memory_find_pattern(const void *data, const size_t data_len, const void *pattern, const size_t pattern_len) noexcept
在内存中搜索子模式
MSTL_CONSTEXPR14 void * memory_set(void *dest, const byte_t value, size_t count) noexcept
使用指定字节填充内存区域
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
int64_t ptrdiff_t
指针差类型
typename make_unsigned< T >::type make_unsigned_t
make_unsigned的便捷别名
MSTL_PURE_FUNCTION constexpr const CharT * string_find_pattern_ignored_case(const CharT *dest, const CharT *src) noexcept
忽略大小写查找子字符串在字符串中首次出现的位置
MSTL_PURE_FUNCTION constexpr const CharT * string_find_last(const CharT *str, const CharT chr) noexcept
查找字符在字符串中最后出现的位置
constexpr CharT * string_reverse(CharT *str) noexcept
反转字符串
MSTL_PURE_FUNCTION constexpr int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
constexpr CharT * string_copy(CharT *MSTL_RESTRICT dest, const CharT *MSTL_RESTRICT src) noexcept
复制字符串
constexpr CharT * string_concatenate(CharT *MSTL_RESTRICT dest, const CharT *MSTL_RESTRICT src) noexcept
连接两个字符串
constexpr CharT * string_copy_offset(CharT *MSTL_RESTRICT dest, const CharT *MSTL_RESTRICT src) noexcept
复制字符串并返回指向结尾的指针
MSTL_PURE_FUNCTION constexpr const CharT * string_find(const CharT *str, const CharT chr) noexcept
查找字符在字符串中首次出现的位置
MSTL_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT *s1, const CharT *s2)
忽略大小写比较两个字符串
MSTL_PURE_FUNCTION constexpr CharT * string_find_any(CharT *str, const CharT *accept) noexcept
查找字符串中第一个出现在指定字符集中的字符
MSTL_PURE_FUNCTION constexpr const CharT * string_find_pattern(const CharT *dest, const CharT *src) noexcept
查找子字符串在字符串中首次出现的位置
MSTL_PURE_FUNCTION constexpr size_t string_span_not_in(const CharT *str, const CharT *reject) noexcept
计算字符串开头不包含在指定字符集中的字符数
MSTL_PURE_FUNCTION constexpr size_t string_length(const CharT *str) noexcept
计算字符串长度
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
MSTL_PURE_FUNCTION constexpr size_t string_span_in(const CharT *str, const CharT *accept) noexcept
计算字符串开头包含在指定字符集中的字符数
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
MSTL类型萃取