DeSiGNAR  0.5a
Data Structures General Library
map.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef DSGMAP_H
26 # define DSGMAP_H
27 
28 # include <set.H>
29 
30 namespace Designar
31 {
32  template <typename Key, typename Value>
33  using MapKey = std::pair<Key, Value>;
34 
35  template <typename Key, typename Value>
37 
38  template <typename... Args>
39  auto map_key(Args &&... args) ->
40  decltype(std::make_pair(std::forward<Args>(args)...))
41  {
42  return std::make_pair(std::forward<Args>(args)...);
43  }
44 
45  template <typename... Args>
46  auto map_item(Args &&... args) ->
47  decltype(std::make_pair(std::forward<Args>(args)...))
48  {
49  return std::make_pair(std::forward<Args>(args)...);
50  }
51 
52  template <typename Key, typename Value>
53  Key & key(MapKey<Key, Value> & item)
54  {
55  return item.first;
56  }
57 
58  template <typename Key, typename Value>
59  const Key & key(const MapKey<Key, Value> & item)
60  {
61  return item.first;
62  }
63 
64  template <typename Key, typename Value>
65  Key key(MapKey<Key, Value> && item)
66  {
67  return item.first;
68  }
69 
70  template <typename Key, typename Value>
71  Key & key(MapKey<Key, Value> * item_ptr)
72  {
73  return key(*item_ptr);
74  }
75 
76  template <typename Key, typename Value>
77  Value & value(MapKey<Key, Value> & item)
78  {
79  return item.second;
80  }
81 
82  template <typename Key, typename Value>
83  const Value & value(const MapKey<Key, Value> & item)
84  {
85  return item.second;
86  }
87 
88  template <typename Key, typename Value>
89  Value value(MapKey<Key, Value> && item)
90  {
91  return item.second;
92  }
93 
94  template <typename Key, typename Value>
95  Value & value(MapKey<Key, Value> * item_ptr)
96  {
97  return value(*item_ptr);
98  }
99 
100  template <typename Key, typename Value, class Cmp>
102  {
103  Cmp & cmp;
104 
105  public:
106  CmpWrapper(Cmp & _cmp)
107  : cmp(_cmp)
108  {
109  // empty
110  }
111 
112  CmpWrapper(Cmp && _cmp = Cmp())
113  : CmpWrapper(_cmp)
114  {
115  // empty
116  }
117 
118  CmpWrapper(const CmpWrapper & cw)
119  : cmp(cw.cmp)
120  {
121  // empty
122  }
123 
125  : CmpWrapper()
126  {
127  std::swap(cmp, cw.cmp);
128  }
129 
130  Cmp & get_cmp()
131  {
132  return cmp;
133  }
134 
135  const Cmp & get_cmp() const
136  {
137  return cmp;
138  }
139 
141  {
142  if (this == &cw)
143  return *this;
144 
145  cmp = cw.cmp;
146  return *this;
147  }
148 
150  {
151  std::swap(cmp, cw.cmp);
152  return *this;
153  }
154 
156  const MapKey<Key, Value> & q) const
157  {
158  return cmp(p.first, q.first);
159  }
160  };
161 
162 
163  template <typename Key, typename Value, class Cmp, class BaseSet>
164  class GenMap :
165  public BaseSet
166  {
167  using Item = MapKey<Key, Value>;
168  using BaseSet::BaseSet;
169 
170  public:
171  using KeyType = Key;
172  using ValueType = Value;
173  using SizeType = nat_t;
174  using CmpType = Cmp;
175 
176  Cmp & get_cmp()
177  {
178  return BaseSet::get_cmp().get_cmp();
179  }
180 
181  const Cmp & get_cmp() const
182  {
183  return BaseSet::get_cmp().get_cmp();
184  }
185 
186  Value * insert(const Key & k, const Value & v)
187  {
188  Item p = map_key(k, v);
189 
190  Item * result = BaseSet::insert(std::move(p));
191 
192  if (result == nullptr)
193  return nullptr;
194 
195  return &result->second;
196  }
197 
198  Value * insert(Key && k, const Value & v)
199  {
200  Item p = map_key(std::forward<Key>(k), v);
201 
202  Item * result = BaseSet::insert(std::move(p));
203 
204  if (result == nullptr)
205  return nullptr;
206 
207  return &result->second;
208  }
209 
210  Value * insert(const Key & k, Value && v)
211  {
212  Item p = map_key(k, std::forward<Value>(v));
213 
214  Item * result = BaseSet::insert(std::move(p));
215 
216  if (result == nullptr)
217  return nullptr;
218 
219  return &result->second;
220  }
221 
222  Value * insert(Key && k, Value && v)
223  {
224  Item p = map_key(std::forward<Key>(k), std::forward<Value>(v));
225 
226  Item * result = BaseSet::insert(std::move(p));
227 
228  if (result == nullptr)
229  return nullptr;
230 
231  return &result->second;
232  }
233 
234  Value * append(const Key & k, const Value & v)
235  {
236  return insert(k, v);
237  }
238 
239  Value * append(Key && k, const Value & v)
240  {
241  return insert(std::forward<Key>(k), v);
242  }
243 
244  Value * append(const Key & k, Value && v)
245  {
246  return insert(k, std::forward<Value>(v));
247  }
248 
249  Value * append(Key && k, Value && v)
250  {
251  return insert(std::forward<Key>(k), std::forward<Value>(v));
252  }
253 
254  Value * search(const Key & k)
255  {
256  Item p = map_key(k, Value());
257 
258  Item * result = BaseSet::search(p);
259 
260  if (result == nullptr)
261  return nullptr;
262 
263  return &result->second;
264  }
265 
266  Value * search(Key && k)
267  {
268  Item p = map_key(std::forward<Key>(k), Value());
269 
270  Item * result = BaseSet::search(p);
271 
272  if (result == nullptr)
273  return nullptr;
274 
275  return &result->second;
276  }
277 
278  const Value * search(const Key & k) const
279  {
280  Item p = map_key(k, Value());
281 
282  const Item * result = BaseSet::search(p);
283 
284  if (result == nullptr)
285  return nullptr;
286 
287  return &result->second;
288  }
289 
290  const Value * search(Key && k) const
291  {
292  Item p = map_key(std::forward<Key>(k), Value());
293 
294  const Item * result = BaseSet::search(p);
295 
296  if (result == nullptr)
297  return nullptr;
298 
299  return &result->second;
300  }
301 
302  Value * search_or_insert(const Key & k, const Value & v)
303  {
304  Item p = map_key(k, v);
305  return &BaseSet::search_or_insert(std::move(p))->second;
306  }
307 
308  Value * search_or_insert(Key && k, const Value & v)
309  {
310  Item p = map_key(std::forward<Key>(k), v);
311  return &BaseSet::search_or_insert(std::move(p))->second;
312  }
313 
314  Value * search_or_insert(const Key & k, Value && v)
315  {
316  Item p = map_key(k, std::forward<Value>(v));
317  return &BaseSet::search_or_insert(std::move(p))->second;
318  }
319 
320  Value * search_or_insert(Key && k, Value && v)
321  {
322  Item p = map_key(std::forward<Key>(k), std::forward<Value>(v));
323  return &BaseSet::search_or_insert(std::move(p))->second;
324  }
325 
326  Value * search_or_insert(const Key & k)
327  {
328  return search_or_insert(k, Value());
329  }
330 
331  Value * search_or_insert(Key && k)
332  {
333  return search_or_insert(std::forward<Key>(k), Value());;
334  }
335 
336  Value & find(const Key & k)
337  {
338  Item p = map_key(k, Value());
339  return BaseSet::find(std::move(p)).second;
340  }
341 
342  const Value & find(const Key & k) const
343  {
344  Item p = map_key(k, Value());
345  return BaseSet::find(std::move(p)).second;
346  }
347 
348  Value & find(Key && k)
349  {
350  Item p = map_key(std::forward<Key>(k), Value());
351  return BaseSet::find(std::move(p)).second;
352  }
353 
354  const Value & find(Key && k) const
355  {
356  Item p = map_key(std::forward<Key>(k), Value());
357  return BaseSet::find(std::move(p)).second;
358  }
359 
360  bool has(const Key & k) const
361  {
362  Item p = map_key(k, Value());
363  return BaseSet::has(std::move(p));
364  }
365 
366  bool has(Key && k) const
367  {
368  Item p = map_key(std::forward<Key>(k), Value());
369  return BaseSet::has(std::move(p));
370  }
371 
372  bool remove(const Key & k)
373  {
374  Item p = map_key(k, Value());
375  return BaseSet::remove(p);
376  }
377 
378  Value & operator [] (const Key & k)
379  {
380  return *search_or_insert(k);
381  }
382 
383  const Value & operator [] (const Key & k) const
384  {
385  return *search_or_insert(k);
386  }
387 
388  Value & operator [] (Key && k)
389  {
390  return *search_or_insert(std::forward<Key>(k));
391  }
392 
393  const Value & operator [] (Key && k) const
394  {
395  return *search_or_insert(std::forward<Key>(k));
396  }
397  };
398 
399  template <typename Key, typename Value, class Cmp = std::less<Key>,
400  template <typename, class> class ArrayType = UnsortedArraySet>
401  class ArrayMap : public GenMap<Key, Value, Cmp,
402  ArraySet<MapKey<Key, Value>,
403  CmpWrapper<Key, Value, Cmp>,
404  ArrayType>>
405  {
407  using Item = MapKey<Key, Value>;
410 
411  public:
412  ArrayMap(nat_t cap, Cmp & _cmp)
413  : BaseMap(cap, CmpWrapperType(_cmp))
414  {
415  // empty
416  }
417 
418  ArrayMap(Cmp && _cmp = Cmp())
419  : BaseMap(CmpWrapperType(std::forward<Cmp>(_cmp)))
420  {
421  // empty
422  }
423 
424  ArrayMap(nat_t cap, Cmp && _cmp = Cmp())
425  : BaseMap(cap, CmpWrapperType(std::forward<Cmp>(_cmp)))
426  {
427  // empty
428  }
429 
430  ArrayMap(const std::initializer_list<Item> & l)
431  : BaseMap(l)
432  {
433  // empty
434  }
435 
436  ArrayMap(const ArrayMap & map)
437  : BaseMap(map)
438  {
439  // empty
440  }
441 
443  : ArrayMap()
444  {
445  BaseMap::swap(map);
446  }
447 
449  {
450  if (this == &m)
451  return *this;
452 
453  (BaseMap &) *this = m;
454  return *this;
455  }
456 
458  {
459  BaseMap::swap(m);
460  return *this;
461  }
462  };
463 
464  template <typename Key, typename Value, class Cmp = std::less<Key>,
465  template <typename, class> class TreeType = RankedTreap>
466  class TreeMap : public GenMap<Key, Value, Cmp,
467  TreeSet<MapKey<Key, Value>,
468  CmpWrapper<Key, Value, Cmp>,
469  TreeType>>
470  {
472  using Item = MapKey<Key, Value>;
475 
476 
477  public:
478  TreeMap(rng_seed_t seed, Cmp & _cmp)
479  : BaseMap(seed, CmpWrapperType(_cmp))
480  {
481  // empty
482  }
483 
484  TreeMap(Cmp & _cmp)
485  : BaseMap(CmpWrapperType(_cmp))
486  {
487  // empty
488  }
489 
490  TreeMap(Cmp && _cmp = Cmp())
491  : TreeMap(_cmp)
492  {
493  // empty
494  }
495 
496  TreeMap(rng_seed_t seed, Cmp && _cmp = Cmp())
497  : TreeMap(seed, _cmp)
498  {
499  // empty
500  }
501 
502  TreeMap(const std::initializer_list<Item> & l)
503  : BaseMap(l)
504  {
505  // empty
506  }
507 
508  TreeMap(const TreeMap & map)
509  : BaseMap(map)
510  {
511  // empty
512  }
513 
514  TreeMap(TreeMap && map)
515  : TreeMap()
516  {
517  BaseMap::swap(map);
518  }
519 
521  {
522  if (this == &m)
523  return *this;
524 
525  (BaseMap &) *this = m;
526  return *this;
527  }
528 
530  {
531  BaseMap::swap(m);
532  return *this;
533  }
534  };
535 
536  template<typename Key, typename Value, typename Fct>
537  inline nat_t hash_fct_wrapper(Fct fct, const MapKey<Key, Value> & p)
538  {
539  return fct(p.first);
540  }
541 
542  template <typename Key, typename Value, class Cmp = std::equal_to<Key>,
543  template <typename, class> class HashTableType = LHashTable>
544  class HashMap : public GenMap<Key, Value, Cmp,
545  HashSet<MapKey<Key, Value>,
546  CmpWrapper<Key, Value, Cmp>,
547  HashTableType>>
548  {
550  using Item = MapKey<Key, Value>;
553  using HashFctPtr = nat_t (*) (const Key &);
554  using HashFctType = std::function<nat_t(const Key &)>;
555 
556  HashFctType fct;
557 
558  public:
559  HashMap(nat_t size, Cmp & _cmp, HashFctPtr _fct)
560  : BaseMap(size, CmpWrapperType(_cmp),
561  std::bind(hash_fct_wrapper<Key,Value,HashFctType>, _fct,
562  std::placeholders::_1)), fct(_fct)
563  {
564  // empty
565  }
566 
567  HashMap(nat_t size, Cmp && _cmp = Cmp(), HashFctPtr fct = &super_fast_hash)
568  : HashMap(size, _cmp, fct)
569  {
570  // empty
571  }
572 
573  HashMap(Cmp & _cmp, HashFctPtr _fct)
574  : BaseMap(CmpWrapperType(_cmp),
575  std::bind(hash_fct_wrapper<Key,Value,HashFctType>, _fct,
576  std::placeholders::_1)), fct(_fct)
577  {
578  // empty
579  }
580 
581  HashMap(Cmp && _cmp = Cmp(), HashFctPtr fct = &super_fast_hash)
582  : HashMap(_cmp, fct)
583  {
584  // empty
585  }
586 
587  HashMap(const std::initializer_list<Item> &);
588 
589  HashMap(const HashMap & map)
590  : BaseMap(map), fct(map.fct)
591  {
592  // empty
593  }
594 
595  HashMap(HashMap && map)
596  : HashMap()
597  {
598  swap(map);
599  }
600 
602  {
603  if (this == &m)
604  return *this;
605 
606  (BaseMap &) *this = m;
607  fct = m.fct;
608  return *this;
609  }
610 
612  {
613  swap(m);
614  return *this;
615  }
616 
617  void swap(HashMap & map)
618  {
619  BaseMap::swap(map);
620  std::swap(fct, map.fct);
621  }
622 
624  {
625  return fct;
626  }
627 
628  const HashFctType & get_hash_fct() const
629  {
630  return fct;
631  }
632  };
633 
634  template <typename Key, typename Value, class Cmp,
635  template <typename, class> class HashTableType>
637  HashMap(const std::initializer_list<Item> & l)
638  : HashMap(l.size())
639  {
640  for (const auto & item : l)
641  BaseHash::append(item);
642  }
643 
644 } // end namespace Designar
645 
646 # endif // DSGMAP_H
TreeMap(rng_seed_t seed, Cmp &&_cmp=Cmp())
Definition: map.H:496
const Cmp & get_cmp() const
Definition: map.H:181
Value & find(const Key &k)
Definition: map.H:336
ArrayMap(const ArrayMap &map)
Definition: map.H:436
Definition: map.H:101
Value * append(const Key &k, Value &&v)
Definition: map.H:244
const Value * search(const Key &k) const
Definition: map.H:278
MapKey< Key, Value > MapItem
Definition: map.H:36
HashMap(Cmp &&_cmp=Cmp(), HashFctPtr fct=&super_fast_hash)
Definition: map.H:581
HashFctType & get_hash_fct()
Definition: map.H:623
CmpWrapper(Cmp &&_cmp=Cmp())
Definition: map.H:112
CmpWrapper & operator=(const CmpWrapper &cw)
Definition: map.H:140
TreeMap(TreeMap &&map)
Definition: map.H:514
ArrayMap(Cmp &&_cmp=Cmp())
Definition: map.H:418
Value * search_or_insert(const Key &k)
Definition: map.H:326
HashMap(Cmp &_cmp, HashFctPtr _fct)
Definition: map.H:573
const Cmp & get_cmp() const
Definition: map.H:135
Definition: set.H:573
Value * append(Key &&k, const Value &v)
Definition: map.H:239
auto map_key(Args &&...args) -> decltype(std::make_pair(std::forward< Args >(args)...))
Definition: map.H:39
std::function< nat_t(const MapKey< Node< GT > *, Arc< GT > ** > &)> HashFctType
Definition: hash.H:88
ArrayMap(const std::initializer_list< Item > &l)
Definition: map.H:430
Cmp & get_cmp()
Definition: map.H:176
TreeMap(const std::initializer_list< Item > &l)
Definition: map.H:502
void swap(HashMap &map)
Definition: map.H:617
CmpWrapper(CmpWrapper &&cw)
Definition: map.H:124
CmpWrapper(const CmpWrapper &cw)
Definition: map.H:118
nat_t hash_fct_wrapper(Fct fct, const MapKey< Key, Value > &p)
Definition: map.H:537
bool has(const Key &k) const
Definition: map.H:360
const HashFctType & get_hash_fct() const
Definition: map.H:628
Cmp & get_cmp()
Definition: map.H:130
Definition: map.H:401
Definition: set.H:551
HashMap(const HashMap &map)
Definition: map.H:589
Definition: hash.H:73
Value * append(Key &&k, Value &&v)
Definition: map.H:249
Value * search_or_insert(const Key &k, const Value &v)
Definition: map.H:302
Value * insert(const Key &k, Value &&v)
Definition: map.H:210
nat_t super_fast_hash(void *, nat_t)
Value * insert(Key &&k, const Value &v)
Definition: map.H:198
auto map_item(Args &&...args) -> decltype(std::make_pair(std::forward< Args >(args)...))
Definition: map.H:46
ArrayMap(ArrayMap &&map)
Definition: map.H:442
Definition: set.H:534
const Value & find(const Key &k) const
Definition: map.H:342
Key & key(MapKey< Key, Value > &item)
Definition: map.H:53
Definition: map.H:544
TreeMap(Cmp &_cmp)
Definition: map.H:484
ArrayMap(nat_t cap, Cmp &_cmp)
Definition: map.H:412
rng_t::result_type rng_seed_t
Definition: types.H:53
Value * insert(const Key &k, const Value &v)
Definition: map.H:186
Value * search_or_insert(const Key &k, Value &&v)
Definition: map.H:314
Value * insert(Key &&k, Value &&v)
Definition: map.H:222
std::pair< Key, Value > MapKey
Definition: map.H:33
const Value & find(Key &&k) const
Definition: map.H:354
Value * search_or_insert(Key &&k, const Value &v)
Definition: map.H:308
Definition: tree.H:102
bool has(Key &&k) const
Definition: map.H:366
HashMap(nat_t size, Cmp &&_cmp=Cmp(), HashFctPtr fct=&super_fast_hash)
Definition: map.H:567
TreeMap(const TreeMap &map)
Definition: map.H:508
CmpWrapper(Cmp &_cmp)
Definition: map.H:106
Value * search_or_insert(Key &&k)
Definition: map.H:331
Definition: map.H:466
HashMap(nat_t size, Cmp &_cmp, HashFctPtr _fct)
Definition: map.H:559
TreeMap(Cmp &&_cmp=Cmp())
Definition: map.H:490
Definition: array.H:32
Definition: set.H:562
unsigned long int nat_t
Definition: types.H:50
TreeMap(rng_seed_t seed, Cmp &_cmp)
Definition: map.H:478
bool operator()(const MapKey< Key, Value > &p, const MapKey< Key, Value > &q) const
Definition: map.H:155
Definition: map.H:164
Value & value(MapKey< Key, Value > &item)
Definition: map.H:77
Value * search(const Key &k)
Definition: map.H:254
HashMap(HashMap &&map)
Definition: map.H:595
Value * search(Key &&k)
Definition: map.H:266
ArrayMap(nat_t cap, Cmp &&_cmp=Cmp())
Definition: map.H:424
Value * append(const Key &k, const Value &v)
Definition: map.H:234
Value * search_or_insert(Key &&k, Value &&v)
Definition: map.H:320
Value & find(Key &&k)
Definition: map.H:348
const Value * search(Key &&k) const
Definition: map.H:290