neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
map.hpp
Go to the documentation of this file.
1// map.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <map>
40#include <neolib/core/pair.hpp>
42#include <neolib/core/i_map.hpp>
43
44namespace neolib
45{
46 template <typename Key, typename T, typename Pr = std::less<Key>, typename Alloc = std::allocator<std::pair<const Key, T>>>
47 class map : public reference_counted<i_map<abstract_t<Key>, abstract_t<T>>>
48 {
49 typedef map<Key, T, Pr, Alloc> self_type;
51 // types
52 public:
54 typedef Key key_type;
55 typedef T mapped_type;
60 typedef Pr key_compare;
61 typedef Alloc allocator_type;
62 typedef std::map<key_type, value_type, key_compare, typename std::allocator_traits<allocator_type>::template rebind_alloc<std::pair<const key_type, value_type>>> std_type;
63 typedef typename std_type::value_type container_value_type;
64 public:
65 using typename abstract_type::size_type;
66 using typename abstract_type::const_iterator;
67 using typename abstract_type::iterator;
69 protected:
74 // construction
75 public:
76 map()
77 {
78 }
79 map(const map& aOther) :
80 iMap{ aOther.iMap }
81 {
82 }
83 map(map&& aOther) :
84 iMap{ std::move(aOther.iMap) }
85 {
86 }
87 map(const std::initializer_list<value_type>& aIlist)
88 {
89 for (auto& value : aIlist)
90 iMap.emplace(value.first(), value);
91 }
93 {
94 assign(aOther);
95 }
96 template <typename InputIter>
97 map(InputIter aFirst, InputIter aLast) :
98 iMap(aFirst, aLast)
99 {}
100 // assignment
101 public:
102 map& operator=(const map& aOther)
103 {
104 iMap = aOther.iMap;
105 return *this;
106 }
107 map& operator=(map&& aOther)
108 {
109 iMap = std::move(aOther.iMap);
110 return *this;
111 }
112 // non-asbtract operations
113 public:
114 const std_type& as_std_map() const { return iMap; }
115 std_type& as_std_map() { return iMap; }
116 std_type to_std_map() const { return iMap; }
117 // comparison
118 public:
119 constexpr bool operator==(const self_type& that) const noexcept
120 {
121 return as_std_map() == that.as_std_map();
122 }
123 constexpr std::partial_ordering operator<=>(const self_type& that) const noexcept
124 {
125 return as_std_map() <=> that.as_std_map();
126 }
127 // implementation
128 // from i_container
129 public:
130 size_type size() const noexcept final { return iMap.size(); }
131 size_type max_size() const noexcept final { return iMap.max_size(); }
132 void clear() final { iMap.clear(); }
133 void assign(const generic_container_type& aOther) final
134 {
135 if (&aOther == this)
136 return;
137 clear();
138 for (const_iterator i = aOther.begin(); i != aOther.end(); ++i)
139 iMap.insert(container_value_type{ key_type{ i->first() }, value_type{ key_type{i->first()}, mapped_type{i->second()} } });
140 }
141 // from i_map
142 public:
143 using abstract_type::insert;
144 using abstract_type::find;
145 // from i_container
146 private:
147 abstract_const_iterator* do_begin(void* memory) const final { return new (memory) container_const_iterator{ iMap.begin() }; }
148 abstract_const_iterator* do_end(void* memory) const final { return new (memory) container_const_iterator{ iMap.end() }; }
149 abstract_iterator* do_begin(void* memory) final { return new (memory) container_iterator{ iMap.begin() }; }
150 abstract_iterator* do_end(void* memory) final { return new (memory) container_iterator{ iMap.end() }; }
151 abstract_iterator* do_erase(void* memory, const abstract_const_iterator& aPosition) final { return new (memory) container_iterator{ iMap.erase(static_cast<const container_const_iterator&>(aPosition)) }; }
152 abstract_iterator* do_erase(void* memory, const abstract_const_iterator& aFirst, const abstract_const_iterator& aLast) final { return new (memory) container_iterator{ iMap.erase(static_cast<const container_const_iterator&>(aFirst), static_cast<const container_const_iterator&>(aLast)) }; }
153 // from i_map
154 public:
156 {
157 auto existing = iMap.find(aKey);
158 if (existing == iMap.end())
159 {
160 existing = iMap.insert(
161 typename std_type::value_type{
162 typename std_type::key_type{aKey},
163 typename std_type::mapped_type{
164 key_type{aKey},
165 mapped_type{}} }).first;
166 }
167 return existing->second.second();
168 }
169 const abstract_mapped_type& at(const abstract_key_type& aKey) const final
170 {
171 return iMap.at(aKey).second();
172 }
174 {
175 return iMap.at(aKey).second();
176 }
177 // own
178 public:
179 template <typename Key2, typename... Args>
180 value_type& emplace(Key2&& aKey, Args&&... aArgs)
181 {
182 auto result = iMap.emplace(std::forward<Key2>(aKey),
183 typename std_type::mapped_type{ aKey, mapped_type{ std::forward<Args>(aArgs)... } });
184 return result.first->second;
185 }
186 private:
187 abstract_iterator* do_insert(void* memory, const abstract_key_type& aKey, const abstract_mapped_type& aMapped) final
188 {
189 return new (memory) container_iterator{ iMap.insert(
190 typename std_type::value_type{
191 typename std_type::key_type{aKey},
192 typename std_type::mapped_type{
193 key_type{aKey},
194 mapped_type{aMapped}} }).first };
195 }
196 abstract_const_iterator* do_find(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.find(aKey) }; }
197 abstract_iterator* do_find(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.find(aKey) }; }
198 abstract_const_iterator* do_lower_bound(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.lower_bound(aKey) }; }
199 abstract_iterator* do_lower_bound(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.lower_bound(aKey) }; }
200 abstract_const_iterator* do_upper_bound(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.upper_bound(aKey) }; }
201 abstract_iterator* do_upper_bound(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.upper_bound(aKey) }; }
202 private:
203 std_type iMap;
204 };
205
206 template <typename Key, typename T, typename Pr = std::less<Key>, typename Alloc = std::allocator<std::pair<const Key, T>>>
207 class multimap : public reference_counted<i_multimap<abstract_t<Key>, abstract_t<T>>>
208 {
209 typedef multimap<Key, T, Pr, Alloc> self_type;
211 // types
212 public:
214 typedef Key key_type;
215 typedef T mapped_type;
220 typedef Pr key_compare;
221 typedef Alloc allocator_type;
222 typedef std::multimap<key_type, value_type, key_compare, typename std::allocator_traits<allocator_type>::template rebind_alloc<std::pair<const key_type, value_type>>> std_type;
223 typedef typename std_type::value_type container_value_type;
224 public:
225 using typename abstract_type::size_type;
226 using typename abstract_type::const_iterator;
227 using typename abstract_type::iterator;
229 protected:
234 // construction
235 public:
237 {
238 }
239 multimap(const multimap& aOther) :
240 iMap{ aOther.iMap }
241 {
242 }
243 multimap(multimap&& aOther) :
244 iMap{ std::move(aOther.iMap) }
245 {
246 }
247 multimap(const std::initializer_list<value_type>& aIlist)
248 {
249 for (auto& value : aIlist)
250 iMap.emplace(value.first(), value);
251 }
253 {
254 assign(aOther);
255 }
256 template <typename InputIter>
257 multimap(InputIter aFirst, InputIter aLast) :
258 iMap(aFirst, aLast)
259 {}
260 // assignment
261 public:
263 {
264 iMap = aOther.iMap;
265 return *this;
266 }
268 {
269 iMap = std::move(aOther.iMap);
270 return *this;
271 }
272 // non-asbtract operations
273 public:
274 const std_type& as_std_multimap() const { return iMap; }
275 std_type& as_std_multimap() { return iMap; }
276 std_type to_std_multimap() const { return iMap; }
277 // comparison
278 public:
279 constexpr bool operator==(const self_type& that) const noexcept
280 {
281 return as_std_multimap() == that.as_std_multimap();
282 }
283 constexpr std::partial_ordering operator<=>(const self_type& that) const noexcept
284 {
285 return as_std_multimap() <=> that.as_std_multimap();
286 }
287 // implementation
288 // from i_container
289 public:
290 size_type size() const noexcept final { return iMap.size(); }
291 size_type max_size() const noexcept final { return iMap.max_size(); }
292 void clear() final { iMap.clear(); }
293 void assign(const generic_container_type& aOther) final
294 {
295 if (&aOther == this)
296 return;
297 clear();
298 for (const_iterator i = aOther.begin(); i != aOther.end(); ++i)
299 iMap.insert(container_value_type{ key_type{ i->first() }, value_type{ key_type{i->first()}, mapped_type{i->second()} } });
300 }
301 // from i_multimap
302 public:
303 using abstract_type::insert;
304 using abstract_type::find;
305 // from i_container
306 private:
307 abstract_const_iterator* do_begin(void* memory) const final { return new (memory) container_const_iterator{ iMap.begin() }; }
308 abstract_const_iterator* do_end(void* memory) const final { return new (memory) container_const_iterator{ iMap.end() }; }
309 abstract_iterator* do_begin(void* memory) final { return new (memory) container_iterator{ iMap.begin() }; }
310 abstract_iterator* do_end(void* memory) final { return new (memory) container_iterator{ iMap.end() }; }
311 abstract_iterator* do_erase(void* memory, const abstract_const_iterator& aPosition) final { return new (memory) container_iterator(iMap.erase(static_cast<const container_const_iterator&>(aPosition))); }
312 abstract_iterator* do_erase(void* memory, const abstract_const_iterator& aFirst, const abstract_const_iterator& aLast) final { return new (memory) container_iterator(iMap.erase(static_cast<const container_const_iterator&>(aFirst), static_cast<const container_const_iterator&>(aLast))); }
313 // own
314 public:
315 template <typename Key2, typename... Args>
316 value_type& emplace(Key2&& aKey, Args&&... aArgs)
317 {
318 return iMap.emplace(std::forward<Key2>(aKey), typename std_type::mapped_type{ aKey, mapped_type{ std::forward<Args>(aArgs)... } })->second;
319 }
320 // from i_multimap
321 private:
322 abstract_iterator* do_insert(void* memory, const abstract_key_type& aKey, const abstract_mapped_type& aMapped) final
323 {
324 return new (memory) container_iterator{ iMap.insert(
325 typename std_type::value_type{
326 typename std_type::key_type{aKey},
327 typename std_type::mapped_type{
328 key_type{aKey},
329 mapped_type{aMapped}} }) };
330 }
331 abstract_const_iterator* do_find(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.find(aKey) }; }
332 abstract_iterator* do_find(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.find(aKey) }; }
333 abstract_const_iterator* do_lower_bound(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.lower_bound(aKey) }; }
334 abstract_iterator* do_lower_bound(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.lower_bound(aKey) }; }
335 abstract_const_iterator* do_upper_bound(void* memory, const abstract_key_type& aKey) const final { return new (memory) container_const_iterator{ iMap.upper_bound(aKey) }; }
336 abstract_iterator* do_upper_bound(void* memory, const abstract_key_type& aKey) final { return new (memory) container_iterator{ iMap.upper_bound(aKey) }; }
337 private:
338 std_type iMap;
339 };
340}
i_container< T, ConstIteratorType, IteratorType > generic_container_type
base_type::abstract_iterator abstract_iterator
Definition i_map.hpp:56
abstract_mapped_type & at(const abstract_key_type &aKey) final
Definition map.hpp:173
pair< const key_type, mapped_type > value_type
Definition map.hpp:56
T mapped_type
Definition map.hpp:55
map(map &&aOther)
Definition map.hpp:83
i_pair< const abstract_key_type, abstract_mapped_type > abstract_value_type
Definition map.hpp:59
container::const_iterator< value_type, typename std_type::const_iterator > container_const_iterator
Definition map.hpp:70
container::iterator< value_type, typename std_type::iterator, typename std_type::const_iterator > container_iterator
Definition map.hpp:71
i_map< abstract_t< Key >, abstract_t< T > > abstract_type
Definition map.hpp:53
map(InputIter aFirst, InputIter aLast)
Definition map.hpp:97
map & operator=(const map &aOther)
Definition map.hpp:102
Key key_type
Definition map.hpp:54
void assign(const generic_container_type &aOther) final
Definition map.hpp:133
value_type & emplace(Key2 &&aKey, Args &&... aArgs)
Definition map.hpp:180
map & operator=(map &&aOther)
Definition map.hpp:107
abstract_mapped_type & operator[](const abstract_key_type &aKey) final
Definition map.hpp:155
abstract_t< key_type > abstract_key_type
Definition map.hpp:57
std::map< key_type, value_type, key_compare, typename std::allocator_traits< allocator_type >::template rebind_alloc< std::pair< const key_type, value_type > > > std_type
Definition map.hpp:62
map(const map &aOther)
Definition map.hpp:79
map(const std::initializer_list< value_type > &aIlist)
Definition map.hpp:87
constexpr std::partial_ordering operator<=>(const self_type &that) const noexcept
Definition map.hpp:123
Pr key_compare
Definition map.hpp:60
abstract_type::abstract_const_iterator abstract_const_iterator
Definition map.hpp:72
void clear() final
Definition map.hpp:132
size_type max_size() const noexcept final
Definition map.hpp:131
constexpr bool operator==(const self_type &that) const noexcept
Definition map.hpp:119
map(const generic_container_type &aOther)
Definition map.hpp:92
const abstract_mapped_type & at(const abstract_key_type &aKey) const final
Definition map.hpp:169
abstract_t< mapped_type > abstract_mapped_type
Definition map.hpp:58
Alloc allocator_type
Definition map.hpp:61
size_type size() const noexcept final
Definition map.hpp:130
std_type::value_type container_value_type
Definition map.hpp:63
std_type & as_std_map()
Definition map.hpp:115
const std_type & as_std_map() const
Definition map.hpp:114
abstract_type::abstract_iterator abstract_iterator
Definition map.hpp:73
std_type to_std_map() const
Definition map.hpp:116
std_type to_std_multimap() const
Definition map.hpp:276
std::multimap< key_type, value_type, key_compare, typename std::allocator_traits< allocator_type >::template rebind_alloc< std::pair< const key_type, value_type > > > std_type
Definition map.hpp:222
constexpr bool operator==(const self_type &that) const noexcept
Definition map.hpp:279
void assign(const generic_container_type &aOther) final
Definition map.hpp:293
multimap(const multimap &aOther)
Definition map.hpp:239
multimap & operator=(multimap &&aOther)
Definition map.hpp:267
i_multimap< abstract_t< Key >, abstract_t< T > > abstract_type
Definition map.hpp:213
pair< const key_type, mapped_type > value_type
Definition map.hpp:216
i_pair< const abstract_key_type, abstract_mapped_type > abstract_value_type
Definition map.hpp:219
void clear() final
Definition map.hpp:292
abstract_type::abstract_iterator abstract_iterator
Definition map.hpp:233
Alloc allocator_type
Definition map.hpp:221
value_type & emplace(Key2 &&aKey, Args &&... aArgs)
Definition map.hpp:316
container::const_iterator< value_type, typename std_type::const_iterator > container_const_iterator
Definition map.hpp:230
multimap(InputIter aFirst, InputIter aLast)
Definition map.hpp:257
size_type max_size() const noexcept final
Definition map.hpp:291
abstract_t< mapped_type > abstract_mapped_type
Definition map.hpp:218
std_type::value_type container_value_type
Definition map.hpp:223
container::iterator< value_type, typename std_type::iterator, typename std_type::const_iterator > container_iterator
Definition map.hpp:231
multimap(multimap &&aOther)
Definition map.hpp:243
std_type & as_std_multimap()
Definition map.hpp:275
abstract_t< key_type > abstract_key_type
Definition map.hpp:217
multimap(const std::initializer_list< value_type > &aIlist)
Definition map.hpp:247
multimap & operator=(const multimap &aOther)
Definition map.hpp:262
constexpr std::partial_ordering operator<=>(const self_type &that) const noexcept
Definition map.hpp:283
abstract_type::abstract_const_iterator abstract_const_iterator
Definition map.hpp:232
const std_type & as_std_multimap() const
Definition map.hpp:274
multimap(const generic_container_type &aOther)
Definition map.hpp:252
size_type size() const noexcept final
Definition map.hpp:290
typename detail::abstract_type< T >::type abstract_t
Definition neolib.hpp:178
Definition plf_hive.h:79