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 const auto* src_v = static_cast<const volatile byte_t*>(src);
41 while (count-- != 0U) {
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 const auto* src_v = static_cast<const volatile byte_t*>(src);
79 while (count-- != 0U) {
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 const auto* src_v = static_cast<const volatile byte_t*>(src);
102
103 while (count-- != 0U) {
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-- != 0U) {
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 const auto* src_v = static_cast<const volatile byte_t*>(src);
177 if (dest_v < src_v) {
178 while (count-- != 0U) {
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-- != 0U) {
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-- != 0U) {
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 auto* const 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 const auto* p = static_cast<const byte_t*>(dest);
255 while (count-- != 0U) {
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* const data_ptr = static_cast<const byte_t*>(data);
279 const auto* const 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
556 size_t i = 0;
557 while (i < count) {
558 if (dest[i] != src[i]) {
559 if (dest[i] == static_cast<CharT>(0) || src[i] == static_cast<CharT>(0)) {
560 return 0;
561 }
562 return dest[i] < src[i] ? -1 : 1;
563 }
564 if (dest[i] == static_cast<CharT>(0)) {
565 return 0;
566 }
567 ++i;
568 }
569 return 0;
570}
571
582template <typename CharT>
583NEFORCE_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT* s1, const CharT* s2) noexcept {
584 if (s1 == nullptr && s2 == nullptr) {
585 return 0;
586 }
587 if (s1 == nullptr) {
588 return -1;
589 }
590 if (s2 == nullptr) {
591 return 1;
592 }
593
594 while (*s1 && *s2) {
595 const CharT c1 = _NEFORCE to_lowercase(*s1);
596 const CharT c2 = _NEFORCE to_lowercase(*s2);
597 if (c1 < c2) {
598 return -1;
599 }
600 if (c1 > c2) {
601 return 1;
602 }
603 ++s1;
604 ++s2;
605 }
606 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
607}
608
617template <typename CharT>
618NEFORCE_PURE_FUNCTION constexpr int string_compare_ignore_case(const CharT* s1, const CharT* s2,
619 const size_t count) noexcept {
620 if ((s1 == nullptr && s2 == nullptr) || count == 0) {
621 return 0;
622 }
623 if (s1 == nullptr) {
624 return -1;
625 }
626 if (s2 == nullptr) {
627 return 1;
628 }
629
630 size_t i = 0;
631 while (*s1 && *s2 && i < count - 1) {
632 const CharT c1 = _NEFORCE to_lowercase(*s1);
633 const CharT c2 = _NEFORCE to_lowercase(*s2);
634 if (c1 < c2) {
635 return -1;
636 }
637 if (c1 > c2) {
638 return 1;
639 }
640 ++s1;
641 ++s2;
642 ++i;
643 }
644 if (i == count - 1) {
645 return 0;
646 }
647
648 const CharT c1 = _NEFORCE to_lowercase(*s1);
649 const CharT c2 = _NEFORCE to_lowercase(*s2);
650 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
651}
652
659template <typename CharT>
660NEFORCE_PURE_FUNCTION constexpr size_t string_length(const CharT* str) noexcept {
661 static_assert(is_character_v<CharT>, "CharT must be a character");
662 if (str == nullptr) {
663 return 0;
664 }
665 const CharT* p = str;
666 while (*p != static_cast<CharT>(0)) {
667 ++p;
668 }
669 return static_cast<size_t>(p - str);
670}
671
681template <typename CharT>
682NEFORCE_PURE_FUNCTION constexpr size_t string_length(const CharT* str, const size_t max_len) noexcept {
683 const CharT* p = str;
684 ptrdiff_t len = 0;
685 while (*p != static_cast<CharT>(0) && len < max_len) {
686 ++p;
687 ++len;
688 }
689 return len;
690}
691
699template <typename CharT>
700NEFORCE_PURE_FUNCTION constexpr const CharT* string_find(const CharT* str, const CharT chr) noexcept {
701 if (str == nullptr) {
702 return nullptr;
703 }
704 while (*str != static_cast<CharT>(0)) {
705 if (*str == chr) {
706 return str;
707 }
708 ++str;
709 }
710 if (*str == chr) {
711 return str;
712 }
713 return nullptr;
714}
715
724template <typename CharT>
725NEFORCE_PURE_FUNCTION constexpr const CharT* string_find(const CharT* str, const CharT chr,
726 const size_t count) noexcept {
727 if (str == nullptr || count == 0) {
728 return nullptr;
729 }
730
731 for (size_t i = 0; i < count; ++i) {
732 if (str[i] == chr) {
733 return str + i;
734 }
735 if (str[i] == static_cast<CharT>(0)) {
736 break;
737 }
738 }
739 return nullptr;
740}
741
749template <typename CharT>
750NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_last(const CharT* str, const CharT chr) noexcept {
751 if (str == nullptr) {
752 return nullptr;
753 }
754 const CharT* last = nullptr;
755
756 while (*str != static_cast<CharT>(0)) {
757 if (*str == chr) {
758 last = str;
759 }
760 ++str;
761 }
762 return last;
763}
764
772template <typename CharT>
773NEFORCE_PURE_FUNCTION constexpr CharT* string_find_any(CharT* str, const CharT* accept) noexcept {
774 if (str == nullptr || *str == static_cast<CharT>(0) || accept == nullptr || *accept == static_cast<CharT>(0)) {
775 return nullptr;
776 }
777
778 while (*str != static_cast<CharT>(0)) {
779 const CharT* a = accept;
780 while (*a != static_cast<CharT>(0)) {
781 if (*str == *a) {
782 return str;
783 }
784 ++a;
785 }
786 ++str;
787 }
788 return nullptr;
789}
790
798template <typename CharT>
799NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_pattern(const CharT* dest, const CharT* src) noexcept {
800 if (dest == nullptr || src == nullptr) {
801 return nullptr;
802 }
803 const CharT* cur = dest;
804 while (*cur) {
805 const CharT* str1 = cur;
806 const CharT* str2 = src;
807 while (*str1 && *str2 && *str1 == *str2) {
808 ++str1;
809 ++str2;
810 }
811 if (*str2 == static_cast<CharT>(0)) {
812 return cur;
813 }
814 ++cur;
815 }
816 return nullptr;
817}
818
826template <typename CharT>
827NEFORCE_PURE_FUNCTION constexpr const CharT* string_find_pattern_ignored_case(const CharT* dest,
828 const CharT* src) noexcept {
829 if (dest == nullptr || src == nullptr) {
830 return nullptr;
831 }
832 if (*src == static_cast<CharT>(0)) {
833 return dest;
834 }
835
836 const CharT* cur = dest;
837 while (*cur) {
838 const CharT* str1 = cur;
839 const CharT* str2 = src;
840 while (*str1 && *str2) {
841 const CharT c1 = _NEFORCE to_lowercase(*str1);
842 const CharT c2 = _NEFORCE to_lowercase(*str2);
843 if (c1 != c2) {
844 break;
845 }
846 ++str1;
847 ++str2;
848 }
849 if (*str2 == static_cast<CharT>(0)) {
850 return cur;
851 }
852 ++cur;
853 }
854 return nullptr;
855}
856
864template <typename CharT>
865NEFORCE_PURE_FUNCTION constexpr size_t string_span_in(const CharT* str, const CharT* accept) noexcept {
866 if (str == nullptr || *str == static_cast<CharT>(0) || accept == nullptr || *accept == static_cast<CharT>(0)) {
867 return 0;
868 }
869
870 const CharT* original_str = str;
871 while (*str != static_cast<CharT>(0)) {
872 const CharT* a = accept;
873 bool found = false;
874 while (*a != static_cast<CharT>(0)) {
875 if (*str == *a) {
876 found = true;
877 break;
878 }
879 ++a;
880 }
881 if (!found) {
882 return static_cast<size_t>(str - original_str);
883 }
884 ++str;
885 }
886 return static_cast<size_t>(str - original_str);
887}
888
896template <typename CharT>
897NEFORCE_PURE_FUNCTION constexpr size_t string_span_not_in(const CharT* str, const CharT* reject) noexcept {
898 if (str == nullptr || *str == static_cast<CharT>(0)) {
899 return 0;
900 }
901 if (reject == nullptr || *reject == static_cast<CharT>(0)) {
902 size_t len = 0;
903 while (str[len] != static_cast<CharT>(0)) {
904 ++len;
905 }
906 return len;
907 }
908
909 const CharT* original_str = str;
910 while (*str != static_cast<CharT>(0)) {
911 const CharT* r = reject;
912 while (*r != static_cast<CharT>(0)) {
913 if (*str == *r) {
914 return static_cast<size_t>(str - original_str);
915 }
916 ++r;
917 }
918 ++str;
919 }
920 return static_cast<size_t>(str - original_str);
921}
922
930template <typename CharT>
931constexpr CharT* string_set(CharT* str, const CharT value) noexcept {
932 if (str == nullptr) {
933 return nullptr;
934 }
935 CharT* original = str;
936 while (*str != static_cast<CharT>(0)) {
937 *str = value;
938 ++str;
939 }
940 return original;
941}
942
951template <typename CharT>
952constexpr CharT* string_set(CharT* str, const CharT value, const size_t count) noexcept {
953 if (str == nullptr || count == 0) {
954 return str;
955 }
956 for (size_t i = 0; i < count; ++i) {
957 str[i] = value;
958 }
959 return str;
960}
961
968template <typename CharT>
969constexpr CharT* string_reverse(CharT* str) noexcept {
970 if (str == nullptr || *str == static_cast<CharT>(0)) {
971 return str;
972 }
973
974 CharT* end = str;
975 while (*end != static_cast<CharT>(0)) {
976 ++end;
977 }
978 --end;
979 while (str < end) {
980 const CharT temp = *str;
981 *str = *end;
982 *end = temp;
983 ++str;
984 --end;
985 }
986 return str;
987}
988
997template <typename CharT>
998constexpr CharT* string_concatenate(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src) noexcept {
999 if (dest == nullptr || src == nullptr) {
1000 return nullptr;
1001 }
1002 CharT* original_dest = dest;
1003 while (*dest != static_cast<CharT>(0)) {
1004 ++dest;
1005 }
1006
1007 while (*src != static_cast<CharT>(0)) {
1008 *dest = *src;
1009 ++dest;
1010 ++src;
1011 }
1012 *dest = static_cast<CharT>(0);
1013 return original_dest;
1014}
1015
1025template <typename CharT>
1026constexpr CharT* string_concatenate(CharT* NEFORCE_RESTRICT dest, const CharT* NEFORCE_RESTRICT src,
1027 const size_t count) noexcept {
1028 if (dest == nullptr || src == nullptr) {
1029 return nullptr;
1030 }
1031
1032 CharT* original_dest = dest;
1033 while (*dest != static_cast<CharT>(0)) {
1034 ++dest;
1035 }
1036
1037 size_t copied = 0;
1038 while (*src != static_cast<CharT>(0) && copied < count) {
1039 *dest = *src;
1040 ++dest;
1041 ++src;
1042 ++copied;
1043 }
1044 *dest = static_cast<CharT>(0);
1045 return original_dest;
1046}
1047 // StringOperations
1049
1050NEFORCE_END_NAMESPACE__
1051#endif // NEFORCE_CORE_MEMORY_MEMORY_HPP__
constexpr bool is_character_v
is_character的便捷变量模板
constexpr CharT to_lowercase(const CharT c) noexcept
将字符转换为小写
constexpr CharT to_uppercase(const CharT c) noexcept
将字符转换为大写
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_zero(void *dest, const size_t count) noexcept
将内存区域清零
constexpr void * memory_set(void *dest, const byte_t value, size_t count) noexcept
使用指定字节填充内存区域
constexpr const void * memory_find_pattern(const void *data, const size_t data_len, const void *pattern, const size_t pattern_len) noexcept
在内存中搜索子模式
constexpr To memory_cast(const From &value) noexcept
执行内存层的类型转换
constexpr void * memory_copy_until(void *dest, const void *src, 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 void * memory_copy_offset(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存并返回复制结束位置
int64_t ptrdiff_t
指针差类型
typename make_unsigned< T >::type make_unsigned_t
make_unsigned的便捷别名
constexpr const CharT * string_find_last(const CharT *str, const CharT chr) noexcept
查找字符在字符串中最后出现的位置
constexpr const CharT * string_find_pattern_ignored_case(const CharT *dest, const CharT *src) noexcept
忽略大小写查找子字符串在字符串中首次出现的位置
constexpr size_t string_span_not_in(const CharT *str, const CharT *reject) noexcept
计算字符串开头不包含在指定字符集中的字符数
constexpr CharT * string_reverse(CharT *str) noexcept
反转字符串
constexpr CharT * string_copy(CharT *NEFORCE_RESTRICT dest, const CharT *NEFORCE_RESTRICT src) noexcept
复制字符串
constexpr int string_compare_ignore_case(const CharT *s1, const CharT *s2) noexcept
忽略大小写比较两个字符串
constexpr CharT * string_find_any(CharT *str, const CharT *accept) noexcept
查找字符串中第一个出现在指定字符集中的字符
constexpr int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
constexpr size_t string_length(const CharT *str) noexcept
计算字符串长度
constexpr CharT * string_concatenate(CharT *NEFORCE_RESTRICT dest, const CharT *NEFORCE_RESTRICT src) noexcept
连接两个字符串
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
复制字符串并返回指向结尾的指针
constexpr size_t string_span_in(const CharT *str, const CharT *accept) noexcept
计算字符串开头包含在指定字符集中的字符数
constexpr const CharT * string_find(const CharT *str, const CharT chr) noexcept
查找字符在字符串中首次出现的位置
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
constexpr bool is_default_constructible_v
is_default_constructible的便捷变量模板
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
类型萃取