1#ifndef SMALL_COMPARE_HH
2#define SMALL_COMPARE_HH
54 assert(str[N - 1] ==
'\0');
55 std::copy_n(str, N - 1,
value.data());
58 [[nodiscard]]
constexpr size_t size()
const {
return value.size(); }
59 [[nodiscard]]
constexpr const char*
data()
const {
return value.data(); }
69 [[nodiscard]]
type operator()(
const void* p) {
return *
reinterpret_cast<const uint8_t*
>(p); }
83struct ErrorNotSupportedLoader;
84template<
size_t N>
struct SelectLoader
85 : std::conditional_t<N <= 1, Load8,
86 std::conditional_t<N <= 2, Load16,
87 std::conditional_t<N <= 4, Load32,
88 std::conditional_t<N <= 8, Load64,
89 ErrorNotSupportedLoader>>>> {};
92template<typename T> constexpr std::pair<T, T> calcValueMask(auto str)
96 int s = Endian::LITTLE ? 0 : (8 * (sizeof(T) - 1));
97 for (size_t i = 0; i < str.size(); ++i) {
98 v = T(v + (T(str.data()[i]) << s));
99 m = T(m + (T(255) << s));
100 s += Endian::LITTLE ? 8 : -8;
107template<StringLiteral Literal>
108[[nodiscard]] bool small_compare(const char* p)
110 using Loader = detail::SelectLoader<Literal.size()>;
111 using Type = typename Loader::type;
112 static constexpr auto vm = detail::calcValueMask<Type>(Literal);
113 auto [value, mask] = vm;
116 return (loader(p) & mask) == value;
119template<StringLiteral Literal>
120[[nodiscard]] bool small_compare(std::string_view str)
122 if (str.size() != Literal.size()) return false;
123 return small_compare<Literal>(str.data());
ALWAYS_INLINE uint64_t unalignedLoad64(const void *p)
ALWAYS_INLINE uint16_t unalignedLoad16(const void *p)
ALWAYS_INLINE uint32_t unalignedLoad32(const void *p)
constexpr const char * data() const
constexpr size_t size() const
std::array< char, N - 1 > value
constexpr StringLiteral(const char(&str)[N])
type operator()(const void *p)
type operator()(const void *p)
type operator()(const void *p)
type operator()(const void *p)