| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | // ==++== |
| 6 | // |
| 7 | |
| 8 | // |
| 9 | |
| 10 | // |
| 11 | // ==--== |
| 12 | |
| 13 | /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| 14 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| 15 | XX XX |
| 16 | XX unordered_map<K,V,H,P,A> XX |
| 17 | XX Derives from hashtable for most implementation. Inserted elements are XX |
| 18 | XX value pairs and the hash key is provided by the helper method that XX |
| 19 | XX extracts the key from the key value pair XX |
| 20 | XX XX |
| 21 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| 22 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| 23 | */ |
| 24 | |
| 25 | #pragma once |
| 26 | |
| 27 | #include "hashtable.h" |
| 28 | |
| 29 | namespace jitstd |
| 30 | { |
| 31 | |
| 32 | template <typename Key, typename Value> |
| 33 | struct pair_key |
| 34 | { |
| 35 | Key& operator()(const jitstd::pair<Key, Value>& pair) const |
| 36 | { |
| 37 | return pair.first; |
| 38 | } |
| 39 | }; |
| 40 | |
| 41 | template<typename Key, |
| 42 | typename Value, |
| 43 | typename Hash = jitstd::hash<Key>, |
| 44 | typename Pred = jitstd::equal_to<Key>, |
| 45 | typename Alloc = jitstd::allocator<jitstd::pair<const Key, Value> > > |
| 46 | class unordered_map |
| 47 | : public hashtable<Key, pair<const Key, Value>, Hash, Pred, Alloc, pair_key<const Key, Value>> |
| 48 | { |
| 49 | public: |
| 50 | |
| 51 | typedef Key key_type; |
| 52 | typedef Value mapped_type; |
| 53 | typedef jitstd::pair<const Key, Value> value_type; |
| 54 | typedef Hash hasher; |
| 55 | typedef Pred key_equal; |
| 56 | typedef Alloc allocator_type; |
| 57 | typedef typename allocator_type::pointer pointer; |
| 58 | typedef typename allocator_type::const_pointer const_pointer; |
| 59 | typedef typename allocator_type::reference reference; |
| 60 | typedef typename allocator_type::const_reference const_reference; |
| 61 | typedef size_t size_type; |
| 62 | typedef ptrdiff_t difference_type; |
| 63 | |
| 64 | explicit unordered_map(size_type size, const hasher& hasher, const key_equal& pred, const allocator_type& allocator); |
| 65 | explicit unordered_map(size_type size, const allocator_type& allocator); |
| 66 | template<typename InputIterator> |
| 67 | unordered_map(InputIterator, InputIterator, |
| 68 | size_type size, |
| 69 | const hasher& hasher, |
| 70 | const key_equal& pred, |
| 71 | const allocator_type& allocator); |
| 72 | |
| 73 | unordered_map(const unordered_map& map); |
| 74 | explicit unordered_map(const allocator_type& allocator); |
| 75 | unordered_map(const unordered_map& map, const allocator_type& allocator); |
| 76 | ~unordered_map(); |
| 77 | |
| 78 | unordered_map& operator=(unordered_map const&); |
| 79 | mapped_type& operator[](const Key& key); |
| 80 | mapped_type& operator[](key_type&& key); |
| 81 | |
| 82 | typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator insert(const key_type& key, const mapped_type& value); |
| 83 | |
| 84 | private: |
| 85 | typedef hashtable<Key, pair<const Key, Value>, Hash, Pred, Alloc, pair_key<const Key, Value>> base_type; |
| 86 | }; |
| 87 | |
| 88 | } |
| 89 | |
| 90 | |
| 91 | namespace jitstd |
| 92 | { |
| 93 | |
| 94 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 95 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(size_type size, const hasher& hasher, const key_equal& pred, const allocator_type& allocator) |
| 96 | : base_type(size, hasher, pred, allocator) |
| 97 | { |
| 98 | } |
| 99 | |
| 100 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 101 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(size_type size, const allocator_type& allocator) |
| 102 | : base_type(size, allocator) |
| 103 | { |
| 104 | } |
| 105 | |
| 106 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 107 | template<typename InputIterator> |
| 108 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(InputIterator first, InputIterator last, |
| 109 | size_type size, |
| 110 | const hasher& hasher, |
| 111 | const key_equal& pred, |
| 112 | const allocator_type& allocator) |
| 113 | : base_type(first, last, size, hasher, pred, allocator) |
| 114 | { |
| 115 | } |
| 116 | |
| 117 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 118 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const unordered_map& map) |
| 119 | : base_type(map) |
| 120 | { |
| 121 | } |
| 122 | |
| 123 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 124 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const allocator_type& allocator) |
| 125 | : base_type(allocator) |
| 126 | { |
| 127 | } |
| 128 | |
| 129 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 130 | unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const unordered_map& map, const allocator_type& allocator) |
| 131 | : base_type(map, allocator) |
| 132 | { |
| 133 | } |
| 134 | |
| 135 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 136 | unordered_map<Key, Value, Hash, Pred, Alloc>::~unordered_map() |
| 137 | { |
| 138 | } |
| 139 | |
| 140 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 141 | unordered_map<Key, Value, Hash, Pred, Alloc>& unordered_map<Key, Value, Hash, Pred, Alloc>::operator=(const unordered_map& map) |
| 142 | { |
| 143 | base_type::operator=(map); |
| 144 | return *this; |
| 145 | } |
| 146 | |
| 147 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 148 | Value& unordered_map<Key, Value, Hash, Pred, Alloc>::operator[](const Key& key) |
| 149 | { |
| 150 | typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator iter = base_type::find(key, this->key_eq()); |
| 151 | if (iter == this->end()) |
| 152 | { |
| 153 | iter = base_type::insert(jitstd::pair<const Key, mapped_type>(key, mapped_type())).first; |
| 154 | } |
| 155 | return (*iter).second; |
| 156 | } |
| 157 | |
| 158 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 159 | Value& unordered_map<Key, Value, Hash, Pred, Alloc>::operator[](key_type&& key) |
| 160 | { |
| 161 | typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator iter = base_type::find(key, this->key_eq()); |
| 162 | if (iter == this->end()) |
| 163 | { |
| 164 | iter = base_type::insert(jitstd::pair<const Key, mapped_type>(key, mapped_type())).first; |
| 165 | } |
| 166 | return (*iter).second; |
| 167 | } |
| 168 | |
| 169 | |
| 170 | template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc> |
| 171 | typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator |
| 172 | unordered_map<Key, Value, Hash, Pred, Alloc>::insert(const key_type& key, const mapped_type& value) |
| 173 | { |
| 174 | typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator iter = base_type::find(key, this->key_eq()); |
| 175 | iter = base_type::insert(jitstd::pair<const Key, mapped_type>(key, value)).first; |
| 176 | return iter; |
| 177 | } |
| 178 | |
| 179 | } |
| 180 | |