1#ifndef NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
2#define NEFORCE_CORE_STRING_CHAR_TRAITS_HPP__
15NEFORCE_BEGIN_NAMESPACE__
32template <
typename CharT,
typename IntT>
38 "int_type must be able to represent all char_type values plus EOF");
120 NEFORCE_NODISCARD
static constexpr bool eq(
const char_type lhs,
const char_type rhs)
noexcept {
return lhs == rhs; }
128 NEFORCE_NODISCARD
static constexpr bool lt(
const char_type lhs,
const char_type rhs)
noexcept {
return lhs < rhs; }
136 return rsc ==
eof() ?
static_cast<int_type>(0) : rsc;
154template <
typename CharT,
typename IntT>
156 static_assert(
sizeof(CharT) ==
sizeof(
byte_t),
"size of CharT must be the same as byte type");
182 const size_t n)
noexcept {
225template <
typename CharT>
236#ifdef NEFORCE_STANDARD_20
255template <
typename Traits>
262template <
typename Traits>
277template <
typename CharT,
bool IsChar = is_
character_v<CharT>>
278class __string_bitmap {
286 constexpr __string_bitmap() =
default;
294 constexpr bool mark(
const CharT* first,
const CharT*
const last)
noexcept {
295 for (; first != last; ++first) {
296 matches_[
static_cast<byte_t>(*first)] =
true;
306 constexpr bool match(
const CharT chr)
const noexcept {
return matches_[
static_cast<byte_t>(chr)]; }
309template <
typename CharT>
310class __string_bitmap<CharT, false> {};
324template <
typename Traits>
327 if (lh_size != rh_size) {
334 return Traits::compare(lhs, rhs, lh_size) == 0;
346template <
typename Traits>
349 const int state = Traits::compare(lhs, rhs, _NEFORCE
min(lh_size, rh_size));
354 if (lh_size < rh_size) {
357 if (lh_size > rh_size) {
373template <
typename Traits>
376 if (rsc_size > dest_size || start > dest_size - rsc_size) {
377 return static_cast<size_t>(-1);
383 const auto may_match_end = dest + (dest_size - rsc_size) + 1;
384 for (
auto if_match = dest + start;; ++if_match) {
385 if_match = Traits::find(if_match,
static_cast<size_t>(may_match_end - if_match), *rsc);
387 return static_cast<size_t>(-1);
390 if (Traits::compare(if_match, rsc, rsc_size) == 0) {
391 return static_cast<size_t>(if_match - dest);
405template <
typename Traits>
408 if (start < dest_size) {
409 const auto found = Traits::find(dest + start, dest_size - start, chr);
411 return static_cast<size_t>(found - dest);
414 return static_cast<size_t>(-1);
427template <
typename Traits>
431 return _NEFORCE
min(start, dest_size);
434 if (rsc_size <= dest_size) {
435 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - rsc_size);; --if_match) {
436 if (Traits::eq(*if_match, *rsc) && Traits::compare(if_match, rsc, rsc_size) == 0) {
437 return static_cast<size_t>(if_match - dest);
440 if (if_match == dest) {
445 return static_cast<size_t>(-1);
457template <
typename Traits>
460 if (dest_size != 0) {
461 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
462 if (Traits::eq(*if_match, chr)) {
463 return static_cast<size_t>(if_match - dest);
466 if (if_match == dest) {
471 return static_cast<size_t>(-1);
485#ifdef NEFORCE_STANDARD_17
494 const size_t rsc_size)
noexcept {
495 if (rsc_size != 0 && start < dest_size) {
496 inner::__string_bitmap<char_traits_char_t<Traits>> match;
497 if (!match.mark(rsc, rsc + rsc_size)) {
500 const auto end = dest + dest_size;
501 for (
auto if_match = dest + start; if_match <
end; ++if_match) {
502 if (match.match(*if_match)) {
503 return static_cast<size_t>(if_match - dest);
507 return static_cast<size_t>(-1);
521#ifdef NEFORCE_STANDARD_17
530 const size_t rsc_size)
noexcept {
531 if (rsc_size != 0 && start < dest_size) {
532 const auto end = dest + dest_size;
533 for (
auto if_match = dest + start; if_match <
end; ++if_match) {
534 if (Traits::find(rsc, rsc_size, *if_match)) {
535 return static_cast<size_t>(if_match - dest);
539 return static_cast<size_t>(-1);
553#ifdef NEFORCE_STANDARD_17
562 const size_t rsc_size)
noexcept {
563 if (rsc_size != 0 && dest_size != 0) {
564 inner::__string_bitmap<char_traits_char_t<Traits>> match;
565 if (!match.mark(rsc, rsc + rsc_size)) {
569 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
570 if (match.match(*if_match)) {
571 return static_cast<size_t>(if_match - dest);
574 if (if_match == dest) {
579 return static_cast<size_t>(-1);
593#ifdef NEFORCE_STANDARD_17
602 const size_t rsc_size)
noexcept {
603 if (rsc_size != 0 && dest_size != 0) {
604 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
605 if (Traits::find(rsc, rsc_size, *if_match)) {
606 return static_cast<size_t>(if_match - dest);
609 if (if_match == dest) {
614 return static_cast<size_t>(-1);
628#ifdef NEFORCE_STANDARD_17
637 const size_t rsc_size)
noexcept {
638 if (start < dest_size) {
639 inner::__string_bitmap<char_traits_char_t<Traits>> match;
640 if (!match.mark(rsc, rsc + rsc_size)) {
644 const auto end = dest + dest_size;
645 for (
auto if_match = dest + start; if_match <
end; ++if_match) {
646 if (!match.match(*if_match)) {
647 return static_cast<size_t>(if_match - dest);
651 return static_cast<size_t>(-1);
665#ifdef NEFORCE_STANDARD_17
674 const size_t rsc_size)
noexcept {
675 if (start < dest_size) {
676 const auto end = dest + dest_size;
677 for (
auto if_match = dest + start; if_match <
end; ++if_match) {
678 if (!Traits::find(rsc, rsc_size, *if_match)) {
679 return static_cast<size_t>(if_match - dest);
683 return static_cast<size_t>(-1);
695template <
typename Traits>
698 if (start < dest_size) {
699 const auto end = dest + dest_size;
700 for (
auto if_match = dest + start; if_match <
end; ++if_match) {
701 if (!Traits::eq(*if_match, chr)) {
702 return static_cast<size_t>(if_match - dest);
706 return static_cast<size_t>(-1);
720#ifdef NEFORCE_STANDARD_17
729 const size_t rsc_size)
noexcept {
730 if (dest_size != 0) {
731 inner::__string_bitmap<char_traits_char_t<Traits>> match;
732 if (!match.mark(rsc, rsc + rsc_size)) {
736 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
737 if (!match.match(*if_match)) {
738 return static_cast<size_t>(if_match - dest);
741 if (if_match == dest) {
746 return static_cast<size_t>(-1);
760#ifdef NEFORCE_STANDARD_17
769 const size_t rsc_size)
noexcept {
770 if (dest_size != 0) {
771 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
772 if (!Traits::find(rsc, rsc_size, *if_match)) {
773 return static_cast<size_t>(if_match - dest);
776 if (if_match == dest) {
781 return static_cast<size_t>(-1);
793template <
typename Traits>
796 if (dest_size != 0) {
797 for (
auto if_match = dest + _NEFORCE
min(start, dest_size - 1);; --if_match) {
798 if (!Traits::eq(*if_match, chr)) {
799 return static_cast<size_t>(if_match - dest);
802 if (if_match == dest) {
807 return static_cast<size_t>(-1);
812#define __NEFORCE_BUILD_CHAR_PTR_HASH(OPT) \
814 struct hash<OPT*> { \
815 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
816 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
820 struct hash<const OPT*> { \
821 NEFORCE_NODISCARD constexpr size_t operator()(const OPT* str) const noexcept { \
822 return FNV_hash_string(str, char_traits<OPT>::length(str)); \
825 template <size_t N> \
826 struct hash<OPT[N]> { \
827 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
828 return FNV_hash_string(str, N - 1); \
831 template <size_t N> \
832 struct hash<const OPT[N]> { \
833 NEFORCE_NODISCARD constexpr size_t operator()(const OPT (&str)[N]) const noexcept { \
834 return FNV_hash_string(str, N - 1); \
839#undef __NEFORCE_BUILD_CHAR_PTR_HASH
841NEFORCE_END_NAMESPACE__
static constexpr T max() noexcept
获取类型的最大值
const typename Traits::char_type * char_traits_ptr_t
获取字符特征中的字符指针类型
typename Traits::char_type char_traits_char_t
获取字符特征中的字符类型
constexpr size_t char_traits_find_first_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找第一个出现在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_rfind(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
从后向前查找子序列
constexpr size_t char_traits_find_last_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找最后一个出现在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_find_last_not_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找最后一个不在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_rfind_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
从后向前查找单个字符
constexpr size_t char_traits_rfind_not_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
查找最后一个不等于指定字符的位置
constexpr int char_traits_compare(const char_traits_ptr_t< Traits > lhs, const size_t lh_size, const char_traits_ptr_t< Traits > rhs, const size_t rh_size) noexcept
比较两个字符序列(三路比较)
constexpr size_t char_traits_find(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
在字符序列中查找子序列
constexpr size_t char_traits_find_not_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
查找第一个不等于指定字符的位置
constexpr size_t char_traits_find_first_not_of(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_ptr_t< Traits > rsc, const size_t rsc_size) noexcept
查找第一个不在给定集合中的字符(char_traits特化版本)
constexpr size_t char_traits_find_char(const char_traits_ptr_t< Traits > dest, const size_t dest_size, const size_t start, const char_traits_char_t< Traits > chr) noexcept
在字符序列中查找单个字符
constexpr bool char_traits_equal(const char_traits_ptr_t< Traits > lhs, const size_t lh_size, const char_traits_ptr_t< Traits > rhs, const size_t rh_size) noexcept
比较两个字符序列是否相等
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
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_set(void *dest, 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 int string_compare(const CharT *dest, const CharT *src) noexcept
比较两个字符串
constexpr size_t string_length(const CharT *str) noexcept
计算字符串长度
constexpr const CharT * string_find(const CharT *str, const CharT chr) noexcept
查找字符在字符串中首次出现的位置
constexpr CharT * string_set(CharT *str, const CharT value) noexcept
将字符串中的所有字符设置为指定值
constexpr bool is_specialization_v
is_specialization的便捷变量模板
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
#define NEFORCE_MACRO_RANGE_CHARS(MAC)
所有字符类型列表宏
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
static constexpr int_type not_eof(const int_type rsc) noexcept
如果不是EOF则返回原值,否则返回0
static constexpr int compare(const char_type *lhs, const char_type *rhs, size_t count) noexcept
比较两个字符序列
static constexpr char_type * assign(char_type *const str, const size_t count, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值
static constexpr bool eq(const char_type lhs, const char_type rhs) noexcept
相等比较
static constexpr char_type * move(char_type *dest, const char_type *srcs, const size_t count) noexcept
移动字符序列
static constexpr char_type * copy(char_type *dest, const char_type *srcs, const size_t count) noexcept
复制字符序列
static constexpr int_type eof() noexcept
返回EOF值
static constexpr const char_type * find(const char_type *str, const size_t count, const char_type target) noexcept
在字符序列中查找指定字符
static constexpr size_t length(const char_type *str) noexcept
计算字符串长度
static constexpr void assign(char_type &lhs, const char_type rhs) noexcept
赋值单个字符
static constexpr bool lt(const char_type lhs, const char_type rhs) noexcept
小于比较
static constexpr void assign(char_type &lhs, const char_type &rhs) noexcept
赋值单个字符
static constexpr const char_type * find(const char_type *str, const size_t n, const char_type chr) noexcept
在字符序列中查找指定字符(内存优化版本)
static constexpr int compare(const char_type *lhs, const char_type *rhs, const size_t n) noexcept
比较两个字符序列(内存优化版本)
static constexpr char_type * assign(char_type *str, size_t n, const char_type chr) noexcept
将字符序列中的每个字符设置为指定值(内存优化版本)