Aleph-w  1.9
General library for algorithms and data structures
Multimap.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 /*
29  Aleph implementation of multimap C++ standard container
30 */
31 
32 # ifndef ALEPH_MULTIMAP_H
33 # define ALEPH_MULTIMAP_H
34 
35 # include <ah_stdc++_utils.H>
36 # include <tpl_treapRk.H>
37 
38 namespace Aleph
39 {
40 
99  template <typename Key, typename T,
100  class Compare = Aleph::less<Key>,
101  template <class, class> class KTree = Treap_Rk,
102  template <class, class> class TTree = Treap_Rk>
103  class multimap
104  {
105  // Definición de registro conteniendo elem de tipo T
106  struct Tdata
107  {
108  T elem; // elemento mapeado a una clave de tipo key
109  size_t num_reps = 0; // número de ocurrencias de elem relacionado
110  // a un valor de clave key
111 
112  Tdata() : elem(), num_reps(0) { /* empty */ }
113 
114  Tdata(const T & e) : elem(e), num_reps(0) { /* empty */ }
115 
116  Tdata(const Tdata & item) : elem(item.elem), num_reps(item.num_reps)
117  {
118  // empty
119  }
120  };
121 
122  typedef Aleph::less<T> Tless;
123 
124  struct Cmpt // Clase de comparación para clave asociada
125  {
126  bool operator () (const Tdata & op1, const Tdata & op2) const
127  {
128  return Tless () (op1.elem, op2.elem);
129  }
130  };
131 
132  // definición de árbol de claves elementos mapeados
133  typedef TTree<Tdata, Cmpt> T_Tree;
134 
135  typedef typename T_Tree::Node Tnode;
136 
137  // Definición de registro conteniendo elementos del multimapeo
138  struct Kdata
139  {
140  Key key; // clave primaria
141  size_t num_reps = 0; // Número de repeticiones del valor de key
142  T_Tree t_tree; // árbol de elementos de tipo T asociados a key
143 
144  Kdata() : num_reps(0) { /* empty */ }
145 
146  Kdata(const Kdata & item) : key(item.key), num_reps(0)
147  {
148  t_tree.getRoot() = copyRec(const_cast<Kdata&>(item).t_tree.getRoot());
149  num_reps = item.num_reps;
150  }
151 
152  ~Kdata()
153  {
154  destroyRec(t_tree.getRoot());
155  }
156 
157  Kdata & operator = (const Kdata & item)
158  {
159  if (this == &item)
160  return *this;
161 
162  destroyRec(t_tree.getRoot());
163  num_reps = 0;
164  t_tree.getRoot() = copyRec(const_cast<Kdata&>(item).t_tree.getRoot());
165 
166  key = item.key;
167  num_reps = item.num_reps;
168 
169  return *this;
170  }
171  };
172 
173  struct Cmpk // clase de comparación para clave
174  {
175  bool operator () (const Kdata & op1, const Kdata & op2) const
176  {
177  return Compare () (op1.key, op2.key);
178  }
179  };
180 
181  typedef KTree<Kdata, Cmpk> K_Tree;
182 
183  typedef typename K_Tree::Node Knode;
184 
185  K_Tree k_tree;
186 
187  size_t num_elem = 0;
188 
189  // Para ahorrar memoria, el árbol ktree indiza por registros de tipo
190  // Kdata y la función de comparación siguiente se encarga de sólo
191  // comparar la clave. Ahora bien, es muy importante, para no tener
192  // una penalidad en desempeño, que no se desperdicie tiempo en el
193  // constructor de Kdata cada vez que se requiera realizar una
194  // búsqueda. Así el siguiente campo se crea una sola vez y se emplea
195  // para las búsquedas.
196  mutable Kdata searching_kdata;
197 
198  // esta función se emplea cuando se desee buscar key y se requiera
199  // obtener un Kdata
200  Kdata & key_kdata(const Key & key) const
201  {
202  searching_kdata.key = key;
203  return searching_kdata;
204  }
205 
206  public:
207 
208  multimap() { /* empty */ }
209 
210  ~multimap()
211  {
212  destroyRec(k_tree.getRoot());
213  }
214 
216  void clear()
217  {
218  destroyRec(k_tree.getRoot());
219  num_elem = 0;
220  }
221 
222  typedef std::pair<Key, T> Pair;
223 
225  typedef Pair value_type;
226 
228  typedef typename multimap::value_type & reference;
229 
230  typedef const typename multimap::value_type & const_reference;
231 
232  typedef size_t size_type;
233 
234  typedef Key key_type;
235 
236  typedef T mapped_type;
237 
240  const size_t & size () const { return num_elem; }
241 
244  size_type max_size() const
245  {
246  int sizek = sizeof(Knode);
247  int sizet = sizeof(Tnode);
248 
249  double total_mem = pow(2, __WORDSIZE);
250 
251  size_type ret_val = floor(total_mem / (sizek + sizet));
252 
253  return ret_val;
254  }
255 
258  bool empty () const {return k_tree.is_empty(); }
259 
260  private:
261 
262  typedef typename K_Tree::Iterator K_Itor;
263  typedef typename T_Tree::Iterator T_Itor;
264 
265  public:
266 
271  class iterator
272  {
273  friend class multimap<Key, T, Compare, KTree, TTree>;
274 
275  multimap * multimap_ptr = nullptr;
276  const K_Tree * k_tree_ptr = nullptr;
277  mutable K_Itor k_it;
278  const T_Tree * t_tree_ptr = nullptr;
279  mutable T_Itor t_it;
280  mutable int pos_in_k = 0;
281  mutable int pos_in_t = 0;
282  bool underflow;
283  bool overflow;
284  Pair ret_pair; // Usado por el operador ->
285 
286  void default_init()
287  {
288  assert(k_tree_ptr != nullptr);
289 
290  if (k_it.has_curr())
291  {
292  assert(KEY(k_it.get_curr()).t_tree.size() > 0);
293  underflow = overflow = false;
294  pos_in_k = pos_in_t = 0;
295  t_tree_ptr = &KEY(k_it.get_curr()).t_tree;
296  t_it = T_Itor(*t_tree_ptr);
297  }
298  else
299  put_in_overflow();
300  }
301 
302  iterator(const multimap * m, Knode * kp, Tnode * tp,
303  int kpos = 0, int tpos = 0)
304  : multimap_ptr(const_cast<multimap*>(m)),
305  k_tree_ptr(&m->k_tree),
306  k_it(*k_tree_ptr, kp),
307  t_tree_ptr(&KEY(kp).t_tree),
308  t_it(*t_tree_ptr, tp),
309  pos_in_k(kpos),
310  pos_in_t(tpos),
311  underflow(false),
312  overflow(false)
313  {
314  assert(not KEY(kp).t_tree.is_empty());
315  assert(KEY(tp).num_reps > 0 and tpos < KEY(tp).num_reps);
316  }
317 
318  iterator(const multimap * m, Knode * p)
319  : multimap_ptr(const_cast<multimap*>(m)),
320  k_tree_ptr(&m->k_tree), k_it(*k_tree_ptr, p),
321  t_tree_ptr(&KEY(p).t_tree), t_it(*t_tree_ptr),
322  pos_in_t(0), underflow(false), overflow(false)
323  {
324  assert(KEY(p).num_reps > 0);
325  assert(not KEY(p).t_tree.is_empty());
326  }
327 
328  public:
329 
332 
335  typedef typename multimap::size_type difference_type;
336 
338  typedef typename multimap::value_type * pointer;
339 
341  typedef typename multimap::reference reference;
342 
345  iterator(const multimap & mm)
346  : multimap_ptr(const_cast<multimap*>(&mm)),
347  k_tree_ptr(&multimap_ptr->k_tree), k_it(*k_tree_ptr)
348  {
349  default_init();
350  }
351 
353  iterator(const iterator & it)
354  : multimap_ptr(it.multimap_ptr), k_tree_ptr(it.k_tree_ptr), k_it(it.k_it),
355  t_tree_ptr(it.t_tree_ptr), t_it(it.t_it),
356  pos_in_k(it.pos_in_k), pos_in_t(it.pos_in_t),
357  underflow(it.underflow), overflow(it.overflow)
358  {
359  // empty
360  }
361 
364  : multimap_ptr(nullptr), k_tree_ptr(nullptr), t_tree_ptr(nullptr),
365  pos_in_k(-1), pos_in_t(-1), underflow(true), overflow(true)
366  {
367  // empty
368  }
369 
372  {
373  if (this == &it)
374  return *this;
375 
376  multimap_ptr = it.multimap_ptr;
377  k_tree_ptr = it.k_tree_ptr;
378  k_it = it.k_it;
379  t_tree_ptr = it.t_tree_ptr;
380  t_it = it.t_it;
381  pos_in_k = it.pos_in_k;
382  pos_in_t = it.pos_in_t;
383  underflow = it.underflow;
384  overflow = it.overflow;
385 
386  return *this;
387  }
388 
389  private:
390 
391  bool has_curr() const { return k_it.has_curr(); }
392 
393  Knode * get_curr() { return k_it.get_curr(); }
394 
395  Kdata & get_curr_kdata() { return KEY(get_curr()); }
396 
397  public:
398 
400  value_type operator * ()
401  {
402  return value_type(get_curr_kdata().key, KEY(t_it.get_curr()).elem);
403  }
404 
416  const value_type * operator -> ()
417  {
418  ret_pair.first = get_curr_kdata().key;
419  ret_pair.second = KEY(t_it.get_curr()).elem;
420 
421  return &ret_pair;
422  }
423 
424  private:
425 
426  void goto_begin()
427  {
428  k_it.reset_first();
429  if (not has_curr())
430  {
431  put_in_underflow();
432  return;
433  }
434 
435  t_tree_ptr = &KEY(get_curr()).t_tree;
436  t_it = T_Itor(*t_tree_ptr);
437  pos_in_k = pos_in_t = 0;
438  }
439 
440  void goto_last()
441  {
442  k_it.reset_last();
443  if (not has_curr())
444  {
445  put_in_overflow();
446  return;
447  }
448 
449  overflow = false;
450  Kdata & kdata = KEY(get_curr());
451  t_tree_ptr = &kdata.t_tree;
452  t_it = T_Itor(*t_tree_ptr);
453  t_it.reset_last();
454  pos_in_k = kdata.num_reps - 1;
455  pos_in_t = KEY(t_it.get_curr()).num_reps - 1;
456  }
457 
458  void goto_end()
459  {
460  k_it.reset_last();
461  if (has_curr())
462  {
463  k_it.next_ne(); // lo coloca fuera de rango
464  underflow = false;
465  }
466  else
467  put_in_underflow();
468 
469  put_in_overflow();
470  }
471 
472  iterator compute_end() const
473  {
474  iterator it(*this);
475  it.goto_end();
476  assert(it.overflow);
477  return it;
478  }
479 
480  bool is_at_end() const { return not has_curr(); }
481 
482  iterator compute_begin() const
483  {
484  iterator it(*this);
485  return it;
486  }
487 
488  void put_in_overflow()
489  {
490  t_tree_ptr = nullptr;
491 
492  if (k_tree_ptr->is_empty())
493  put_in_underflow();
494 
495  overflow = true;
496  }
497 
498  void put_in_underflow()
499  {
500  t_tree_ptr = nullptr;
501 
502  pos_in_t = -1;
503  underflow = true;
504  }
505 
506  // avanza todas las claves de la posición actual
507  void forward_k_it()
508  {
509  k_it.next();
510  if (not has_curr())
511  {
512  put_in_overflow();
513  return;
514  }
515 
516  t_tree_ptr = &KEY(get_curr()).t_tree;
517  t_it = T_Itor(*t_tree_ptr);
518  pos_in_t = 0;
519  }
520 
521  void forward_tree_iterators()
522  {
523  t_it.next();
524  if (t_it.has_curr())
525  {
526  pos_in_t = 0;
527  return;
528  }
529 
530  forward_k_it();
531  }
532 
533  void forward()
534  {
535  if (underflow)
536  {
537  goto_begin();
538  return;
539  }
540 
541  if (overflow)
542  {
543  assert(t_tree_ptr == nullptr);
544  throw std::overflow_error("Multimap::iterator is already "
545  "in overflow");
546  }
547 
548  assert(t_it.has_curr() and t_tree_ptr != nullptr);
549 
550  Tdata & tdata = KEY(t_it.get_curr());
551  if (++pos_in_t < tdata.num_reps) // alcanza el último elemento
552  return; // aún no!
553 
554  forward_tree_iterators();
555  }
556 
557  void backward_k_it()
558  {
559  k_it.prev();
560  if (not has_curr())
561  {
562  put_in_underflow();
563  return;
564  }
565 
566  t_tree_ptr = &KEY(get_curr()).t_tree;
567  t_it = T_Itor(*t_tree_ptr);
568  t_it.reset_last();
569  pos_in_t = KEY(t_it.get_curr()).num_reps - 1;
570  }
571 
572  void backward_tree_iterators()
573  {
574  t_it.prev();
575  if (t_it.has_curr())
576  {
577  pos_in_t = KEY(t_it.get_curr()).num_reps - 1;
578  return;
579  }
580 
581  backward_k_it();
582  }
583 
584  void backward()
585  {
586  if (overflow)
587  {
588  goto_last();
589  return;
590  }
591 
592  if (underflow)
593  {
594  assert(t_tree_ptr == nullptr);
595  throw std::underflow_error("Multimap::iterator is "
596  "already in underflow");
597  }
598 
599  assert(t_it.has_curr() and t_tree_ptr != nullptr);
600 
601  if (--pos_in_t >= 0) // alcanza el primer elemento
602  return;
603 
604  backward_tree_iterators();
605  }
606 
607  void del()
608  {
609  Kdata & kdata = get_curr_kdata();
610  Tnode * tp = t_it.get_curr();
611  Tdata & tdata = KEY(tp);
612 
613  --multimap_ptr->num_elem;
614  --kdata.num_reps;
615  if (--tdata.num_reps == 0)
616  {
617  delete t_it.del();
618  pos_in_t = 0;
619  }
620  else if (pos_in_t == tdata.num_reps)
621  {
622  t_it.next();
623  pos_in_t = 0;
624  }
625 
626  if (t_it.has_curr())
627  {
628  assert(kdata.num_reps > 0);
629  return;
630  }
631 
632  if (kdata.num_reps == 0)
633  {
634  Knode * kp = k_it.del();
635  assert(KEY(kp).t_tree.is_empty());
636  delete kp;
637  }
638  else
639  k_it.next();
640 
641  if (not k_it.has_curr())
642  {
643  put_in_overflow();
644  return;
645  }
646 
647  t_tree_ptr = &KEY(get_curr()).t_tree;
648  t_it = T_Itor(*t_tree_ptr);
649  pos_in_k = pos_in_t = 0;
650  }
651 
652  public:
653 
655  bool operator == (const iterator & it) const
656  {
657  if (this->has_curr() and it.has_curr())
658  return (t_it.get_curr() == it.t_it.get_curr() and
659  pos_in_t == it.pos_in_t);
660 
661  if (this->is_at_end() and it.is_at_end())
662  {
663  assert(this->overflow and it.overflow);
664  return true;
665  }
666 
667  return false;
668  }
669 
671  bool operator != (const iterator & itor) const
672  {
673  return not (*this == itor);
674  }
675 
678  iterator operator ++ ()
679  {
680  forward();
681  return *this;
682  }
683 
686  iterator operator ++ (int)
687  {
688  iterator ret_val = *this;
689  forward();
690  return ret_val;
691  }
692 
695  iterator operator -- ()
696  {
697  backward();
698  return *this;
699  }
700 
703  iterator operator -- (int)
704  {
705  iterator ret_val = *this;
706  backward();
707  return ret_val;
708  }
709 
712  iterator operator += (size_type n)
713  {
714  if (n == 0)
715  return *this;
716 
717  while (true) // avanzar por nodos en t_it
718  {
719  assert(KEY(t_it.get_curr()).num_reps > 0);
720 
721  const size_t treps = KEY(t_it.get_curr()).num_reps;
722  const int remain_in_t_node = treps - pos_in_t;
723  if (n < remain_in_t_node)
724  {
725  pos_in_k += n;
726  pos_in_t += n;
727  assert(pos_in_t < KEY(t_it.get_curr()).num_reps);
728 
729  return *this;
730  }
731 
732  n -= remain_in_t_node;
733  pos_in_k += treps;
734  t_it.next();
735  pos_in_t = 0;
736  if (t_it.has_curr())
737  continue;
738 
739  assert(pos_in_k == KEY(k_it.get_curr()).num_reps);
740 
741  while (true) // avanzar por nodos en k_it
742  {
743  k_it.next();
744  if (not has_curr())
745  {
746  put_in_overflow();
747  throw std::overflow_error("Multimap::iterator is "
748  "already in overflow");
749  }
750 
751  assert(KEY(get_curr()).num_reps > 0);
752 
753  const int remain_in_k_node = KEY(get_curr()).num_reps;
754  if (n < remain_in_k_node)
755  {
756  t_tree_ptr = &KEY(get_curr()).t_tree;
757  t_it = T_Itor(*t_tree_ptr);
758  pos_in_k = pos_in_t = 0;
759  break;
760  }
761 
762  n -= remain_in_k_node;
763  }
764  }
765  }
766  };
767 
769  typedef const iterator const_iterator;
770 
777  iterator insert(const value_type & value)
778  {
779  Knode * kp = new Knode(key_kdata(value.first)); // nuevo nodo
780  Knode * kq = k_tree.search_or_insert(kp);
781 
782  if (kp != kq) // ¿Está ya la clave primaria en el multiconjunto?
783  delete kp; // sí está ==> mantenga el nodo para uso futuro pero borre kp
784 
785  assert(KEY(kq).key == value.first); // TMP
786 
787  T_Tree & t_tree = KEY(kq).t_tree;
788  const Tdata tdata(value.second);
789 
790  try
791  {
792  Tnode * tp = new Tnode(tdata);
793  Tnode * tq = t_tree.search_or_insert(tp);
794 
795  if (tp != tq) // ¿Está el elemento ya asociado a la clave?
796  delete tp;
797 
798  ++num_elem;
799  ++KEY(kq).num_reps;
800 
801  return iterator(this, kq, tq, KEY(tq).num_reps++);
802  }
803  catch (...)
804  {
805  if (kp == kq)
806  delete kp;
807 
808  throw;
809  }
810  }
811 
814  template <class InputIterator>
815  void insert(InputIterator first, const InputIterator & last)
816  {
817  while (first != last)
818  insert(*first++);
819  }
820 
822  template <class InputIterator>
823  multimap(InputIterator first, const InputIterator & last)
824  : multimap()
825  {
826  this->insert(first, last);
827  }
828 
830  multimap(const multimap & m)
831  : multimap::multimap()
832  {
833  k_tree.getRoot() = copyRec(const_cast<multimap&>(m).k_tree.getRoot());
834  num_elem = m.num_elem;
835  }
836 
840  {
841  if (this == &m)
842  return *this;
843 
844  destroyRec(k_tree.getRoot());
845  num_elem = 0;
846 
847  k_tree.getRoot() = copyRec(const_cast<multimap&>(m).k_tree.getRoot());
848  num_elem = m.num_elem;
849 
850  return *this;
851  }
852 
870  iterator insert(const_iterator & hint, const value_type & value)
871  {
872  if (hint.has_curr()) // mirar lo que contiene el iterador
873  {
874  Knode * kp = const_cast<iterator&>(hint).get_curr();
875  Kdata & kdata = KEY(kp);
876 
877  // clave primaria de hint coincide con value.first
878  if (Aleph::are_equals <Key, Compare> (kdata.key, value.first))
879  { // sí ==> no hay necesidad de buscar en árbol k_tree
880 
881  Tnode * tq = hint.t_it.get_curr(); // mirar clave asociada
882  const Tdata & tdata = KEY(tq);
883  // ¿clave asociada distinta?
884  if (Aleph::no_equals <T, Tless> (tdata.elem, value.second))
885  { // sí == > buscar o insertar en subárbol de clave asociada
886  Tnode * tp = new Tnode(tdata);
887  tq = kdata.t_tree.search_or_insert(tp);
888  if (tp != tq) // ¿Está el elemento ya asociado a la clave?
889  delete tp; // sí ==> manténgalo para uso futuro
890  }
891 
892  ++num_elem;
893  ++kdata.num_reps;
894 
895  return iterator(this, kp, tq, KEY(tq).num_reps++);
896  }
897  }
898 
899  // hint no tiene nada que ver con value ==> inserción normal
900  return insert(value);
901  }
902 
904  iterator erase(const_iterator & position)
905  {
906  iterator ret_val = position;
907 
908  ret_val.del();
909 
910  return ret_val;
911  }
912 
915  size_type erase(const key_type & key)
916  {
917  Knode * p = k_tree.remove(key_kdata(key));
918  if (p == nullptr)
919  return 0;
920 
921  size_type ret_val = KEY(p).num_reps;
922 
923  num_elem -= ret_val;
924 
925  delete p; // no hacemos kpool.deallocate(p) porque queremos liberar
926  // enteramente el árbol de claves asociadas KEY(p).t_tree
927 
928  return ret_val;
929  }
930 
942  iterator erase(iterator first, const_iterator & last)
943  {
944  iterator it = first;
945  while (it != last)
946  it = erase(it);
947 
948  return it;
949  }
950 
952  iterator begin() const { return iterator(*this); }
953 
955  iterator end () const { return iterator(*this).compute_end(); }
956 
958  size_type count(const Key & key) const
959  {
960  Kdata & kdata = const_cast<multimap*>(this)->key_kdata(key);
961  Knode * p = const_cast<multimap*>(this)->k_tree.search(kdata);
962  if (p == nullptr)
963  return 0;
964 
965  return KEY(p).num_reps;
966  }
967 
970  iterator find(const Key & key) const
971  {
972  Knode * p = k_tree.search(key_kdata(key));
973  if (p == nullptr)
974  return end();
975 
976  return iterator(this, p);
977  }
978 
980  iterator lower_bound(const Key & key) const
981  {
982  if (k_tree.is_empty())
983  return end();
984 
985  std::pair<int, Knode*> p = k_tree.find_position(key_kdata(key));
986  Knode * kp = p.second;
987 
988  iterator ret = iterator(this, kp);
989 
990  if (Aleph::are_equals <Key, Compare> (KEY(kp).key, key))
991  return ret;
992 
993  if (p.first == k_tree.size()) // ¿clave mayor que todas las contenidas?
994  return end();
995 
996  if (p.first == -1)
997  return begin();
998 
999  if (Compare () (ret->first, key)) // key > *ret
1000  ret.forward_k_it();
1001 
1002  return ret;
1003  }
1004 
1007  iterator upper_bound(const Key & key) const
1008  {
1009  if (k_tree.is_empty())
1010  return end();
1011 
1012  std::pair<int, Knode*> p = k_tree.find_position(key_kdata(key));
1013  Knode * kp = p.second;
1014 
1015  iterator ret = iterator(this, kp);
1016 
1017  if (Aleph::are_equals <Key, Compare> (KEY(kp).key, key))
1018  ret.forward_k_it();
1019 
1020  if (p.first == k_tree.size()) // ¿clave mayor que todas las contenidas?
1021  return end();
1022 
1023  if (p.first == -1)
1024  return begin();
1025 
1026  if (Compare () (ret->first, key)) // key > *ret
1027  ret.forward_k_it();
1028 
1029  return ret;
1030  }
1031 
1034  std::pair<iterator,iterator> equal_range(const Key & key) const
1035  {
1036  Knode * p = k_tree.search(key_kdata(key));
1037  if (p == nullptr)
1038  {
1039  iterator e = end();
1040  return std::pair<iterator,iterator>(e, e);
1041  }
1042 
1043  iterator first(this, p);
1044  iterator last(this, p);
1045  last += KEY(p).num_reps;
1046 
1047  return std::pair<iterator,iterator>(first, last);
1048  }
1049 
1051  void swap(multimap & other)
1052  {
1053  k_tree.swap(other.k_tree);
1054  std::swap(num_elem, other.num_elem);
1055  }
1056 
1062  bool operator < (const multimap & rhs) const
1063  {
1064  K_Itor kit1(const_cast<multimap*>(this)->k_tree);
1065  K_Itor kit2(const_cast<multimap&>(rhs).k_tree);
1066  for (; kit1.has_curr() and kit2.has_curr(); kit1.next_ne(), kit2.next_ne())
1067  {
1068  Kdata & kdata1 = KEY(kit1.get_curr_ne());
1069  Kdata & kdata2 = KEY(kit2.get_curr_ne());
1070 
1071  const size_t & n1 = kdata1.num_reps;
1072  const size_t & n2 = kdata2.num_reps;
1073 
1074  if (n1 != n2)
1075  return n1 > n2;
1076 
1077  const Key & key1 = kdata1.key;
1078  const Key & key2 = kdata2.key;
1079  if (Compare () (key1, key2))
1080  return true;
1081  else if (Compare () (key2, key1))
1082  return false;
1083  }
1084 
1085  if (kit1.has_curr() or kit2.has_curr())
1086  return kit2.has_curr();
1087 
1088  return false;
1089  }
1090 
1096  bool operator <= (const multimap & rhs) const
1097  {
1098  K_Itor kit1(const_cast<multimap*>(this)->k_tree);
1099  K_Itor kit2(const_cast<multimap&>(rhs).k_tree);
1100  for (; kit1.has_curr() and kit2.has_curr(); kit1.next_ne(), kit2.next_ne())
1101  {
1102  Kdata & kdata1 = KEY(kit1.get_curr_ne());
1103  Kdata & kdata2 = KEY(kit2.get_curr_ne());
1104 
1105  const size_t & n1 = kdata1.num_reps;
1106  const size_t & n2 = kdata2.num_reps;
1107 
1108  if (n1 != n2)
1109  return n1 > n2;
1110 
1111  const Key & key1 = kdata1.key;
1112  const Key & key2 = kdata2.key;
1113  if (Compare () (key1, key2))
1114  return true;
1115  else if (Compare () (key2, key1))
1116  return false;
1117  }
1118 
1119  if (kit1.has_curr() or kit2.has_curr())
1120  return kit2.has_curr();
1121 
1122  return true;
1123  }
1124 
1126  bool operator == (const multimap & rhs) const
1127  {
1128  if (size() != rhs.size())
1129  return false;
1130 
1131  K_Itor kit1(const_cast<multimap*>(this)->k_tree);
1132  K_Itor kit2(const_cast<multimap&>(rhs).k_tree);
1133  for (; kit1.has_curr() and kit2.has_curr(); kit1.next_ne(), kit2.next_ne())
1134  {
1135  Kdata & kdata1 = KEY(kit1.get_curr_ne());
1136  Kdata & kdata2 = KEY(kit2.get_curr_ne());
1137 
1138  if (kdata1.num_reps != kdata2.num_reps)
1139  return false;
1140 
1141  const Key & key1 = kdata1.key;
1142  const Key & key2 = kdata2.key;
1143  if (Compare () (key1, key2))
1144  return false;
1145  else if (Compare () (key2, key1))
1146  return false;
1147  }
1148 
1149  if (kit1.has_curr() or kit2.has_curr())
1150  return false;
1151 
1152  return true;
1153  }
1154 
1156  bool operator != (const multimap & rhs) const
1157  {
1158  return not (*this == rhs);
1159  }
1160 
1166  bool operator > (const multimap & rhs) const
1167  {
1168  return rhs < *this;
1169  }
1170 
1176  bool operator >= (const multimap & rhs) const
1177  {
1178  return rhs <= *this;
1179  }
1180 
1194  const T & operator [] (const Key & key)
1195  {
1196  iterator ret = insert(make_pair(key, T()));
1197 
1198  return ret->second;
1199  }
1200 
1203  const T & operator [] (const Key & key) const
1204  {
1205  iterator ret = find(key);
1206  if (ret == end())
1207  throw std::domain_error("key not found on constant multimap");
1208 
1209  return ret->second;
1210  }
1211  };
1212 
1213 } // end namespace Aleph
1214 
1215 
1216 # endif // ALEPH_MULTIMAP_H
iterator erase(const_iterator &position)
Elimina del multimapeo el elemento situado en position.
Definition: Multimap.H:904
iterator insert(const value_type &value)
Definition: Multimap.H:777
iterator erase(iterator first, const_iterator &last)
Definition: Multimap.H:942
bool operator<(const multimap &rhs) const
Definition: Multimap.H:1062
bool operator>(const multimap &rhs) const
Definition: Multimap.H:1166
void clear()
Vacía el multimapeo. Todos los elementos son borrados.
Definition: Multimap.H:216
const iterator const_iterator
iterador constante
Definition: Multimap.H:769
Pair value_type
Tipo de valor de clave manejado (que es un par)
Definition: Multimap.H:225
bool operator<=(const multimap &rhs) const
Definition: Multimap.H:1096
iterator()
Constructor vacío; uso indefinido.
Definition: Multimap.H:363
const size_t & size() const
Definition: Multimap.H:240
multimap::reference reference
Tipo referencia a elemento dentro del multi-mapeo.
Definition: Multimap.H:341
const T & operator[](const Key &key)
Definition: Multimap.H:1194
iterator(const multimap &mm)
Definition: Multimap.H:345
iterator insert(const_iterator &hint, const value_type &value)
Definition: Multimap.H:870
Definition: Multimap.H:271
iterator end() const
retorna un iterador al último elemento del multimapeo.
Definition: Multimap.H:955
void insert(InputIterator first, const InputIterator &last)
Definition: Multimap.H:815
multimap(InputIterator first, const InputIterator &last)
Construye un multimapeo con los pares del rango [first,last).
Definition: Multimap.H:823
bool operator==(const multimap &rhs) const
Retorna true si this es exactamente igual a rhs.
Definition: Multimap.H:1126
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
multimap::value_type * pointer
Tipo apuntador a elemento dentro del multi-mapeo.
Definition: Multimap.H:338
size_type max_size() const
Definition: Multimap.H:244
Definition: ah-comb.H:35
bool operator!=(const multimap &rhs) const
Retorna true si this es distinto de rhs.
Definition: Multimap.H:1156
void destroyRec(Node *&root) noexcept
Definition: tpl_binNodeUtils.H:500
iterator(const iterator &it)
Constructor copia (masivamente usado por el estándar)
Definition: Multimap.H:353
Definition: Multimap.H:103
Definition: tpl_treapRk.H:1010
multimap & operator=(const multimap &m)
Definition: Multimap.H:839
size_type count(const Key &key) const
retorna la cantidad pares con clave igual a key
Definition: Multimap.H:958
iterator upper_bound(const Key &key) const
Definition: Multimap.H:1007
size_type erase(const key_type &key)
Definition: Multimap.H:915
void swap(multimap &other)
Intercambia los valores de this con los de other.
Definition: Multimap.H:1051
Node * copyRec(Node *root)
Definition: tpl_binNodeUtils.H:519
iterator find(const Key &key) const
Definition: Multimap.H:970
multimap::value_type & reference
Referencia al par.
Definition: Multimap.H:228
iterator begin() const
retorna un iterador al primer elemento del multimapeo.
Definition: Multimap.H:952
std::pair< iterator, iterator > equal_range(const Key &key) const
Definition: Multimap.H:1034
iterator lower_bound(const Key &key) const
Retorna un iterador posicionado en el lugar donde sería insertado key.
Definition: Multimap.H:980
multimap::size_type difference_type
Definition: Multimap.H:335
multimap(const multimap &m)
Constructor copia.
Definition: Multimap.H:830
bool empty() const
Definition: Multimap.H:258
multimap::value_type value_type
El tipo de dato que contiene el multi-mapeo.
Definition: Multimap.H:331
bool operator>=(const multimap &rhs) const
Definition: Multimap.H:1176

Leandro Rabindranath León