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
14XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15XX XX
16XX unordered_map<K,V,H,P,A> XX
17XX Derives from hashtable for most implementation. Inserted elements are XX
18XX value pairs and the hash key is provided by the helper method that XX
19XX extracts the key from the key value pair XX
20XX XX
21XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
22XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
23*/
24
25#pragma once
26
27#include "hashtable.h"
28
29namespace jitstd
30{
31
32template <typename Key, typename Value>
33struct pair_key
34{
35 Key& operator()(const jitstd::pair<Key, Value>& pair) const
36 {
37 return pair.first;
38 }
39};
40
41template<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> > >
46class unordered_map
47 : public hashtable<Key, pair<const Key, Value>, Hash, Pred, Alloc, pair_key<const Key, Value>>
48{
49public:
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
84private:
85 typedef hashtable<Key, pair<const Key, Value>, Hash, Pred, Alloc, pair_key<const Key, Value>> base_type;
86};
87
88}
89
90
91namespace jitstd
92{
93
94template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
95unordered_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
100template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
101unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(size_type size, const allocator_type& allocator)
102 : base_type(size, allocator)
103{
104}
105
106template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
107template<typename InputIterator>
108unordered_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
117template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
118unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const unordered_map& map)
119 : base_type(map)
120{
121}
122
123template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
124unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const allocator_type& allocator)
125 : base_type(allocator)
126{
127}
128
129template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
130unordered_map<Key, Value, Hash, Pred, Alloc>::unordered_map(const unordered_map& map, const allocator_type& allocator)
131 : base_type(map, allocator)
132{
133}
134
135template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
136unordered_map<Key, Value, Hash, Pred, Alloc>::~unordered_map()
137{
138}
139
140template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
141unordered_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
147template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
148Value& 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
158template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
159Value& 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
170template<typename Key, typename Value, typename Hash, typename Pred, typename Alloc>
171typename unordered_map<Key, Value, Hash, Pred, Alloc>::iterator
172unordered_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