#pragma once #include "asl/annotations.hpp" #include "asl/meta.hpp" #include "asl/utility.hpp" #include "asl/maybe_uninit.hpp" #include "asl/hash.hpp" #include "asl/allocator.hpp" #include "asl/memory.hpp" #include "asl/hash_set.hpp" namespace asl { namespace hash_map_internal { template struct Slot { K key; V value; }; template KeyHasher> struct SlotHasher : public KeyHasher { using KeyHasher::hash; constexpr static uint64_t hash(const Slot& slot) { return KeyHasher::hash(slot.key); } }; template KeyComparator> struct SlotComparator : public KeyComparator { using KeyComparator::eq; constexpr static bool eq(const Slot& a, const Slot& b) { return KeyComparator::eq(a.key, b.key); } constexpr static bool eq(const Slot& a, const K& b) { return KeyComparator::eq(a.key, b); } }; } // namespace hash_map_internal template< is_object K, is_object V, allocator Allocator = DefaultAllocator, key_hasher KeyHasher = default_key_hasher, key_comparator KeyComparator = default_key_comparator > requires moveable && moveable class hash_map : hash_set< hash_map_internal::Slot, Allocator, hash_map_internal::SlotHasher, hash_map_internal::SlotComparator> { using Base = hash_set< hash_map_internal::Slot, Allocator, hash_map_internal::SlotHasher, hash_map_internal::SlotComparator>; public: constexpr hash_map() requires default_constructible = default; explicit constexpr hash_map(Allocator allocator) : Base{ASL_MOVE(allocator)} {} hash_map(const hash_map&) requires copyable && copyable = default; hash_map& operator=(const hash_map&) requires copyable && copyable = default; hash_map(hash_map&&) = default; hash_map& operator=(hash_map&&) = default; ~hash_map() = default; using Base::destroy; using Base::clear; using Base::size; // @Todo insert // @Todo contains // @Todo remove // @Todo get // @Todo tests }; } // namespace asl