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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
template <class Key, class T, class Hash = tinystl::hash<Key>, class KeyEqual = tinystl::equal_to<Key>> class unordered_map {
private: typedef tinystl::hashtable<tinystl::pair<const Key, T>, Hash, KeyEqual> base_type; base_type ht_;
public: typedef typename base_type::allocator_type allocator_type; typedef typename base_type::key_type key_type; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::value_type value_type; typedef typename base_type::hasher hasher; typedef typename base_type::key_equal key_equal;
typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference;
typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::local_iterator local_iterator; typedef typename base_type::const_local_iterator const_local_iterator;
allocator_type get_allocator() const { return ht_.get_allocator(); }
public: unordered_map() : ht_(100, hasher(), key_equal()) {}
explicit unordered_map(size_type bucket_count, const hasher& hash = hasher(), const key_equal& equal = key_equal()) : ht_(bucket_count, hash, equal) {}
template <class InputIterator> unordered_map(InputIterator first, InputIterator last, const size_type bucket_count = 100, const hasher& hash = hasher(), const key_equal& equal = key_equal()) : ht_(tinystl::max(bucket_count, static_cast<size_type>(tinystl::distance(first, last))), hash, equal) { for (; first != last; ++first) ht_.insert_unique_noresize(*first); }
unordered_map(std::initializer_list<value_type> ilist, const size_type bucket_count = 100, const hasher& hash = hasher(), const key_equal& equal = key_equal()) : ht_(tinystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal) { for (auto first = ilist.begin(); first != ilist.end(); ++first) ht_.insert_unique_noresize(*first); }
unordered_map(const unordered_map& rhs) : ht_(rhs.ht_) {}
unordered_map(unordered_map&& rhs) noexcept : ht_(tinystl::move(rhs.ht_)) {}
unordered_map& operator=(const unordered_map& rhs) { ht_ = rhs.ht_; return *this; }
unordered_map& operator=(unordered_map&& rhs) noexcept { ht_ = tinystl::move(rhs.ht_); return *this; }
unordered_map& operator=(std::initializer_list<value_type> ilist) { ht_.clear(); ht_.reserve(ilist.size()); for (auto first = ilist.begin(); first != ilist.end(); ++first) ht_.insert_unique_noresize(*first); return *this; }
~unordered_map() = default;
public: iterator begin() noexcept { return ht_.begin(); } const_iterator begin() const noexcept { return ht_.begin(); } iterator end() noexcept { return ht_.end(); } const_iterator end() const noexcept { return ht_.end(); }
const_iterator cbegin() const noexcept { return ht_.cbegin(); } const_iterator cend() const noexcept { return ht_.cend(); }
public: bool empty() const noexcept { return ht_.empty(); } size_type size() const noexcept { return ht_.size(); } size_type max_size() const noexcept { return ht_.max_size(); }
public: template <class... Args> tinystl::pair<iterator, bool> emplace(Args&&... args) { return ht_.emplace_unique(tinystl::forward<Args>(args)...); }
template <class... Args> iterator emplace_hint(const_iterator hint, Args&&... args) { return ht_.emplace_unique_use_hint(hint, tinystl::forward<Args>(args)...); }
tinystl::pair<iterator, bool> insert(const value_type& value) { return ht_.insert_unique(value); }
tinystl::pair<iterator, bool> insert(value_type&& value) { return ht_.insert_unique(tinystl::move(value)); }
iterator insert(const_iterator hint, const value_type& value) { return ht_.insert_unique_use_hint(hint, value); }
iterator insert(const_iterator hint, value_type&& value) { return ht_.insert_unique_use_hint(hint, tinystl::move(value)); }
template <class InputIterator> void insert(InputIterator first, InputIterator last) { ht_.insert_unique(first, last); }
void erase(iterator position) { ht_.erase(position); }
void erase(iterator first, iterator last) { ht_.erase(first, last); }
size_type erase(const key_type& key) { return ht_.erase_unique(key); }
void clear() { ht_.clear(); }
void swap(unordered_map& rhs) noexcept { ht_.swap(rhs.ht_); }
public: mapped_type& at(const key_type key) { auto it = ht_.find(key); THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists"); return it->second; }
const mapped_type& at(const key_type key) const { auto it = ht_.find(key); THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists"); return it->second; }
mapped_type& operator[](const key_type& key) { iterator it = ht_.find(key); if (it.node == nullptr) { it = ht_.emplace_unique(key, mapped_type()).first; } return it->second; }
mapped_type& operator[](key_type&& key) { iterator it = ht_.find(key); if (it.node == nullptr) { it = ht_.emplace_unique(tinystl::move(key), mapped_type()).first; } return it->second; }
size_type count(const key_type& key) const { return ht_.count(key); }
iterator find(const key_type& key) { return ht_.find(key); }
const_iterator find(const key_type& key) const { return ht_.find(key); }
tinystl::pair<iterator, iterator> equal_range(const key_type& key) { return ht_.equal_range_unique(key); }
tinystl::pair<const_iterator, const_iterator> equal_range(const key_type& key) const { return ht_.equal_range_unique(key); }
public: size_type bucket_count() const noexcept { return ht_.bucket_count(); } size_type max_bucket_count() const noexcept { return ht_.max_bucket_count(); }
size_type bucket_size(size_type n) const noexcept { return ht_.bucket_size(n); } size_type bucket(const key_type& key) const { return ht_.bucket(key); }
public: float load_factor() const noexcept { return ht_.load_factor(); } float max_load_factor() const noexcept { return ht_.max_load_factor(); } void max_load_factor(float ml) { ht_.max_load_factor(ml); }
void rehash(size_type count) { ht_.rehash(count); } void reserve(size_type count) { ht_.reserve(count); }
hasher hash_function() const { return ht_.hash_function(); } key_equal key_eq() const { return ht_.key_eq(); }
public: friend bool operator==(const unordered_map& lhs, const unordered_map& rhs) { return lhs.ht_.equal_range_unique(rhs.ht_); }
friend bool operator!=(const unordered_map& lhs, const unordered_map& rhs) { return !lhs.ht_.equal_range_unique(rhs.ht_); } };
template <class Key, class T, class Hash, class KeyEqual> bool operator==(const unordered_map<Key, T, Hash, KeyEqual>& lhs, const unordered_map<Key, T, Hash, KeyEqual>& rhs) { return lhs != rhs; }
template <class Key, class T, class Hash, class KeyEqual> bool operator!=(const unordered_map<Key, T, Hash, KeyEqual>& lhs, const unordered_map<Key, T, Hash, KeyEqual>& rhs) { return lhs != rhs; }
template <class Key, class T, class Hash, class KeyEqual> void swap(unordered_map<Key, T, Hash, KeyEqual>& lhs, unordered_map<Key, T, Hash, KeyEqual>& rhs) noexcept { lhs.swap(rhs); }
|