diff --git a/Source/utils/language.cpp b/Source/utils/language.cpp index e09dacd6b46..a94871791d9 100644 --- a/Source/utils/language.cpp +++ b/Source/utils/language.cpp @@ -14,6 +14,7 @@ #include "utils/file_util.h" #include "utils/log.hpp" #include "utils/paths.h" +#include "utils/string_view_hash.hpp" #ifdef USE_SDL1 #include "utils/sdl2_to_1_2_backports.h" @@ -37,23 +38,7 @@ std::unique_ptr translationValues; using TranslationRef = uint32_t; -struct StringHash { - using is_avalanching = void; - - [[nodiscard]] uint64_t operator()(const char *str) const noexcept - { - return ankerl::unordered_dense::hash {}(str); - } -}; - -struct StringEq { - bool operator()(const char *lhs, const char *rhs) const noexcept - { - return std::string_view(lhs) == std::string_view(rhs); - } -}; - -std::vector> translation = { {}, {} }; +std::vector> translation = { {}, {} }; constexpr uint32_t TranslationRefOffsetBits = 19; constexpr uint32_t TranslationRefSizeBits = 32 - TranslationRefOffsetBits; // 13 diff --git a/Source/utils/string_view_hash.hpp b/Source/utils/string_view_hash.hpp new file mode 100644 index 00000000000..e2cae2e618c --- /dev/null +++ b/Source/utils/string_view_hash.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include + +#include + +namespace devilution { + +// A hash functor that enables heterogenous lookup for `unordered_set/map`. +struct StringViewHash { + using is_transparent = void; + using is_avalanching = void; + + [[nodiscard]] uint64_t operator()(std::string_view str) const noexcept + { + return ankerl::unordered_dense::hash {}(str); + } + + [[nodiscard]] uint64_t operator()(const char *str) const noexcept + { + return (*this)(std::string_view { str }); + } + + [[nodiscard]] uint64_t operator()(const std::string &str) const noexcept + { + return (*this)(std::string_view { str }); + } +}; + +// Usually we'd use `std::equal_to<>` instead but the latter +// does not link on the libcxx that comes with Xbox NXDK as of Aug 2024, +struct StringViewEquals { + using is_transparent = void; + + [[nodiscard]] bool operator()(std::string_view a, std::string_view b) const { return a == b; } + [[nodiscard]] bool operator()(std::string_view a, const std::string &b) const { return a == b; } + [[nodiscard]] bool operator()(const std::string &a, std::string_view &b) const { return a == b; } + [[nodiscard]] bool operator()(const char *a, const std::string &b) const { return a == b; } + [[nodiscard]] bool operator()(const std::string &a, const char *b) const { return a == b; } + [[nodiscard]] bool operator()(std::string_view a, const char *b) const { return a == b; } + [[nodiscard]] bool operator()(const char *a, std::string_view b) const { return a == b; } + [[nodiscard]] bool operator()(const char *a, const char *b) const { return std::string_view { a } == b; } +}; + +} // namespace devilution