// C++20 demo: Heterogeneous lookup for unordered containers (transparent hashing) // https://en.cppreference.com/w/cpp/container/unordered_map/find #pragma once #include #include #include #include #include #include #include "tsl/robin_map.h" #include "tsl/robin_set.h" using namespace std::string_literals; using namespace std::string_view_literals; namespace hlookup { struct string_hash { using hash_type = std::hash; using is_transparent = void; size_t operator()(const char* str) const { return hash_type{}(str); } size_t operator()(std::string_view str) const { return hash_type{}(str); } size_t operator()(std::string const& str) const { return hash_type{}(str); } }; struct equal_to { template constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const noexcept(noexcept(static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right))) // strengthened -> decltype(static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right)) { return static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right); } using is_transparent = int; }; template using stl_string_map = std::map>; using stl_string_set = std::set>; template using string_map = tsl::robin_map; using string_set = tsl::robin_set; template inline auto set_item(_Cont& cont, std::string_view key, _Valty&& _Val) { typename _Cont::iterator it = cont.find(key); if (it != cont.end()) it.value() = std::move(_Val); else it = cont.emplace(std::string{key}, std::forward<_Valty>(_Val)).first; return it; } constexpr auto empty_sv = ""sv; } // namespace hlookup