Aleph-w  1.9
General library for algorithms and data structures
Map.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 
28 # ifndef ALEPH_MAP_H
29 # define ALEPH_MAP_H
30 /*
31  Aleph implementation of map C++ standard container
32 */
33 
34 # include <cstdlib>
35 # include <ahFunction.H>
36 # include <ah_stdc++_utils.H>
37 # include <tpl_treapRk.H>
38 # include <tpl_nodePool.H>
39 
40 
41 namespace Aleph
42 {
43 
44 
77  template <class Key,
78  class Elem,
79  class Compare = Aleph::less<Key>,
80  template <class, class> class Tree = Treap_Rk
81  >
82  class map
83  {
84  struct Cmp
85  {
86  bool
87  operator () (const std::pair<Key, Elem> & __x,
88  const std::pair<Key, Elem> & __y) const noexcept
89  {
90  return Compare () (__x.first, __y.first);
91  }
92  };
93 
94  public:
95 
97  typedef std::pair<Key, Elem> Pair;
98 
100  typedef Pair value_type;
101 
104  typedef typename map::value_type & reference;
105 
107  typedef const typename map::value_type & const_reference;
108 
109  typedef size_t size_type;
110 
112  typedef Key key_type;
113 
115  typedef Elem mapped_type;
116 
117  private:
118 
119  typedef Tree<Pair, Cmp> Tree_Type;
120 
121  typedef typename Tree_Type::Node Node;
122 
123  Node_Pool<Node> node_pool;
124 
125  mutable Tree_Type tree;
126 
127  Node * search_in_tree (const Key & k)
128  {
129  return tree.search (Pair(k, Elem()));
130  }
131 
132  public:
133 
138  class iterator
139  {
140  private:
141 
142  friend class map<Key, Elem>;
143 
144  typedef typename Tree_Type::Iterator Iterator;
145 
146  Iterator itor;
147  bool underflow;
148  bool overflow;
149 
150  void init_flags ()
151  {
152  if (itor.has_curr () )
153  underflow = overflow = false;
154  else
155  underflow = overflow = true;
156  }
157 
158  void goto_begin ()
159  {
160  itor.reset_first ();
161  init_flags ();
162  }
163 
164  void goto_last ()
165  {
166  itor.reset_last ();
167  init_flags ();
168  }
169 
170  void goto_end ()
171  {
172  itor.reset_last ();
173  init_flags ();
174  if (not overflow)
175  itor.next ();
176  overflow = true;
177  }
178 
179  void forward ()
180  {
181  if (underflow)
182  {
183  goto_begin ();
184  return;
185  }
186 
187  itor.next ();
188 
189  if (not itor.has_curr () )
190  overflow = true;
191  }
192 
193  void backward ()
194  {
195  if (overflow)
196  {
197  goto_last ();
198  return;
199  }
200 
201  itor.prev ();
202 
203  if (not itor.has_curr () )
204  underflow = true;
205  }
206 
207  iterator (Tree_Type & _tree, Node * node)
208  : itor (_tree, node), underflow (false), overflow (false)
209  {
210  /* empty */
211  }
212 
213  public:
214 
216  typedef typename map::value_type value_type;
217 
219  typedef typename map::size_type difference_type;
220 
222  typedef typename map::value_type * pointer;
223 
225  typedef typename map::reference reference;
226 
228  iterator () { /* empty */ }
229 
230  iterator (Tree_Type & tree) : itor (tree)
231  {
232  init_flags ();
233  }
234 
236  const Pair & operator * ()
237  {
238  return KEY(itor.get_curr());
239  }
240 
242  const Pair * operator -> ()
243  {
244  return &KEY(itor.get_curr());
245  }
246 
249  iterator operator ++ ()
250  {
251  forward ();
252  return *this;
253  }
254 
257  iterator operator ++ (int)
258  {
259  iterator ret_val = *this;
260  forward ();
261  return ret_val;
262  }
263 
266  iterator operator -- ()
267  {
268  backward ();
269  return *this;
270  }
271 
273  iterator operator -- (int)
274  {
275  iterator ret_val = *this;
276  backward ();
277  return ret_val;
278  }
279 
282  iterator operator += (const size_type & n)
283  {
284  itor.reset_to_pos (itor.get_current_position () + n);
285  return *this;
286  }
287 
290  iterator operator -= (const size_type & n)
291  {
292  itor.reset_to_pos (itor.get_current_position () - n);
293  return *this;
294  }
295 
297  bool operator == (const iterator & _itor) const
298  {
299  return itor == _itor.itor;
300  }
301 
303  bool operator != (const iterator & _itor) const
304  {
305  return not (itor == _itor.itor);
306  }
307 
308  bool verify (const map & _map) const
309  {
310  return itor.verify ( (Tree_Type*) &_map.tree);
311  }
312 
313  bool verify (const iterator & it) const
314  {
315  return itor.verify (it.itor);
316  }
317  };
318 
320  map () : node_pool(100) { /* empty */ }
321 
323  map (const map & c) : node_pool(100)
324  {
325  tree.getRoot () = copyRec (c.tree.getRoot () );
326  }
327 
328 
331  ~map ()
332  {
333  destroyRec (tree.getRoot () );
334  }
335 
337  map & operator = (const map& c)
338  {
339  if (this == &c)
340  return *this;
341 
342  destroyRec (tree.getRoot ());
343 
344  tree.getRoot () = copyRec (c.tree.getRoot ());
345 
346  return *this;
347  }
348 
350  size_t size () const { return COUNT (tree.getRoot () ); }
351 
353  bool empty () const
354  {
355  return size() == 0;
356  }
357 
360  bool operator == (const map & c) const
361  {
362  if (size () != c.size () )
363  return false;
364 
365  typename Tree_Type::Iterator itor1 (tree), itor2 (c.tree);
366 
367  while (itor1.has_curr() and itor2.has_curr() )
368  {
369  if (KEY (itor1.get_curr() ) != KEY (itor2.get_curr() ) )
370  return false;
371 
372  itor1.next ();
373  itor2.next ();
374  }
375 
376  assert(not itor1.has_curr() and not itor2.has_curr() );
377 
378  return true;
379  }
380 
383  bool operator != (const map & c) const
384  {
385  return not (*this == c);
386  }
387 
390  bool operator < (const map & c) const
391  {
392  typename Tree_Type::Iterator itor1 (tree), itor2 (c.tree);
393 
394  while (itor1.has_curr() and itor2.has_curr() )
395  {
396  if (KEY (itor1.get_curr() ) < KEY (itor2.get_curr() ))
397  return true;
398  else if (KEY (itor2.get_curr() ) < KEY (itor1.get_curr() ))
399  return false;
400 
401  // En este caso las claves sons iguales
402  itor1.next ();
403  itor2.next ();
404  }
405 
406  if (not itor1.has_curr())
407  return true;
408 
409  return false;
410  }
411 
414  bool operator > (const map & c)
415  {
416  return not (*this == c or *this < c);
417  }
418 
421  bool operator <= (const map & c)
422  {
423  return not (*this > c );
424  }
425 
428  bool operator >= (const map & c)
429  {
430  return not (*this < c);
431  }
432 
444  size_type count (const Key & key)
445  {
446  if (search_in_tree (key) != nullptr)
447  return 1;
448 
449  return 0;
450  }
451 
464  iterator find (const Key & key)
465  {
466  Node * p = search_in_tree (key);
467 
468  if (p == nullptr)
469  return end ();
470 
471  return iterator (tree, p);
472  }
476  iterator lower_bound (const Key & key)
477  {
478  Node * p =
479  search_rank_parent <Node, Cmp> (tree.getRoot(), Pair(key, Elem()));
480 
481  return iterator(tree, p);
482  }
483 
487  iterator upper_bound (const Key & key)
488  {
489  Node * p =
490  search_rank_parent <Node, Cmp> (tree.getRoot(), Pair(key, Elem()));
491 
492  iterator upper(tree, p);
493 
494  if (KEY (p).first == key)
495  upper.itor.next();
496 
497  return upper;
498  }
499 
502  void swap (map & c)
503  {
504  tree.swap (c.tree);
505  }
506 
509  {
510  return iterator (tree);
511  }
512 
515  {
516  iterator last (tree);
517  last.goto_end ();
518 
519  return last;
520  }
521 
537  std::pair<iterator, bool> insert (const Pair & key)
538  {
539  Node * p = node_pool.allocate(key);
540 
541  if (tree.search_or_insert(p) != p)
542  {
543  node_pool.deallocate(p);
544  return std::pair<iterator, bool> (iterator (tree), false);
545  }
546 
547  return std::pair<iterator, bool> (iterator(tree, p), true);
548  }
549 
565  template <typename Itor>
566  map (Itor beg, const Itor & end) : map()
567  {
568  while (beg != end)
569  insert(*beg++);
570  }
571 
590  iterator insert (iterator /* pos */, const Pair& key)
591  {
592  return insert(key);
593  }
594 
612  template <typename Itor>
613  void insert (Itor beg, const Itor & end)
614  {
615  while (beg != end)
616  insert (*beg++);
617  }
618 
630  size_type erase (const Key & key)
631  {
632  Node * p = tree.remove (Pair(key, Elem()));
633 
634  if (p == nullptr)
635  return 0;
636 
637  node_pool.deallocate(p);
638 
639  return 1;
640  }
641 
655  void erase (iterator pos)
656  {
657  erase (KEY (pos.itor.get_curr ()).first);
658  }
659 
673  iterator erase (const iterator & beg, const iterator & end)
674  {
675  Aleph::verify_iterators (beg, end);
676  Aleph::verify_container_and_iterator (*this, beg);
677 
678  iterator ret_val = end;
679 
680  const size_t pos_beg = beg.itor.get_current_position ();
681  const size_t pos_end = end.itor.get_current_position ();
682 
683  Node * removed_tree = tree.remove (pos_beg, pos_end - 1);
684 
685  destroyRec (removed_tree);
686 
687  return ret_val;
688  }
689 
691  void clear ()
692  {
693  destroyRec (tree.getRoot());
694  }
695 
696  private:
697 
698  struct Proxy
699  {
700  map * map_ptr;
701  Node * node;
702  Key key;
703 
704  Proxy (map * m_ptr, const Key & _key) : map_ptr (m_ptr), key (_key)
705  {
706  node = map_ptr->search_in_tree(key);
707  }
708 
709  Proxy & operator = (const Elem & elem)
710  {
711  if (node == nullptr)
712  {
713  node = map_ptr->node_pool.allocate(std::make_pair(key, elem));
714  map_ptr->tree.insert(node);
715  }
716  else
717  KEY(node).second = elem;
718 
719  return *this;
720  }
721 
722  Proxy & operator = (const Proxy & proxy)
723  {
724  if (this == &proxy)
725  return *this;
726 
727  if (proxy.node == nullptr)
728  throw std::domain_error("key not found");;
729 
730  if (map_ptr == proxy.map_ptr and key == proxy.key)
731  return *this; // They are the same
732 
733  if (node == nullptr)
734  {
735  node = map_ptr->node_pool.allocate(KEY(proxy.node));
736  map_ptr->tree.insert(node);
737  }
738  else
739  KEY(node).second = KEY(proxy.node).second;
740 
741  return *this;
742  }
743 
744  operator Elem & () const
745  {
746  if (node == nullptr)
747  throw std::domain_error ("key not found");;
748 
749  return KEY (node).second;
750  }
751  };
752 
753  public:
754 
755  const Proxy operator [] (const Key & key) const
756  {
757  return Proxy (this, key);
758  }
759 
760  Proxy operator [] (const Key & key)
761  {
762  return Proxy (this, key);
763  }
764  };
765 
766 
767 
768 } // end namespace Aleph
769 
770 
771 # endif // ALEPH_MAP_H
map & operator=(const map &c)
Asigna todo el contenido de c a this.
Definition: Map.H:337
iterator find(const Key &key)
Definition: Map.H:464
iterator begin()
Retorna un iterador posicionado al primer elemento del mapeo.
Definition: Map.H:508
bool operator>(const map &c)
Definition: Map.H:414
bool operator==(const map &c) const
Definition: Map.H:360
iterator erase(const iterator &beg, const iterator &end)
Definition: Map.H:673
void swap(map &c)
Definition: Map.H:502
Definition: tpl_nodePool.H:45
iterator insert(iterator, const Pair &key)
Definition: Map.H:590
iterator()
Constructor vacío; no tiene validez si no se asocia un mapeo.
Definition: Map.H:228
void deallocate(Node *p) noexcept
Definition: tpl_nodePool.H:102
map::value_type value_type
El tipo de elemento que maneja el iterador.
Definition: Map.H:216
auto & COUNT(Node *p) noexcept
Definition: tpl_binNodeXt.H:66
Key key_type
El tipo de clave de indización.
Definition: Map.H:112
const map::value_type & const_reference
Tipo generico referencia constante.
Definition: Map.H:107
void erase(iterator pos)
Definition: Map.H:655
map()
Constructor vacío.
Definition: Map.H:320
bool operator<(const map &c) const
Definition: Map.H:390
map(const map &c)
Instancia una copia del mapeo c.
Definition: Map.H:323
map::size_type difference_type
El tipo numérico para manejar aritmética.
Definition: Map.H:219
size_t size() const
Retorna la cantidad de elementos que contiene el mapeo.
Definition: Map.H:350
bool operator>=(const map &c)
Definition: Map.H:428
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
map::value_type * pointer
Tipo de dato puntero a elemento actual.
Definition: Map.H:222
size_type count(const Key &key)
Definition: Map.H:444
bool operator<=(const map &c)
Definition: Map.H:421
Definition: ah-comb.H:35
map(Itor beg, const Itor &end)
Definition: Map.H:566
size_type erase(const Key &key)
Definition: Map.H:630
Definition: Map.H:138
std::pair< Key, Elem > Pair
Tipo par almacenado en mapeo.
Definition: Map.H:97
bool operator!=(const map &c) const
Definition: Map.H:383
void destroyRec(Node *&root) noexcept
Definition: tpl_binNodeUtils.H:500
Definition: tpl_treapRk.H:1010
map::value_type & reference
Definition: Map.H:104
void clear()
Borra todos los elementos del mapeo.
Definition: Map.H:691
Pair value_type
Tipo a exportar como tipo del contenedor.
Definition: Map.H:100
map::reference reference
Tipo de dato referencia a elemento actual.
Definition: Map.H:225
void insert(Itor beg, const Itor &end)
Definition: Map.H:613
std::pair< iterator, bool > insert(const Pair &key)
Definition: Map.H:537
iterator upper_bound(const Key &key)
Definition: Map.H:487
~map()
Definition: Map.H:331
Node * copyRec(Node *root)
Definition: tpl_binNodeUtils.H:519
Definition: Map.H:82
bool empty() const
Retorna true si el contenedor esta vacío.
Definition: Map.H:353
iterator lower_bound(const Key &key)
Definition: Map.H:476
Node * allocate()
Definition: tpl_nodePool.H:56
Elem mapped_type
El tipo de rango del mapeo.
Definition: Map.H:115
iterator end()
Retorna un iterador posicionado al último elemento del mapeo.
Definition: Map.H:514

Leandro Rabindranath León