#pragma once #include #include #include template struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; }; template <> struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; bool isZero(const HashTableNoState & state) const { return isZero(this->key, state); } // Zero means unoccupied cells in hash table. Use key with last word = 0 as // zero keys, because such keys are unrepresentable (no way to encode length). static bool isZero(const StringKey16 & key_, const HashTableNoState &) { return key_.items[1] == 0; } void setZero() { this->key.items[1] = 0; } }; template <> struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; bool isZero(const HashTableNoState & state) const { return isZero(this->key, state); } // Zero means unoccupied cells in hash table. Use key with last word = 0 as // zero keys, because such keys are unrepresentable (no way to encode length). static bool isZero(const StringKey24 & key_, const HashTableNoState &) { return key_.c == 0; } void setZero() { this->key.c = 0; } }; template <> struct StringHashSetCell : public HashSetCellWithSavedHash { using Base = HashSetCellWithSavedHash; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; }; template struct StringHashSetSubMaps { using T0 = StringHashTableEmpty>; using T1 = HashSetTable, StringHashTableHash, StringHashTableGrower<>, Allocator>; using T2 = HashSetTable, StringHashTableHash, StringHashTableGrower<>, Allocator>; using T3 = HashSetTable, StringHashTableHash, StringHashTableGrower<>, Allocator>; using Ts = HashSetTable, StringHashTableHash, StringHashTableGrower<>, Allocator>; }; template class StringHashSet : public StringHashTable> { public: using Key = StringRef; using Base = StringHashTable>; using Self = StringHashSet; using LookupResult = typename Base::LookupResult; using Base::Base; template void ALWAYS_INLINE emplace(KeyHolder && key_holder, bool & inserted) { LookupResult it; Base::emplace(key_holder, it, inserted); } };