1#ifndef MSTL_CORE_MEMORY_MEMORY_HPP__
2#define MSTL_CORE_MEMORY_MEMORY_HPP__
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;
35 auto dest_v =
static_cast<volatile byte_t*
>(dest);
36 auto src_v =
static_cast<const volatile byte_t*
>(src);
55memory_copy(T* MSTL_RESTRICT dest,
const T* MSTL_RESTRICT src)
noexcept {
69 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
71 auto dest_v =
static_cast<volatile byte_t*
>(dest);
72 auto src_v =
static_cast<const volatile byte_t*
>(src);
78 return (
void*) dest_v;
91 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
93 auto dest_v =
static_cast<volatile byte_t*
>(dest);
94 auto src_v =
static_cast<const volatile byte_t*
>(src);
97 const byte_t current = *src_v;
99 if (current == value) {
100 return (
void*) (++dest_v);
118MSTL_PURE_FUNCTION MSTL_CONSTEXPR14
int
120 if (lhs ==
nullptr && rhs ==
nullptr)
return 0;
121 if (lhs ==
nullptr)
return -1;
122 if (rhs ==
nullptr)
return 1;
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;
144MSTL_PURE_FUNCTION MSTL_CONSTEXPR14
int
157MSTL_CONSTEXPR14
void*
159 if(dest ==
nullptr || src ==
nullptr)
return nullptr;
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) {
170 }
else if (dest_v > src_v) {
185MSTL_CONSTEXPR14
void*
187 if(dest ==
nullptr)
return nullptr;
189 void* ret =
static_cast<byte_t*
>(dest);
190 auto dest_v =
static_cast<volatile byte_t*
>(dest);
206 if (dest ==
nullptr)
return;
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);
233MSTL_PURE_FUNCTION MSTL_CONSTEXPR14
const void*
235 if(dest ==
nullptr)
return nullptr;
236 auto p =
static_cast<const byte_t*
>(dest);
254MSTL_CONSTEXPR14
const void*
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) {
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;
266 for (
size_t i = 0; i < last_possible; ++i) {
267 if (data_ptr[i] == pattern_ptr[0]) {
269 for (
size_t j = 1; j < pattern_len; ++j) {
270 if (data_ptr[i + j] != pattern_ptr[j]) {
293template <
typename To,
typename From>
294MSTL_NODISCARD MSTL_CONSTEXPR20 To
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");
300#ifdef MSTL_STANDARD_20__
301 return __builtin_bit_cast(To, value);
303 static_assert(is_default_constructible_v<To>,
"To type must be default constructible");
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");
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);
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");
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);
376template <
typename CharT>
379 const CharT* MSTL_RESTRICT src)
noexcept {
380 if(dest ==
nullptr || src ==
nullptr)
return nullptr;
382 while (*src !=
static_cast<CharT
>(0)) {
404template <
typename CharT>
407 const CharT* MSTL_RESTRICT src,
408 const size_t count)
noexcept {
409 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
413 while (i <
count && *src !=
static_cast<CharT
>(0)) {
421 *dest =
static_cast<CharT
>(0);
436template <
typename CharT>
439 const CharT* MSTL_RESTRICT src)
noexcept {
440 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
441 while (*src !=
static_cast<CharT
>(0)) {
459template <
typename CharT>
462 const CharT* MSTL_RESTRICT src,
463 const size_t count)
noexcept {
464 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
467 while (i <
count && *src !=
static_cast<CharT
>(0)) {
475 *dest =
static_cast<CharT
>(0);
492template <
typename CharT>
493MSTL_PURE_FUNCTION
constexpr int
495 if (dest ==
nullptr && src ==
nullptr)
return 0;
496 if (dest ==
nullptr)
return -1;
497 if (src ==
nullptr)
return 1;
499 while (*dest == *src) {
500 if (*dest ==
static_cast<CharT
>(0)) {
506 if (*dest > *src)
return 1;
518template <
typename CharT>
519MSTL_PURE_FUNCTION
constexpr int
521 if (dest ==
nullptr && src ==
nullptr)
return 0;
522 if (dest ==
nullptr)
return -1;
523 if (src ==
nullptr)
return 1;
525 if (
count == 0)
return 0;
527 while (*dest == *src &&
528 *dest !=
static_cast<CharT
>(0) &&
534 if (i ==
count - 1)
return 0;
535 return *dest < *src ? -1 : *dest > *src ? 1 : 0;
548template <
typename CharT>
549MSTL_PURE_FUNCTION
constexpr int
551 if (s1 ==
nullptr && s2 ==
nullptr)
return 0;
552 if (s1 ==
nullptr)
return -1;
553 if (s2 ==
nullptr)
return 1;
558 if (c1 < c2)
return -1;
559 if (c1 > c2)
return 1;
563 return *s1 == *s2 ? 0 : *s1 < *s2 ? -1 : 1;
574template <
typename CharT>
575MSTL_PURE_FUNCTION
constexpr int
577 if ((s1 ==
nullptr && s2 ==
nullptr) ||
count == 0)
return 0;
578 if (s1 ==
nullptr)
return -1;
579 if (s2 ==
nullptr)
return 1;
582 while (*s1 && *s2 && i <
count - 1) {
585 if (c1 < c2)
return -1;
586 if (c1 > c2)
return 1;
591 if (i ==
count - 1)
return 0;
595 return c1 < c2 ? -1 : c1 > c2 ? 1 : 0;
604template <
typename CharT>
605MSTL_PURE_FUNCTION
constexpr size_t
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)) {
613 return static_cast<size_t>(p - str);
625template <
typename CharT>
626MSTL_PURE_FUNCTION
constexpr size_t
628 const CharT* p = str;
630 while (*p !=
static_cast<CharT
>(0) && len < max_len) {
644template <
typename CharT>
645MSTL_PURE_FUNCTION
constexpr const CharT*
647 if (str ==
nullptr)
return nullptr;
648 while (*str !=
static_cast<CharT
>(0)) {
668template <
typename CharT>
669MSTL_PURE_FUNCTION
constexpr const CharT*
671 if (str ==
nullptr ||
count == 0)
return nullptr;
673 for (
size_t i = 0; i <
count; ++i) {
677 if (str[i] ==
static_cast<CharT
>(0)) {
691template <
typename CharT>
692MSTL_PURE_FUNCTION
constexpr const CharT*
694 if (str ==
nullptr)
return nullptr;
695 const CharT* last =
nullptr;
697 while (*str !=
static_cast<CharT
>(0)) {
713template <
typename CharT>
714MSTL_PURE_FUNCTION
constexpr CharT*
716 if (str ==
nullptr || *str ==
static_cast<CharT
>(0) ||
717 accept ==
nullptr || *accept ==
static_cast<CharT
>(0))
720 while (*str !=
static_cast<CharT
>(0)) {
721 const CharT* a = accept;
722 while (*a !=
static_cast<CharT
>(0)) {
740template <
typename CharT>
741MSTL_PURE_FUNCTION
constexpr const CharT*
743 if(dest ==
nullptr || src ==
nullptr)
return nullptr;
744 const CharT* cur = dest;
746 const CharT *str1 = cur;
747 const CharT *str2 = src;
748 while (*str1 && *str2 && *str1 == *str2) {
752 if (*str2 ==
static_cast<CharT
>(0))
return cur;
765template <
typename CharT>
766MSTL_PURE_FUNCTION
constexpr const CharT*
768 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
769 if (*src ==
static_cast<CharT
>(0))
return dest;
771 const CharT* cur = dest;
773 const CharT* str1 = cur;
774 const CharT* str2 = src;
775 while (*str1 && *str2) {
782 if (*str2 ==
static_cast<CharT
>(0)) {
797template <
typename CharT>
798MSTL_PURE_FUNCTION
constexpr size_t
800 if (str ==
nullptr || *str ==
static_cast<CharT
>(0) ||
801 accept ==
nullptr || *accept ==
static_cast<CharT
>(0)) {
805 const CharT* original_str = str;
806 while (*str !=
static_cast<CharT
>(0)) {
807 const CharT* a = accept;
809 while (*a !=
static_cast<CharT
>(0)) {
817 return static_cast<size_t>(str - original_str);
821 return static_cast<size_t>(str - original_str);
831template <
typename CharT>
832MSTL_PURE_FUNCTION
constexpr size_t
834 if (str ==
nullptr || *str ==
static_cast<CharT
>(0))
return 0;
835 if (reject ==
nullptr || *reject ==
static_cast<CharT
>(0)) {
837 while (str[len] !=
static_cast<CharT
>(0)) ++len;
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)) {
846 return static_cast<size_t>(str - original_str);
852 return static_cast<size_t>(str - original_str);
862template <
typename CharT>
865 if (str ==
nullptr)
return nullptr;
866 CharT* original = str;
867 while (*str !=
static_cast<CharT
>(0)) {
882template <
typename CharT>
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) {
902template <
typename CharT>
905 if (str ==
nullptr || *str ==
static_cast<CharT
>(0))
return str;
908 while (*
end !=
static_cast<CharT
>(0)) {
913 const CharT temp = *str;
930template <
typename CharT>
933 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
934 CharT* original_dest = dest;
935 while (*dest !=
static_cast<CharT
>(0))
938 while (*src !=
static_cast<CharT
>(0)) {
943 *dest =
static_cast<CharT
>(0);
944 return original_dest;
956template <
typename CharT>
959 const CharT* MSTL_RESTRICT src,
960 const size_t count)
noexcept {
961 if (dest ==
nullptr || src ==
nullptr)
return nullptr;
963 CharT* original_dest = dest;
964 while (*dest !=
static_cast<CharT
>(0)) {
969 while (*src !=
static_cast<CharT
>(0) && copied <
count) {
975 *dest =
static_cast<CharT
>(0);
976 return original_dest;
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
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()))
获取容器的底层数据指针