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

Leandro Rabindranath León