2#include <ossia/detail/config.hpp>
5#include <ossia/detail/hash.hpp>
6#include <ossia/detail/hash_map.hpp>
10static constexpr unsigned char ascii_tolower(
unsigned char c)
noexcept
12 constexpr unsigned char A =
'A', Z =
'Z', a =
'a';
19struct ascii_tolower_less
21 constexpr bool operator()(
unsigned char c1,
unsigned char c2)
const noexcept
23 return ascii_tolower(c1) < ascii_tolower(c2);
27struct ascii_tolower_equal
29 constexpr bool operator()(
unsigned char c1,
unsigned char c2)
const noexcept
31 return ascii_tolower(c1) == ascii_tolower(c2);
35struct case_insensitive_comparator
37 using is_transparent = std::true_type;
38 bool operator()(std::string_view s1, std::string_view s2)
const noexcept
40 return std::lexicographical_compare(
41 s1.begin(), s1.end(), s2.begin(), s2.end(), ascii_tolower_less{});
45struct case_insensitive_hash
47 static constexpr int buffer_size = 64;
48 using is_transparent = std::true_type;
49 using is_avalanching = std::true_type;
51 uint64_t operator()(std::string_view s1)
const noexcept
54 uint64_t res = UINT64_C(0xff51afd7ed558ccd);
55 unsigned char buf[buffer_size + 1];
56 const char* ptr = s1.data();
57 uint64_t remaining = s1.size();
61 if(remaining >= buffer_size)
63 for(
int i = 0; i < buffer_size; i++)
64 buf[i] = ascii_tolower(ptr[i]);
65 res = rapidhash_withSeed(buf, buffer_size, res);
66 remaining -= buffer_size;
72 for(uint64_t i = 0; i < remaining; i++)
73 buf[i] = ascii_tolower(ptr[i]);
74 res = rapidhash_withSeed(buf, remaining, res);
83struct case_insensitive_equal
85 using is_transparent = std::true_type;
86 constexpr bool operator()(std::string_view s1, std::string_view s2)
const noexcept
88 return std::equal(s1.begin(), s1.end(), s2.begin(), s2.end(), ascii_tolower_equal{});
92template <
typename Value>
93using case_insensitive_string_map
94 = ossia::hash_map<std::string, Value, case_insensitive_hash, case_insensitive_equal>;