#pragma once #include #include #include #include #include #include #include #include #include namespace std { template <> struct less { bool operator()(const char* x, const char* y) const { return strcmp(x, y) < 0; } }; template <> struct equal_to { bool operator()(const char* x, const char* y) const { return strcmp(x, y) == 0; } bool operator()(const char* x, const TStringBuf y) const { return strlen(x) == y.size() && memcmp(x, y.data(), y.size()) == 0; } using is_transparent = void; }; } namespace NHashPrivate { template struct THashHelper { inline size_t operator()(const T& t) const noexcept { return (size_t)t; // If you have a compilation error here, look at explanation below: // Probably error is caused by undefined template specialization of THash // You can find examples of specialization in this file } }; template struct THashHelper { inline size_t operator()(const T& t) const noexcept { return NumericHash(t); } }; template struct TStringHash { using is_transparent = void; inline size_t operator()(const TBasicStringBuf s) const noexcept { return NHashPrivate::ComputeStringHash(s.data(), s.size()); } }; } template struct hash: public NHashPrivate::THashHelper::value && !std::is_integral::value> { }; template struct hash { inline size_t operator()(const T* t) const noexcept { return NumericHash(t); } }; template struct hash: public ::hash { }; template <> struct hash: ::NHashPrivate::TStringHash { }; template struct hash: ::NHashPrivate::TStringHash { }; template <> struct THash: ::NHashPrivate::TStringHash { }; template <> struct THash: ::NHashPrivate::TStringHash { }; template <> struct hash: ::NHashPrivate::TStringHash { }; template <> struct hash: ::NHashPrivate::TStringHash { }; template <> struct THash: ::NHashPrivate::TStringHash { }; template <> struct hash: ::NHashPrivate::TStringHash { }; template <> struct THash: ::NHashPrivate::TStringHash { }; template struct hash>: ::NHashPrivate::TStringHash { }; template <> struct THash { inline size_t operator()(const std::type_index& index) const { return index.hash_code(); } }; namespace NHashPrivate { template Y_FORCE_INLINE static size_t HashObject(const T& val) { return THash()(val); } template struct TupleHashHelper { Y_FORCE_INLINE static size_t Hash(const std::tuple& tuple) { return CombineHashes(HashObject(std::get(tuple)), TupleHashHelper= sizeof...(TArgs), TArgs...>::Hash(tuple)); } }; template struct TupleHashHelper { Y_FORCE_INLINE static size_t Hash(const std::tuple& tuple) { return HashObject(std::get(tuple)); } }; } template struct THash> { size_t operator()(const std::tuple& tuple) const { return NHashPrivate::TupleHashHelper<0, 1 >= sizeof...(TArgs), TArgs...>::Hash(tuple); } }; template struct THash: public ::hash { }; namespace NHashPrivate { template >::value&& std::is_empty>::value> struct TPairHash { private: THash FirstHash; THash SecondHash; public: template inline size_t operator()(const T& pair) const { return CombineHashes(FirstHash(pair.first), SecondHash(pair.second)); } }; /** * Specialization for the case where both hash functors are empty. Basically the * only one we care about. We don't introduce additional specializations for * cases where only one of the functors is empty as the code bloat is just not worth it. */ template struct TPairHash { template inline size_t operator()(const T& pair) const { // maps have TFirst = const TFoo, which would make for an undefined specialization using TFirstClean = std::remove_cv_t; using TSecondClean = std::remove_cv_t; return CombineHashes(THash()(pair.first), THash()(pair.second)); } }; } template struct hash>: public NHashPrivate::TPairHash { }; template struct TEqualTo: public std::equal_to { }; template <> struct TEqualTo: public TEqualTo { using is_transparent = void; }; template <> struct TEqualTo: public TEqualTo { using is_transparent = void; }; template <> struct TEqualTo: public TEqualTo { using is_transparent = void; }; template struct TEqualTo> { template inline bool operator()(const std::pair& a, const TOther& b) const { return TEqualTo()(a.first, b.first) && TEqualTo()(a.second, b.second); } using is_transparent = void; }; template struct TCIEqualTo { }; template <> struct TCIEqualTo { inline bool operator()(const char* a, const char* b) const { return stricmp(a, b) == 0; } }; template <> struct TCIEqualTo { inline bool operator()(const TStringBuf a, const TStringBuf b) const { return a.size() == b.size() && strnicmp(a.data(), b.data(), a.size()) == 0; } }; template <> struct TCIEqualTo { inline bool operator()(const TString& a, const TString& b) const { return a.size() == b.size() && strnicmp(a.data(), b.data(), a.size()) == 0; } }; template struct TLess: public std::less { }; template <> struct TLess: public TLess { using is_transparent = void; }; template <> struct TLess: public TLess { using is_transparent = void; }; template <> struct TLess: public TLess { using is_transparent = void; }; template struct TGreater: public std::greater { }; template <> struct TGreater: public TGreater { using is_transparent = void; }; template <> struct TGreater: public TGreater { using is_transparent = void; }; template <> struct TGreater: public TGreater { using is_transparent = void; };