1#ifndef NEFORCE_CORE_MEMORY_MEMORY_HPP__
2#define NEFORCE_CORE_MEMORY_MEMORY_HPP__
13NEFORCE_BEGIN_NAMESPACE__
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) {
39 auto dest_v =
static_cast<volatile byte_t*
>(dest);
40 auto src_v =
static_cast<const volatile byte_t*
>(src);
59NEFORCE_CONSTEXPR14
void*
memory_copy(T* NEFORCE_RESTRICT dest,
const T* NEFORCE_RESTRICT src)
noexcept {
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) {
77 auto dest_v =
static_cast<volatile byte_t*
>(dest);
78 auto src_v =
static_cast<const volatile byte_t*
>(src);
84 return (
void*) dest_v;
96 if (dest ==
nullptr || src ==
nullptr) {
100 auto dest_v =
static_cast<volatile byte_t*
>(dest);
101 auto src_v =
static_cast<const volatile byte_t*
>(src);
104 const byte_t current = *src_v;
106 if (current == value) {
107 return (
void*) (++dest_v);
125NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14
int memory_compare(
const void* lhs,
const void* rhs,
size_t count)
noexcept {
126 if (lhs ==
nullptr && rhs ==
nullptr) {
129 if (lhs ==
nullptr) {
132 if (rhs ==
nullptr) {
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);
140 lhs =
static_cast<const byte_t*
>(lhs) + 1;
141 rhs =
static_cast<const byte_t*
>(rhs) + 1;
157NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14
int memory_compare(
const T& lhs,
const T& rhs)
noexcept {
170 if (dest ==
nullptr || src ==
nullptr) {
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) {
183 }
else if (dest_v > src_v) {
199 if (dest ==
nullptr) {
203 void* ret =
static_cast<byte_t*
>(dest);
204 auto dest_v =
static_cast<volatile byte_t*
>(dest);
220 if (dest ==
nullptr) {
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);
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) {
254 auto p =
static_cast<const byte_t*
>(dest);
273 const size_t pattern_len)
noexcept {
274 if (
data ==
nullptr || pattern ==
nullptr || data_len == 0 || pattern_len == 0 || pattern_len > data_len) {
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;
282 for (
size_t i = 0; i < last_possible; ++i) {
283 if (data_ptr[i] == pattern_ptr[0]) {
285 for (
size_t j = 1; j < pattern_len; ++j) {
286 if (data_ptr[i + j] != pattern_ptr[j]) {
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");
315#ifdef NEFORCE_STANDARD_20
316 return __builtin_bit_cast(To, value);
342template <
typename CharT>
343NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT
to_lowercase(
const CharT c)
noexcept {
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);
361template <
typename CharT>
362NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 CharT
to_uppercase(
const CharT c)
noexcept {
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);
391template <
typename CharT>
392constexpr CharT*
string_copy(CharT* NEFORCE_RESTRICT dest,
const CharT* NEFORCE_RESTRICT src)
noexcept {
393 if (dest ==
nullptr || src ==
nullptr) {
397 while (*src !=
static_cast<CharT
>(0)) {
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) {
428 while (i <
count && *src !=
static_cast<CharT
>(0)) {
436 *dest =
static_cast<CharT
>(0);
451template <
typename CharT>
452constexpr CharT*
string_copy_offset(CharT* NEFORCE_RESTRICT dest,
const CharT* NEFORCE_RESTRICT src)
noexcept {
453 if (dest ==
nullptr || src ==
nullptr) {
456 while (*src !=
static_cast<CharT
>(0)) {
474template <
typename CharT>
476 const size_t count)
noexcept {
477 if (dest ==
nullptr || src ==
nullptr) {
482 while (i <
count && *src !=
static_cast<CharT
>(0)) {
490 *dest =
static_cast<CharT
>(0);
507template <
typename CharT>
508NEFORCE_PURE_FUNCTION
constexpr int string_compare(
const CharT* dest,
const CharT* src)
noexcept {
509 if (dest ==
nullptr && src ==
nullptr) {
512 if (dest ==
nullptr) {
515 if (src ==
nullptr) {
519 while (*dest == *src) {
520 if (*dest ==
static_cast<CharT
>(0)) {
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) {
545 if (dest ==
nullptr) {
548 if (src ==
nullptr) {
556 while (*dest == *src && *dest !=
static_cast<CharT
>(0) && i <
count - 1) {
561 if (i ==
count - 1) {
564 return *dest < *src ? -1 : *dest > *src ? 1 : 0;
577template <
typename CharT>
579 if (s1 ==
nullptr && s2 ==
nullptr) {
601 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
612template <
typename CharT>
614 const size_t count)
noexcept {
615 if ((s1 ==
nullptr && s2 ==
nullptr) ||
count == 0) {
626 while (*s1 && *s2 && i <
count - 1) {
639 if (i ==
count - 1) {
645 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
654template <
typename CharT>
655NEFORCE_PURE_FUNCTION
constexpr size_t string_length(
const CharT* str)
noexcept {
657 if (str ==
nullptr) {
660 const CharT* p = str;
661 while (*p !=
static_cast<CharT
>(0)) {
664 return static_cast<size_t>(p - str);
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;
680 while (*p !=
static_cast<CharT
>(0) && len < max_len) {
694template <
typename CharT>
695NEFORCE_PURE_FUNCTION
constexpr const CharT*
string_find(
const CharT* str,
const CharT chr)
noexcept {
696 if (str ==
nullptr) {
699 while (*str !=
static_cast<CharT
>(0)) {
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) {
726 for (
size_t i = 0; i <
count; ++i) {
730 if (str[i] ==
static_cast<CharT
>(0)) {
744template <
typename CharT>
745NEFORCE_PURE_FUNCTION
constexpr const CharT*
string_find_last(
const CharT* str,
const CharT chr)
noexcept {
746 if (str ==
nullptr) {
749 const CharT* last =
nullptr;
751 while (*str !=
static_cast<CharT
>(0)) {
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)) {
773 while (*str !=
static_cast<CharT
>(0)) {
774 const CharT* a = accept;
775 while (*a !=
static_cast<CharT
>(0)) {
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) {
798 const CharT* cur = dest;
800 const CharT* str1 = cur;
801 const CharT* str2 = src;
802 while (*str1 && *str2 && *str1 == *str2) {
806 if (*str2 ==
static_cast<CharT
>(0)) {
821template <
typename CharT>
823 const CharT* src)
noexcept {
824 if (dest ==
nullptr || src ==
nullptr) {
827 if (*src ==
static_cast<CharT
>(0)) {
831 const CharT* cur = dest;
833 const CharT* str1 = cur;
834 const CharT* str2 = src;
835 while (*str1 && *str2) {
844 if (*str2 ==
static_cast<CharT
>(0)) {
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)) {
865 const CharT* original_str = str;
866 while (*str !=
static_cast<CharT
>(0)) {
867 const CharT* a = accept;
869 while (*a !=
static_cast<CharT
>(0)) {
877 return static_cast<size_t>(str - original_str);
881 return static_cast<size_t>(str - original_str);
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)) {
896 if (reject ==
nullptr || *reject ==
static_cast<CharT
>(0)) {
898 while (str[len] !=
static_cast<CharT
>(0)) {
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)) {
909 return static_cast<size_t>(str - original_str);
915 return static_cast<size_t>(str - original_str);
925template <
typename CharT>
926constexpr CharT*
string_set(CharT* str,
const CharT value)
noexcept {
927 if (str ==
nullptr) {
930 CharT* original = str;
931 while (*str !=
static_cast<CharT
>(0)) {
946template <
typename CharT>
947constexpr CharT*
string_set(CharT* str,
const CharT value,
const size_t count)
noexcept {
948 if (str ==
nullptr ||
count == 0) {
951 for (
size_t i = 0; i <
count; ++i) {
963template <
typename CharT>
965 if (str ==
nullptr || *str ==
static_cast<CharT
>(0)) {
970 while (*
end !=
static_cast<CharT
>(0)) {
975 const CharT temp = *str;
992template <
typename CharT>
993constexpr CharT*
string_concatenate(CharT* NEFORCE_RESTRICT dest,
const CharT* NEFORCE_RESTRICT src)
noexcept {
994 if (dest ==
nullptr || src ==
nullptr) {
997 CharT* original_dest = dest;
998 while (*dest !=
static_cast<CharT
>(0)) {
1002 while (*src !=
static_cast<CharT
>(0)) {
1007 *dest =
static_cast<CharT
>(0);
1008 return original_dest;
1020template <
typename CharT>
1022 const size_t count)
noexcept {
1023 if (dest ==
nullptr || src ==
nullptr) {
1027 CharT* original_dest = dest;
1028 while (*dest !=
static_cast<CharT
>(0)) {
1033 while (*src !=
static_cast<CharT
>(0) && copied <
count) {
1039 *dest =
static_cast<CharT
>(0);
1040 return original_dest;
1045NEFORCE_END_NAMESPACE__
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
使用指定字节填充内存区域
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的便捷变量模板