1#ifndef SMALL_COMPARE_HH
2#define SMALL_COMPARE_HH
56 assert(str[N - 1] ==
'\0');
57 std::copy_n(str, N - 1,
value.data());
60 [[nodiscard]]
constexpr size_t size()
const {
return value.size(); }
61 [[nodiscard]]
constexpr const char*
data()
const {
return value.data(); }
71 [[nodiscard]]
type operator()(
const void* p)
const {
return *std::bit_cast<const uint8_t*>(p); }
85struct ErrorNotSupportedLoader;
86template<
size_t N>
struct SelectLoader
87 : std::conditional_t<N <= 1, Load8,
88 std::conditional_t<N <= 2, Load16,
89 std::conditional_t<N <= 4, Load32,
90 std::conditional_t<N <= 8, Load64,
91 ErrorNotSupportedLoader>>>> {};
94template<typename T> constexpr std::pair<T, T> calcValueMask(auto str)
98 int s = Endian::LITTLE ? 0 : (8 * (sizeof(T) - 1));
99 for (size_t i = 0; i < str.size(); ++i) {
100 v = T(v + (T(str.data()[i]) << s));
101 m = T(m + (T(255) << s));
102 s += Endian::LITTLE ? 8 : -8;
109template<StringLiteral Literal>
110[[nodiscard]] bool small_compare(const char* p)
112 using Loader = detail::SelectLoader<Literal.size()>;
113 using Type = typename Loader::type;
114 static constexpr auto vm = detail::calcValueMask<Type>(Literal);
115 auto [value, mask] = vm;
118 return (loader(p) & mask) == value;
121template<StringLiteral Literal>
122[[nodiscard]] bool small_compare(std::string_view str)
124 if (str.size() != Literal.size()) return false;
125 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) const
type operator()(const void *p) const
type operator()(const void *p) const
type operator()(const void *p) const