Support for case insensitive ConstString.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
ec728e7d68
commit
efec26fe68
|
@ -16,13 +16,29 @@ namespace Arbutils {
|
||||||
inline static uint32_t constexpr Hash(char const* input) {
|
inline static uint32_t constexpr Hash(char const* input) {
|
||||||
return (*input) ? static_cast<uint32_t>((*input)) + 33 * Hash(input + 1) : 5381;
|
return (*input) ? static_cast<uint32_t>((*input)) + 33 * Hash(input + 1) : 5381;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; }
|
||||||
|
inline static uint32_t constexpr LowercaseHash(char const* input) {
|
||||||
|
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * LowercaseHash(input + 1) : 5381;
|
||||||
|
}
|
||||||
|
|
||||||
inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; }
|
inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; }
|
||||||
|
|
||||||
|
constexpr explicit ConstString(const char* str, bool)
|
||||||
|
: _str(str), _length(Length(str)), _hash(LowercaseHash(str)){};
|
||||||
|
constexpr explicit ConstString(const char* str, size_t size, bool)
|
||||||
|
: _str(str), _length(size), _hash(LowercaseHash(str)){};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr ConstString() : _str(""), _length(0), _hash(Hash("")){};
|
constexpr ConstString() : _str(""), _length(0), _hash(Hash("")){};
|
||||||
constexpr explicit ConstString(const char* str) : _str(str), _length(Length(str)), _hash(Hash(str)){};
|
constexpr explicit ConstString(const char* str) : _str(str), _length(Length(str)), _hash(Hash(str)){};
|
||||||
constexpr explicit ConstString(const char* str, size_t size) : _str(str), _length(size), _hash(Hash(str)){};
|
constexpr explicit ConstString(const char* str, size_t size) : _str(str), _length(size), _hash(Hash(str)){};
|
||||||
|
|
||||||
|
static constexpr inline ConstString CaseInsensitive(const char* str) { return ConstString(str, true); }
|
||||||
|
static constexpr inline ConstString CaseInsensitive(const char* str, size_t size) {
|
||||||
|
return ConstString(str, size, true);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline constexpr const char* c_str() const noexcept { return _str; }
|
[[nodiscard]] inline constexpr const char* c_str() const noexcept { return _str; }
|
||||||
[[nodiscard]] inline std::string std_str() const { return std::string(_str, _length); }
|
[[nodiscard]] inline std::string std_str() const { return std::string(_str, _length); }
|
||||||
|
|
||||||
|
@ -33,20 +49,20 @@ namespace Arbutils {
|
||||||
constexpr std::size_t operator()(ConstString const& s) const noexcept { return s.GetHash(); }
|
constexpr std::size_t operator()(ConstString const& s) const noexcept { return s.GetHash(); }
|
||||||
inline constexpr operator uint32_t() const { return _hash; }
|
inline constexpr operator uint32_t() const { return _hash; }
|
||||||
|
|
||||||
inline constexpr bool operator==(const ConstString& rhs) const{
|
inline constexpr bool operator==(const ConstString& rhs) const { return _hash == rhs._hash; }
|
||||||
return _hash == rhs._hash;
|
inline constexpr bool operator!=(const ConstString& rhs) const { return _hash != rhs._hash; }
|
||||||
}
|
|
||||||
inline constexpr bool operator!=(const ConstString& rhs) const{
|
|
||||||
return _hash != rhs._hash;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr Arbutils::ConstString operator"" _const(const char* c, size_t l) {
|
inline constexpr Arbutils::ConstString operator"" _const(const char* c, size_t l) {
|
||||||
return Arbutils::ConstString(c, l);
|
return Arbutils::ConstString(c, l);
|
||||||
}
|
}
|
||||||
inline constexpr Arbutils::ConstString operator"" _c(const char* c, size_t l) {
|
inline constexpr Arbutils::ConstString operator"" _c(const char* c, size_t l) { return Arbutils::ConstString(c, l); }
|
||||||
return Arbutils::ConstString(c, l);
|
inline constexpr Arbutils::ConstString operator"" _const_nocase(const char* c, size_t l) {
|
||||||
|
return Arbutils::ConstString::CaseInsensitive(c, l);
|
||||||
|
}
|
||||||
|
inline constexpr Arbutils::ConstString operator"" _cnc(const char* c, size_t l) {
|
||||||
|
return Arbutils::ConstString::CaseInsensitive(c, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
|
@ -23,4 +23,24 @@ TEST_CASE("Use const string in switch case", "[Utilities]") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Use insensitive const string in unordered_map", "[Utilities]") {
|
||||||
|
std::unordered_map<Arbutils::ConstString, int32_t> map;
|
||||||
|
map.insert({"foO"_cnc, 1});
|
||||||
|
map.insert({"bAR"_cnc, 5});
|
||||||
|
|
||||||
|
CHECK(map["bar"_cnc] == 5);
|
||||||
|
CHECK(map["foo"_cnc] == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Use case insensitive const string in switch case", "[Utilities]") {
|
||||||
|
auto val = Arbutils::ConstString::CaseInsensitive("foobar");
|
||||||
|
switch (val){
|
||||||
|
case "foo"_cnc: FAIL(); break;
|
||||||
|
case "bar"_cnc: FAIL(); break;
|
||||||
|
case "FOObAr"_cnc: SUCCEED(); break;
|
||||||
|
default: FAIL(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue