summaryrefslogtreecommitdiff
path: root/asl/hash_map.hpp
blob: 310b5324e6ffafe57168453e691f7bf9dd25ce62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#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<typename K, typename V>
struct Slot
{
    K key;
    V value;
};

template<hashable K, typename V, key_hasher<K> KeyHasher>
struct SlotHasher : public KeyHasher
{
    using KeyHasher::hash;
    
    constexpr static uint64_t hash(const Slot<K, V>& slot)
    {
        return KeyHasher::hash(slot.key);
    }
};

template<equality_comparable K, typename V, key_comparator<K> KeyComparator>
struct SlotComparator : public KeyComparator
{
    using KeyComparator::eq;

    constexpr static bool eq(const Slot<K, V>& a, const Slot<K, V>& b)
    {
        return KeyComparator::eq(a.key, b.key);
    }

    constexpr static bool eq(const Slot<K, V>& 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<K> KeyHasher = default_key_hasher<K>,
    key_comparator<K> KeyComparator = default_key_comparator<K>
>
requires moveable<K> && moveable<V>
class hash_map : hash_set<
    hash_map_internal::Slot<K, V>,
    Allocator,
    hash_map_internal::SlotHasher<K, V, KeyHasher>,
    hash_map_internal::SlotComparator<K, V, KeyComparator>>
{
    using Base = 
        hash_set<
            hash_map_internal::Slot<K, V>,
            Allocator,
            hash_map_internal::SlotHasher<K, V, KeyHasher>,
            hash_map_internal::SlotComparator<K, V, KeyComparator>>;

public:
    constexpr hash_map() requires default_constructible<Allocator> = default;

    explicit constexpr hash_map(Allocator allocator)
        : Base{ASL_MOVE(allocator)}
    {}

    hash_map(const hash_map&) requires copyable<K> && copyable<V> = default;
    
    hash_map& operator=(const hash_map&) requires copyable<K> && copyable<V> = 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