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 const auto* src_v =
static_cast<const volatile byte_t*
>(src);
41 while (
count-- != 0U) {
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 const auto* src_v =
static_cast<const volatile byte_t*
>(src);
79 while (
count-- != 0U) {
84 return (
void*) dest_v;
96 if (dest ==
nullptr || src ==
nullptr) {
100 auto* dest_v =
static_cast<volatile byte_t*
>(dest);
101 const auto* src_v =
static_cast<const volatile byte_t*
>(src);
103 while (
count-- != 0U) {
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) {
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);
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 const auto* src_v =
static_cast<const volatile byte_t*
>(src);
177 if (dest_v < src_v) {
178 while (
count-- != 0U) {
183 }
else if (dest_v > src_v) {
184 while (
count-- != 0U) {
199 if (dest ==
nullptr) {
203 void* ret =
static_cast<byte_t*
>(dest);
204 auto* dest_v =
static_cast<volatile byte_t*
>(dest);
205 while (
count-- != 0U) {
220 if (dest ==
nullptr) {
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);
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 const auto* p =
static_cast<const byte_t*
>(dest);
255 while (
count-- != 0U) {
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*
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;
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) {
558 if (dest[i] != src[i]) {
559 if (dest[i] ==
static_cast<CharT
>(0) || src[i] ==
static_cast<CharT
>(0)) {
562 return dest[i] < src[i] ? -1 : 1;
564 if (dest[i] ==
static_cast<CharT
>(0)) {
582template <
typename CharT>
584 if (s1 ==
nullptr && s2 ==
nullptr) {
606 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
617template <
typename CharT>
619 const size_t count)
noexcept {
620 if ((s1 ==
nullptr && s2 ==
nullptr) ||
count == 0) {
631 while (*s1 && *s2 && i <
count - 1) {
644 if (i ==
count - 1) {
650 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
659template <
typename CharT>
660NEFORCE_PURE_FUNCTION
constexpr size_t string_length(
const CharT* str)
noexcept {
662 if (str ==
nullptr) {
665 const CharT* p = str;
666 while (*p !=
static_cast<CharT
>(0)) {
669 return static_cast<size_t>(p - str);
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;
685 while (*p !=
static_cast<CharT
>(0) && len < max_len) {
699template <
typename CharT>
700NEFORCE_PURE_FUNCTION
constexpr const CharT*
string_find(
const CharT* str,
const CharT chr)
noexcept {
701 if (str ==
nullptr) {
704 while (*str !=
static_cast<CharT
>(0)) {
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) {
731 for (
size_t i = 0; i <
count; ++i) {
735 if (str[i] ==
static_cast<CharT
>(0)) {
749template <
typename CharT>
750NEFORCE_PURE_FUNCTION
constexpr const CharT*
string_find_last(
const CharT* str,
const CharT chr)
noexcept {
751 if (str ==
nullptr) {
754 const CharT* last =
nullptr;
756 while (*str !=
static_cast<CharT
>(0)) {
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)) {
778 while (*str !=
static_cast<CharT
>(0)) {
779 const CharT* a = accept;
780 while (*a !=
static_cast<CharT
>(0)) {
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) {
803 const CharT* cur = dest;
805 const CharT* str1 = cur;
806 const CharT* str2 = src;
807 while (*str1 && *str2 && *str1 == *str2) {
811 if (*str2 ==
static_cast<CharT
>(0)) {
826template <
typename CharT>
828 const CharT* src)
noexcept {
829 if (dest ==
nullptr || src ==
nullptr) {
832 if (*src ==
static_cast<CharT
>(0)) {
836 const CharT* cur = dest;
838 const CharT* str1 = cur;
839 const CharT* str2 = src;
840 while (*str1 && *str2) {
849 if (*str2 ==
static_cast<CharT
>(0)) {
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)) {
870 const CharT* original_str = str;
871 while (*str !=
static_cast<CharT
>(0)) {
872 const CharT* a = accept;
874 while (*a !=
static_cast<CharT
>(0)) {
882 return static_cast<size_t>(str - original_str);
886 return static_cast<size_t>(str - original_str);
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)) {
901 if (reject ==
nullptr || *reject ==
static_cast<CharT
>(0)) {
903 while (str[len] !=
static_cast<CharT
>(0)) {
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)) {
914 return static_cast<size_t>(str - original_str);
920 return static_cast<size_t>(str - original_str);
930template <
typename CharT>
931constexpr CharT*
string_set(CharT* str,
const CharT value)
noexcept {
932 if (str ==
nullptr) {
935 CharT* original = str;
936 while (*str !=
static_cast<CharT
>(0)) {
951template <
typename CharT>
952constexpr CharT*
string_set(CharT* str,
const CharT value,
const size_t count)
noexcept {
953 if (str ==
nullptr ||
count == 0) {
956 for (
size_t i = 0; i <
count; ++i) {
968template <
typename CharT>
970 if (str ==
nullptr || *str ==
static_cast<CharT
>(0)) {
975 while (*
end !=
static_cast<CharT
>(0)) {
980 const CharT temp = *str;
997template <
typename CharT>
998constexpr CharT*
string_concatenate(CharT* NEFORCE_RESTRICT dest,
const CharT* NEFORCE_RESTRICT src)
noexcept {
999 if (dest ==
nullptr || src ==
nullptr) {
1002 CharT* original_dest = dest;
1003 while (*dest !=
static_cast<CharT
>(0)) {
1007 while (*src !=
static_cast<CharT
>(0)) {
1012 *dest =
static_cast<CharT
>(0);
1013 return original_dest;
1025template <
typename CharT>
1027 const size_t count)
noexcept {
1028 if (dest ==
nullptr || src ==
nullptr) {
1032 CharT* original_dest = dest;
1033 while (*dest !=
static_cast<CharT
>(0)) {
1038 while (*src !=
static_cast<CharT
>(0) && copied <
count) {
1044 *dest =
static_cast<CharT
>(0);
1045 return original_dest;
1050NEFORCE_END_NAMESPACE__
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
从源内存复制到目标内存并返回复制结束位置
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的便捷变量模板