NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
memory.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_MEMORY_MEMORY_HPP__
2#define NEFORCE_CORE_MEMORY_MEMORY_HPP__
3
11
13NEFORCE_BEGIN_NAMESPACE__
14
20
29NEFORCE_CONSTEXPR14 void* memory_copy(void* NEFORCE_RESTRICT dest, const void* NEFORCE_RESTRICT src,
30 size_t count) noexcept {
31 if (dest == nullptr || src == nullptr) {
32 return nullptr;
33 }
34 if (count == 0) {
35 return dest;
36 }
37
38 void* res = dest;
39 auto dest_v = static_cast<volatile byte_t*>(dest);
40 auto src_v = static_cast<const volatile byte_t*>(src);
41 while (count--) {
42 // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
43 *dest_v = *src_v;
44 dest_v++;
45 src_v++;
46 }
47 return res;
48}
49
58template <typename T>
59NEFORCE_CONSTEXPR14 void* memory_copy(T* NEFORCE_RESTRICT dest, const T* NEFORCE_RESTRICT src) noexcept {
60 return _NEFORCE memory_copy(dest, src, sizeof(T));
61}
62
71NEFORCE_CONSTEXPR14 void* memory_copy_offset(void* NEFORCE_RESTRICT dest, const void* NEFORCE_RESTRICT src,
72 size_t count) noexcept {
73 if (dest == nullptr || src == nullptr) {
74 return nullptr;
75 }
76
77 auto dest_v = static_cast<volatile byte_t*>(dest);
78 auto src_v = static_cast<const volatile byte_t*>(src);
79 while (count--) {
80 *dest_v = *src_v;
81 dest_v++;
82 src_v++;
83 }
84 return (void*) dest_v;
85}
86
95NEFORCE_CONSTEXPR14 void* memory_copy_until(void* dest, const void* src, const byte_t value, size_t count) noexcept {
96 if (dest == nullptr || src == nullptr) {
97 return nullptr;
98 }
99
100 auto dest_v = static_cast<volatile byte_t*>(dest);
101 auto src_v = static_cast<const volatile byte_t*>(src);
102
103 while (count--) {
104 const byte_t current = *src_v;
105 *dest_v = current;
106 if (current == value) {
107 return (void*) (++dest_v);
108 }
109 dest_v++;
110 src_v++;
111 }
112 return nullptr;
113}
114
125NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const void* lhs, const void* rhs, size_t count) noexcept {
126 if (lhs == nullptr && rhs == nullptr) {
127 return 0;
128 }
129 if (lhs == nullptr) {
130 return -1;
131 }
132 if (rhs == nullptr) {
133 return 1;
134 }
135
136 while (count--) {
137 if (*static_cast<const byte_t*>(lhs) != *static_cast<const byte_t*>(rhs)) {
138 return *static_cast<const byte_t*>(lhs) - *static_cast<const byte_t*>(rhs);
139 }
140 lhs = static_cast<const byte_t*>(lhs) + 1;
141 rhs = static_cast<const byte_t*>(rhs) + 1;
142 }
143 return 0;
144}
145
156template <typename T>
157NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const T& lhs, const T& rhs) noexcept {
158 return _NEFORCE memory_compare(&lhs, &rhs, sizeof(T));
159}
160
169NEFORCE_CONSTEXPR14 void* memory_move(void* dest, const void* src, size_t count) noexcept {
170 if (dest == nullptr || src == nullptr) {
171 return nullptr;
172 }
173
174 void* res = dest;
175 auto dest_v = static_cast<volatile byte_t*>(dest);
176 auto src_v = static_cast<const volatile byte_t*>(src);
177 if (dest_v < src_v) {
178 while (count--) {
179 *dest_v = *src_v;
180 dest_v = dest_v + 1;
181 src_v = src_v + 1;
182 }
183 } else if (dest_v > src_v) {
184 while (count--) {
185 *(dest_v + count) = *(src_v + count);
186 }
187 }
188 return res;
189}
190
198NEFORCE_CONSTEXPR14 void* memory_set(void* dest, const byte_t value, size_t count) noexcept {
199 if (dest == nullptr) {
200 return nullptr;
201 }
202
203 void* ret = static_cast<byte_t*>(dest);
204 auto dest_v = static_cast<volatile byte_t*>(dest);
205 while (count--) {
206 *dest_v = value;
207 dest_v = dest_v + 1;
208 }
209 return ret;
210}
211
219NEFORCE_CONSTEXPR14 void memory_zero(void* dest, const size_t count) noexcept {
220 if (dest == nullptr) {
221 return;
222 }
223
224 const auto dest_v = static_cast<volatile byte_t*>(dest);
225 for (size_t i = 0; i < count; ++i) {
226 dest_v[i] = static_cast<byte_t>(0);
227 }
228}
229
237template <typename T>
238NEFORCE_CONSTEXPR14 void memory_zero(T* dest) noexcept {
239 _NEFORCE memory_zero(dest, sizeof(T));
240}
241
249NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 const void* memory_find(const void* dest, const byte_t value,
250 size_t count) noexcept {
251 if (dest == nullptr) {
252 return nullptr;
253 }
254 auto p = static_cast<const byte_t*>(dest);
255 while (count--) {
256 if (*p == value) {
257 return p;
258 }
259 p++;
260 }
261 return nullptr;
262}
263
272NEFORCE_CONSTEXPR14 const void* memory_find_pattern(const void* data, const size_t data_len, const void* pattern,
273 const size_t pattern_len) noexcept {
274 if (data == nullptr || pattern == nullptr || data_len == 0 || pattern_len == 0 || pattern_len > data_len) {
275 return nullptr;
276 }
277
278 const auto data_ptr = static_cast<const byte_t*>(data);
279 const auto pattern_ptr = static_cast<const byte_t*>(pattern);
280 const size_t last_possible = data_len - pattern_len + 1;
281
282 for (size_t i = 0; i < last_possible; ++i) {
283 if (data_ptr[i] == pattern_ptr[0]) {
284 bool match = true;
285 for (size_t j = 1; j < pattern_len; ++j) {
286 if (data_ptr[i + j] != pattern_ptr[j]) {
287 match = false;
288 break;
289 }
290 }
291 if (match) {
292 return data_ptr + i;
293 }
294 }
295 }
296 return nullptr;
297}
298
309template <typename To, typename From>
310NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 To memory_cast(const From& value) noexcept {
311 static_assert(sizeof(To) == sizeof(From), "types must have the same size");
312 static_assert(is_trivially_copyable_v<To>, "To type must be trivially copyable");
313 static_assert(is_trivially_copyable_v<From>, "From type must be trivially copyable");
314
315#ifdef NEFORCE_STANDARD_20
316 return __builtin_bit_cast(To, value);
317#else
318 static_assert(is_default_constructible_v<To>, "To type must be default constructible");
319
320 To result{};
321 _NEFORCE memory_copy(&result, &value, sizeof(To));
322 return result;
323#endif
324}
325 // MemoryFunctions
327
333
342template <typename CharT>
343NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT to_lowercase(const CharT c) noexcept {
344 static_assert(is_character_v<CharT>, "character type is necessary");
345 using UT = make_unsigned_t<CharT>;
346 const auto uc = static_cast<UT>(c);
347 if (uc >= static_cast<UT>('A') && uc <= static_cast<UT>('Z')) {
348 return static_cast<CharT>(uc | 0x20);
349 }
350 return c;
351}
352
361template <typename CharT>
362NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT to_uppercase(const CharT c) noexcept {
363 static_assert(is_character_v<CharT>, "character type is necessary");
364 using UT = make_unsigned_t<CharT>;
365 const auto uc = static_cast<UT>(c);
366 if (uc >= static_cast<UT>('a') && uc <= static_cast<UT>('z')) {
367 return static_cast<CharT>(uc & 0xDF);
368 }
369 return c;
370}
371 // CharCaseConversion
373
379
391template <typename CharT>
392constexpr CharT* string_copy(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src) noexcept {
393 if (dest == nullptr || src == nullptr) {
394 return nullptr;
395 }
396 CharT* ret = dest;
397 while (*src != static_cast<CharT>(0)) {
398 *dest = *src;
399 ++dest;
400 ++src;
401 }
402 *dest = *src;
403 return ret;
404}
405
419template <typename CharT>
420constexpr CharT* string_copy(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src,
421 const size_t count) noexcept {
422 if (dest == nullptr || src == nullptr) {
423 return nullptr;
424 }
425
426 CharT* ret = dest;
427 size_t i = 0;
428 while (i < count && *src != static_cast<CharT>(0)) {
429 *dest = *src;
430 ++dest;
431 ++src;
432 i++;
433 }
434
435 while (i < count) {
436 *dest = static_cast<CharT>(0);
437 ++dest;
438 i++;
439 }
440 return ret;
441}
442
451template <typename CharT>
452constexpr CharT* string_copy_offset(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src) noexcept {
453 if (dest == nullptr || src == nullptr) {
454 return nullptr;
455 }
456 while (*src != static_cast<CharT>(0)) {
457 *dest = *src;
458 ++dest;
459 ++src;
460 }
461 *dest = *src;
462 return dest - 1;
463}
464
474template <typename CharT>
475constexpr CharT* string_copy_offset(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src,
476 const size_t count) noexcept {
477 if (dest == nullptr || src == nullptr) {
478 return nullptr;
479 }
480
481 size_t i = 0;
482 while (i < count && *src != static_cast<CharT>(0)) {
483 *dest = *src;
484 ++dest;
485 ++src;
486 i++;
487 }
488
489 while (i < count) {
490 *dest = static_cast<CharT>(0);
491 ++dest;
492 i++;
493 }
494 return dest;
495}
496
507template <typename CharT>
508NEFORCE_PURE_FUNCTION constexpr int string_compare(const CharT* dest, const CharT* src) noexcept {
509 if (dest == nullptr && src == nullptr) {
510 return 0;
511 }
512 if (dest == nullptr) {
513 return -1;
514 }
515 if (src == nullptr) {
516 return 1;
517 }
518
519 while (*dest == *src) {
520 if (*dest == static_cast<CharT>(0)) {
521 return 0;
522 }
523 ++dest;
524 ++src;
525 }
526 if (*dest > *src) {
527 return 1;
528 }
529 return -1;
530}
531
540template <typename CharT>
541NEFORCE_PURE_FUNCTION constexpr int string_compare(const CharT* dest, const CharT* src, const size_t count) noexcept {
542 if (dest == nullptr && src == nullptr) {
543 return 0;
544 }
545 if (dest == nullptr) {
546 return -1;
547 }
548 if (src == nullptr) {
549 return 1;
550 }
551
552 if (count == 0) {
553 return 0;
554 }
555 size_t i = 0;
556 while (*dest == *src && *dest != static_cast<CharT>(0) && i < count - 1) {
557 ++dest;
558 ++src;
559 ++i;
560 }
561 if (i == count - 1) {
562 return 0;
563 }
564 return *dest < *src ? -1 : *dest > *src ? 1 : 0;
565}
566
577template <typename CharT>
578NEFORCE_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT* s1, const CharT* s2) {
579 if (s1 == nullptr && s2 == nullptr) {
580 return 0;
581 }
582 if (s1 == nullptr) {
583 return -1;
584 }
585 if (s2 == nullptr) {
586 return 1;
587 }
588
589 while (*s1 && *s2) {
590 const CharT c1 = _NEFORCE to_lowercase(*s1);
591 const CharT c2 = _NEFORCE to_lowercase(*s2);
592 if (c1 < c2) {
593 return -1;
594 }
595 if (c1 > c2) {
596 return 1;
597 }
598 ++s1;
599 ++s2;
600 }
601 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
602}
603
612template <typename CharT>
613NEFORCE_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT* s1, const CharT* s2,
614 const size_t count) noexcept {
615 if ((s1 == nullptr && s2 == nullptr) || count == 0) {
616 return 0;
617 }
618 if (s1 == nullptr) {
619 return -1;
620 }
621 if (s2 == nullptr) {
622 return 1;
623 }
624
625 size_t i = 0;
626 while (*s1 && *s2 && i < count - 1) {
627 const CharT c1 = _NEFORCE to_lowercase(*s1);
628 const CharT c2 = _NEFORCE to_lowercase(*s2);
629 if (c1 < c2) {
630 return -1;
631 }
632 if (c1 > c2) {
633 return 1;
634 }
635 ++s1;
636 ++s2;
637 ++i;
638 }
639 if (i == count - 1) {
640 return 0;
641 }
642
643 const CharT c1 = _NEFORCE to_lowercase(*s1);
644 const CharT c2 = _NEFORCE to_lowercase(*s2);
645 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
646}
647
654template <typename CharT>
655NEFORCE_PURE_FUNCTION constexpr size_t string_length(const CharT* str) noexcept {
656 static_assert(is_character_v<CharT>, "CharT must be a character");
657 if (str == nullptr) {
658 return 0;
659 }
660 const CharT* p = str;
661 while (*p != static_cast<CharT>(0)) {
662 ++p;
663 }
664 return static_cast<size_t>(p - str);
665}
666
676template <typename CharT>
677NEFORCE_PURE_FUNCTION constexpr size_t string_length(const CharT* str, const size_t max_len) noexcept {
678 const CharT* p = str;
679 ptrdiff_t len = 0;
680 while (*p != static_cast<CharT>(0) && len < max_len) {
681 ++p;
682 ++len;
683 }
684 return len;
685}
686
694template <typename CharT>
695NEFORCE_PURE_FUNCTION constexpr const CharT* string_find(const CharT* str, const CharT chr) noexcept {
696 if (str == nullptr) {
697 return nullptr;
698 }
699 while (*str != static_cast<CharT>(0)) {
700 if (*str == chr) {
701 return str;
702 }
703 ++str;
704 }
705 if (*str == chr) {
706 return str;
707 }
708 return nullptr;
709}
710
719template <typename CharT>
720NEFORCE_PURE_FUNCTION constexpr const CharT* string_find(const CharT* str, const CharT chr,
721 const size_t count) noexcept {
722 if (str == nullptr || count == 0) {
723 return nullptr;
724 }
725
726 for (size_t i = 0; i < count; ++i) {
727 if (str[i] == chr) {
728 return str + i;
729 }
730 if (str[i] == static_cast<CharT>(0)) {
731 break;
732 }
733 }
734 return nullptr;
735}
736
744template <typename CharT>
745NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_last(const CharT* str, const CharT chr) noexcept {
746 if (str == nullptr) {
747 return nullptr;
748 }
749 const CharT* last = nullptr;
750
751 while (*str != static_cast<CharT>(0)) {
752 if (*str == chr) {
753 last = str;
754 }
755 ++str;
756 }
757 return last;
758}
759
767template <typename CharT>
768NEFORCE_PURE_FUNCTION constexpr CharT* string_find_any(CharT* str, const CharT* accept) noexcept {
769 if (str == nullptr || *str == static_cast<CharT>(0) || accept == nullptr || *accept == static_cast<CharT>(0)) {
770 return nullptr;
771 }
772
773 while (*str != static_cast<CharT>(0)) {
774 const CharT* a = accept;
775 while (*a != static_cast<CharT>(0)) {
776 if (*str == *a) {
777 return str;
778 }
779 ++a;
780 }
781 ++str;
782 }
783 return nullptr;
784}
785
793template <typename CharT>
794NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_pattern(const CharT* dest, const CharT* src) noexcept {
795 if (dest == nullptr || src == nullptr) {
796 return nullptr;
797 }
798 const CharT* cur = dest;
799 while (*cur) {
800 const CharT* str1 = cur;
801 const CharT* str2 = src;
802 while (*str1 && *str2 && *str1 == *str2) {
803 ++str1;
804 ++str2;
805 }
806 if (*str2 == static_cast<CharT>(0)) {
807 return cur;
808 }
809 ++cur;
810 }
811 return nullptr;
812}
813
821template <typename CharT>
822NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_pattern_ignored_case(const CharT* dest,
823 const CharT* src) noexcept {
824 if (dest == nullptr || src == nullptr) {
825 return nullptr;
826 }
827 if (*src == static_cast<CharT>(0)) {
828 return dest;
829 }
830
831 const CharT* cur = dest;
832 while (*cur) {
833 const CharT* str1 = cur;
834 const CharT* str2 = src;
835 while (*str1 && *str2) {
836 const CharT c1 = _NEFORCE to_lowercase(*str1);
837 const CharT c2 = _NEFORCE to_lowercase(*str2);
838 if (c1 != c2) {
839 break;
840 }
841 ++str1;
842 ++str2;
843 }
844 if (*str2 == static_cast<CharT>(0)) {
845 return cur;
846 }
847 ++cur;
848 }
849 return nullptr;
850}
851
859template <typename CharT>
860NEFORCE_PURE_FUNCTION constexpr size_t string_span_in(const CharT* str, const CharT* accept) noexcept {
861 if (str == nullptr || *str == static_cast<CharT>(0) || accept == nullptr || *accept == static_cast<CharT>(0)) {
862 return 0;
863 }
864
865 const CharT* original_str = str;
866 while (*str != static_cast<CharT>(0)) {
867 const CharT* a = accept;
868 bool found = false;
869 while (*a != static_cast<CharT>(0)) {
870 if (*str == *a) {
871 found = true;
872 break;
873 }
874 ++a;
875 }
876 if (!found) {
877 return static_cast<size_t>(str - original_str);
878 }
879 ++str;
880 }
881 return static_cast<size_t>(str - original_str);
882}
883
891template <typename CharT>
892NEFORCE_PURE_FUNCTION constexpr size_t string_span_not_in(const CharT* str, const CharT* reject) noexcept {
893 if (str == nullptr || *str == static_cast<CharT>(0)) {
894 return 0;
895 }
896 if (reject == nullptr || *reject == static_cast<CharT>(0)) {
897 size_t len = 0;
898 while (str[len] != static_cast<CharT>(0)) {
899 ++len;
900 }
901 return len;
902 }
903
904 const CharT* original_str = str;
905 while (*str != static_cast<CharT>(0)) {
906 const CharT* r = reject;
907 while (*r != static_cast<CharT>(0)) {
908 if (*str == *r) {
909 return static_cast<size_t>(str - original_str);
910 }
911 ++r;
912 }
913 ++str;
914 }
915 return static_cast<size_t>(str - original_str);
916}
917
925template <typename CharT>
926constexpr CharT* string_set(CharT* str, const CharT value) noexcept {
927 if (str == nullptr) {
928 return nullptr;
929 }
930 CharT* original = str;
931 while (*str != static_cast<CharT>(0)) {
932 *str = value;
933 ++str;
934 }
935 return original;
936}
937
946template <typename CharT>
947constexpr CharT* string_set(CharT* str, const CharT value, const size_t count) noexcept {
948 if (str == nullptr || count == 0) {
949 return str;
950 }
951 for (size_t i = 0; i < count; ++i) {
952 str[i] = value;
953 }
954 return str;
955}
956
963template <typename CharT>
964constexpr CharT* string_reverse(CharT* str) noexcept {
965 if (str == nullptr || *str == static_cast<CharT>(0)) {
966 return str;
967 }
968
969 CharT* end = str;
970 while (*end != static_cast<CharT>(0)) {
971 ++end;
972 }
973 --end;
974 while (str < end) {
975 const CharT temp = *str;
976 *str = *end;
977 *end = temp;
978 ++str;
979 --end;
980 }
981 return str;
982}
983
992template <typename CharT>
993constexpr CharT* string_concatenate(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src) noexcept {
994 if (dest == nullptr || src == nullptr) {
995 return nullptr;
996 }
997 CharT* original_dest = dest;
998 while (*dest != static_cast<CharT>(0)) {
999 ++dest;
1000 }
1001
1002 while (*src != static_cast<CharT>(0)) {
1003 *dest = *src;
1004 ++dest;
1005 ++src;
1006 }
1007 *dest = static_cast<CharT>(0);
1008 return original_dest;
1009}
1010
1020template <typename CharT>
1021constexpr CharT* string_concatenate(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src,
1022 const size_t count) noexcept {
1023 if (dest == nullptr || src == nullptr) {
1024 return nullptr;
1025 }
1026
1027 CharT* original_dest = dest;
1028 while (*dest != static_cast<CharT>(0)) {
1029 ++dest;
1030 }
1031
1032 size_t copied = 0;
1033 while (*src != static_cast<CharT>(0) && copied < count) {
1034 *dest = *src;
1035 ++dest;
1036 ++src;
1037 ++copied;
1038 }
1039 *dest = static_cast<CharT>(0);
1040 return original_dest;
1041}
1042 // StringOperations
1044
1045NEFORCE_END_NAMESPACE__
1046#endif // NEFORCE_CORE_MEMORY_MEMORY_HPP__
NEFORCE_INLINE17 constexpr bool is_character_v
is_character的便捷变量模板
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT to_uppercase(const CharT c) noexcept
将字符转换为大写
NEFORCE_CONST_FUNCTION NEFORCE_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)
统计范围内等于指定值的元素数量
NEFORCE_CONSTEXPR14 void memory_zero(void *dest, const size_t count) noexcept
将内存区域清零
NEFORCE_CONSTEXPR14 void * memory_copy_offset(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存并返回复制结束位置
NEFORCE_CONSTEXPR14 void * memory_copy(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
NEFORCE_CONSTEXPR14 const void * memory_find_pattern(const void *data, const size_t data_len, const void *pattern, const size_t pattern_len) noexcept
在内存中搜索子模式
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 To memory_cast(const From &value) 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_copy_until(void *dest, const void *src, const byte_t value, size_t count) noexcept
从源内存复制到目标内存,直到遇到特定字节
NEFORCE_CONSTEXPR14 void * memory_set(void *dest, const byte_t value, size_t count) noexcept
使用指定字节填充内存区域
int64_t ptrdiff_t
指针差类型
typename make_unsigned< T >::type make_unsigned_t
make_unsigned的便捷别名
NEFORCE_PURE_FUNCTION constexpr size_t string_span_not_in(const CharT *str, const CharT *reject) 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
查找字符在字符串中首次出现的位置
constexpr CharT * string_reverse(CharT *str) noexcept
反转字符串
constexpr CharT * string_copy(CharT *NEFORCE_RESTRICT dest, const CharT *NEFORCE_RESTRICT src) noexcept
复制字符串
NEFORCE_PURE_FUNCTION constexpr size_t string_span_in(const CharT *str, const CharT *accept) noexcept
计算字符串开头包含在指定字符集中的字符数
NEFORCE_PURE_FUNCTION constexpr const CharT * string_find_pattern_ignored_case(const CharT *dest, const CharT *src) noexcept
忽略大小写查找子字符串在字符串中首次出现的位置
constexpr CharT * string_concatenate(CharT *NEFORCE_RESTRICT dest, const CharT *NEFORCE_RESTRICT src) noexcept
连接两个字符串
NEFORCE_PURE_FUNCTION constexpr int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
NEFORCE_PURE_FUNCTION constexpr CharT * string_find_any(CharT *str, const CharT *accept) noexcept
查找字符串中第一个出现在指定字符集中的字符
NEFORCE_PURE_FUNCTION constexpr const CharT * string_find_pattern(const CharT *dest, const CharT *src) noexcept
查找子字符串在字符串中首次出现的位置
constexpr CharT * string_copy_offset(CharT *NEFORCE_RESTRICT dest, const CharT *NEFORCE_RESTRICT src) noexcept
复制字符串并返回指向结尾的指针
NEFORCE_PURE_FUNCTION constexpr const CharT * string_find_last(const CharT *str, const CharT chr) noexcept
查找字符在字符串中最后出现的位置
NEFORCE_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT *s1, const CharT *s2)
忽略大小写比较两个字符串
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
NEFORCE_INLINE17 constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_default_constructible_v
is_default_constructible的便捷变量模板
类型萃取