Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_dynDlist.H
1 # ifndef TPL_DYNDLIST_H
2 # define TPL_DYNDLIST_H
3 
4 # include <ahFunctional.H>
5 # include <ahDry.H>
6 # include <tpl_dnode.H>
7 
8 using namespace Aleph;
9 
10 namespace Aleph {
11 
25  template <typename T = int>
26 class DynDlist : public Dnode<T>
27 {
28  size_t num_elem;
29 
30 public:
31 
33  typedef DynDlist Set_Type;
34 
36  typedef T Item_Type;
37 
38  typedef T Key_Type;
39 
41  const size_t & size() const { return num_elem; }
42 
43  DynDlist() : num_elem(0) { /* Empty */ }
44 
45  void empty()
46  {
47  while (not this->is_empty())
48  delete this->remove_next();
49 
50  num_elem = 0;
51  }
52 
54  {
55  empty();
56  }
57 
58 private:
59 
60  T & __insert(Dnode<T> * p)
61  {
63  ++num_elem;
64  return p->get_data();
65  }
66 
67  T & __append(Dnode<T> * p)
68  {
70  ++num_elem;
71  return p->get_data();
72  }
73 
74 public:
75 
86  T & insert(const T & item) throw(std::exception, std::bad_alloc)
87  {
88  return __insert(new Dnode<T> (item));
89  }
90 
91  T & insert(T && item)
92  {
93  return __insert(new Dnode<T> (std::move(item)));
94  }
95 
106  T & append(const T & item) throw(std::exception, std::bad_alloc)
107  {
108  return __append(new Dnode<T> (item));
109  }
110 
111  T & append(T && item) throw(std::exception, std::bad_alloc)
112  {
113  return __append(new Dnode<T> (std::move(item)));
114  }
115 
131  size_t insert_list(const DynDlist & list)
132  {
133  Dlink::insert_list(&list);
134  num_elem += list.num_elem;
135  list.num_elem = 0;
136 
137  I(list.is_empty());
138 
139  return num_elem;
140  }
141 
142  size_t insert_list(DynDlist && list)
143  {
145  num_elem += list.num_elem;
146  list.num_elem = 0;
147 
148  I(list.is_empty());
149 
150  return num_elem;
151  }
152 
169  {
170  Dlink::append_list(&list);
171  num_elem += list.num_elem;
172  list.num_elem = 0;
173 
174  I(list.is_empty());
175 
176  return num_elem;
177  }
178 
179  size_t append_list(DynDlist && list)
180  {
182  num_elem += list.num_elem;
183  list.num_elem = 0;
184 
185  I(list.is_empty());
186 
187  return num_elem;
188  }
189 
191  T & get_first() throw(std::exception, std::underflow_error)
192  {
193  return this->get_next()->get_data();
194  }
195 
196  const T & get_first() const throw(std::exception, std::underflow_error)
197  {
198  return const_cast<DynDlist&>(*this).get_next()->get_data();
199  }
200 
202  T & get_last() throw(std::exception, std::underflow_error)
203  {
204  return this->get_prev()->get_data();
205  }
206 
207  const T & get_last() const throw(std::exception, std::underflow_error)
208  {
209  return const_cast<DynDlist&>(*this).get_prev()->get_data();
210  }
211 
218  T remove_first() throw(std::exception, std::underflow_error)
219  {
220  Dnode<T> * ptr = this->remove_next();
221  T retVal = ptr->get_data();
222  delete ptr;
223  --num_elem;
224 
225  return retVal;
226  }
227 
234  T remove_last() throw(std::exception, std::underflow_error)
235  {
236  Dnode<T> * ptr = this->remove_prev();
237  T retVal = ptr->get_data();
238  delete ptr;
239  --num_elem;
240 
241  return retVal;
242  }
243 
245  T & put(const T & item) { return append(item); }
246 
247  T & put(T && item) { return append(std::move(item)); }
248 
250  T get() { return remove_first(); }
251 
253  T & rear() { return get_last(); }
254 
256  T & front() { return get_first(); }
257 
259  T & push(const T & item) { return insert(item); }
260 
262  T & push(T && item) { return insert(std::move(item)); }
263 
265  T pop() { return remove_first(); }
266 
268  T & top() const { return get_first(); }
269 
272  void remove(T & data)
273  {
274  Dnode<T> * p = Dnode<T>::data_to_node(data);
275  p->del();
276  delete p;
277  --num_elem;
278  }
279 
282  void erase(T & data)
283  {
284  remove(data);
285  }
286 
295  void swap(DynDlist & l)
296  {
297  std::swap(num_elem, l.num_elem);
298  this->Dlink::swap(&l);
299  }
300 
313  void split_list(DynDlist & l, DynDlist & r)
314  throw(std::exception, std::domain_error)
315  {
316  if ((not l.is_empty()) or (not r.is_empty()))
317  throw std::domain_error("lists are not empty");
318 
319  Dlink::split_list(l, r);
320  l.num_elem = r.num_elem = num_elem/2;
321 
322  if (num_elem % 2 == 1) // ¿es num_elem impar?
323  l.num_elem++;
324 
325  num_elem = 0;
326  }
327 
332  class Iterator : public Dnode<T>::Iterator
333  {
334  DynDlist * list_ptr; // puntero a la lista
335  int pos; // posición del elemento actual en la secuencia
336 
337  public:
340 
342  typedef T Item_Type;
343 
345  const int & get_pos() const { return pos; }
346 
352  const int & next()
353  {
355  pos++;
356  return pos;
357  }
358 
364  const int & prev()
365  {
367  pos--;
368  return pos;
369  }
370 
376  const int & reset_first()
377  {
379  pos = 0;
380  return pos;
381  }
382 
389  const int & reset_last()
390  {
392  pos = list_ptr->num_elem - 1;
393  return pos;
394  }
395 
398  : Dnode<T>::Iterator(_list), list_ptr(&_list), pos(0)
399  {
400  // empty
401  }
402 
404  Iterator(const DynDlist<T> & _list)
405  : Dnode<T>::Iterator(const_cast<DynDlist<T>&>(_list)),
406  list_ptr(&const_cast<DynDlist<T>&>(_list)), pos(0)
407  {
408  // empty
409  }
410 
411  Iterator() : list_ptr(NULL)
412  {
413  // empty
414  }
415 
418  {
420  list_ptr = it.list_ptr;
421  pos = it.pos;
422 
423  return *this;
424  }
425 
427  T & get_current() const
428  {
429  return Dnode<T>::Iterator::get_current()->get_data();
430  }
431 
433  T & get_curr() const
434  {
435  return get_current();
436  }
437 
448  void insert(const T & item)
449  throw(std::exception, std::overflow_error, std::bad_alloc)
450  {
451  if (not this->has_current())
452  throw std::overflow_error ("DynDlist Iterator has not current");
453 
454  Dnode<T>::Iterator::get_current()->insert(new Dnode<T>(item));
455  ++list_ptr->num_elem;
456  }
457 
458  void insert(T && item)
459  throw(std::exception, std::overflow_error, std::bad_alloc)
460  {
461  if (not this->has_current())
462  throw std::overflow_error ("DynDlist Iterator has not current");
463 
465  insert(new Dnode<T>(std::move(item)));
466  ++list_ptr->num_elem;
467  }
468 
479  void append(const T & item)
480  throw(std::exception, std::overflow_error, std::bad_alloc)
481  {
482  if (not this->has_current())
483  throw std::overflow_error ("DynDlist Iterator has not current");
484 
485  Dnode<T>::Iterator::get_current()->append(new Dnode<T>(item));
486  ++list_ptr->num_elem;
487  }
488 
489  void append(T && item)
490  throw(std::exception, std::overflow_error, std::bad_alloc)
491  {
492  if (not this->has_current())
493  throw std::overflow_error ("DynDlist Iterator has not current");
494 
496  append(new Dnode<T>(std::move(item)));
497  ++list_ptr->num_elem;
498  }
499 
516  void insert_list(const DynDlist & list)
517  throw(std::exception, std::overflow_error)
518  {
519 
520  if (not this->has_current())
521  throw std::overflow_error ("DynDlist Iterator has not current");
522 
523  Dnode<T>::Iterator::get_current()->insert_list(&list);
524  list_ptr->num_elem += list.num_elem;
525  list.num_elem = 0;
526 
527  I(list.is_empty());
528  }
529 
546  void append_list(const DynDlist & list)
547  throw(std::exception, std::overflow_error)
548  {
549  if (not this->has_current())
550  throw std::overflow_error ("DynDlist Iterator has not current");
551 
552  Dnode<T>::Iterator::get_current()->append_list(&list);
553  list_ptr->num_elem += list.num_elem;
554  list.num_elem = 0;
555 
556  I(list.is_empty());
557  }
558 
568  T del() throw(std::exception, std::overflow_error)
569  {
570  if (not this->has_current())
571  throw std::overflow_error ("DynDlist Iterator has not current");
572 
574  T ret_val = ptr->get_data();
576  ptr->del();
577  delete ptr;
578  --list_ptr->num_elem;
579  return ret_val;
580  }
581 
592  T remove_prev() throw(std::exception, std::overflow_error)
593  {
594  if (not this->has_current())
595  throw std::overflow_error ("DynDlist Iterator has not current");
596 
598  Dnode<T> * ptr = curr_ptr->remove_prev();
599  T ret_val = ptr->get_data();
600  delete ptr;
601  --list_ptr->num_elem;
602 
603  return ret_val;
604  }
605 
616  T remove_next() throw(std::exception, std::overflow_error)
617  {
618 
619  if (not this->has_current())
620  throw std::overflow_error ("DynDlist Iterator has not current");
621 
623  Dnode<T> * ptr = curr_ptr->remove_next();
624  T ret_val = ptr->get_data();
625  delete ptr;
626  --list_ptr->num_elem;
627 
628  return ret_val;
629  }
630 
653  {
654  if (not this->has_current())
655  throw std::overflow_error ("DynDlist Iterator has not current");
656 
657  list_ptr->Dnode<T>::cut_list(Dnode<T>::Iterator::get_current(), &list);
658  list.num_elem = list_ptr->num_elem - pos;
659  list_ptr->num_elem -= pos;
660 
661  return list.num_elem;
662  }
663  };
664 
674  {
675  if (this == &list)
676  return *this;
677 
678  empty();
679 
680  I(this->is_empty());
681 
682  for (typename DynDlist<T>::Iterator itor(const_cast<DynDlist&>(list));
683  itor.has_current();itor.next())
684  this->append(itor.get_current());
685 
686  return *this;
687  }
688 
690  DynDlist(const DynDlist & list) : Dnode<T>(list)
691  {
692  this->reset();
693  num_elem = 0;
694 
695  I(this->is_empty());
696 
697  for (typename DynDlist<T>::Iterator itor(const_cast<DynDlist&>(list));
698  itor.has_current();itor.next())
699  this->append(itor.get_current());
700  }
701 
704  DynDlist(DynDlist<T> && list) : Dnode<T>(std::move(list)), num_elem(0)
705  {
706  swap(list);
707  }
708 
709  DynDlist(std::initializer_list<T> l)
710  {
711  std::for_each(l.begin(), l.end(), /* Lambda */ [this] (const T & item)
712  {
713  append(item);
714  }
715  );
716  }
717 
727  {
728  swap(list);
729  return *this;
730  }
731 
732  T & operator [] (const size_t & n)
733  {
734  typename DynDlist<T>::Iterator it(*this);
735 
736  for (int i = 0; i < n and it.has_current(); i++, it.next()) ;
737 
738  return it.get_current();
739  }
740 
741  Generic_Traverse(T);
742 
743  Functional_Methods(T);
744 };
745 
746 } // end namespace Aleph
747 
748 # endif /* TPL_DYNDLIST_H */
749 
void swap(DynDlist &l)
Definition: tpl_dynDlist.H:295
T & rear()
Si this e suna cola, entonces retorna el elemento más joven.
Definition: tpl_dynDlist.H:253
DynDlist< T > & operator=(const DynDlist &list)
Definition: tpl_dynDlist.H:673
const int & reset_last()
Definition: tpl_dynDlist.H:389
T & get_curr() const
Retorna el elemento actual del iterador.
Definition: tpl_dynDlist.H:433
const int & prev()
Definition: tpl_dynDlist.H:364
Definition: tpl_dynDlist.H:26
Dnode< T > * remove_next()
Elimina sucesor a this y retorna su dirección.
Definition: tpl_dnode.H:37
~DynDlist()
Destructor.
Definition: tpl_dynDlist.H:53
T & front()
Si this e suna cola, entonces retorna el elemento más antiguo.
Definition: tpl_dynDlist.H:256
const int & next()
Definition: tpl_dynDlist.H:352
T & put(const T &item)
Si this es una cola, entonces mete el elemento item.
Definition: tpl_dynDlist.H:245
const size_t & size() const
Retorna la cantidad de elemento que tiene la lista.
Definition: tpl_dynDlist.H:41
T & push(const T &item)
Si this es una pila, entonces inserta item.
Definition: tpl_dynDlist.H:259
T pop()
Si this es una pila, entonces elimina el tope.
Definition: tpl_dynDlist.H:265
const int & reset_first()
Definition: tpl_dynDlist.H:376
size_t cut_list(DynDlist &list)
Definition: tpl_dynDlist.H:652
Iterator(const DynDlist< T > &_list)
Constructor de iterador sobre lista constante _list.
Definition: tpl_dynDlist.H:404
Definition: tpl_dynDlist.H:332
T & push(T &&item)
Si this es una pila, entonces inserta item.
Definition: tpl_dynDlist.H:262
DynDlist(DynDlist< T > &&list)
Definition: tpl_dynDlist.H:704
Dnode< T > *& get_next()
Retorna referencia a puntero de nodo siguiente a this.
Definition: tpl_dnode.H:28
T remove_last()
Definition: tpl_dynDlist.H:234
DynDlist Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_dynDlist.H:339
Operation for_each(Itor beg, const Itor &end, Operation op)
Definition: ahAlgo.H:83
T & get_first()
Retorna una referencia al primer elemento de la lista.
Definition: tpl_dynDlist.H:191
T Item_Type
El tipo de elemento que alberga el conjunto.
Definition: tpl_dynDlist.H:36
void insert(const T &item)
Definition: tpl_dynDlist.H:448
void empty()
Vacía todos los elementos de la lista.
Definition: tpl_dynDlist.H:45
Iterator & operator=(const Iterator &it)
Asignación e iterador.
Definition: tpl_dynDlist.H:417
T remove_next()
Definition: tpl_dynDlist.H:616
void insert_list(const DynDlist &list)
Definition: tpl_dynDlist.H:516
const int & get_pos() const
retorna la posición ordinal del elemento actual de iterador.
Definition: tpl_dynDlist.H:345
T remove_prev()
Definition: tpl_dynDlist.H:592
Dnode< T > *& get_prev()
Retorna referencia a puntero de nodo previo a this.
Definition: tpl_dnode.H:31
T Item_Type
El tipo de elemento que retorna get_current().
Definition: tpl_dynDlist.H:342
DynDlist(const DynDlist &list)
Constructor copia; todos los elementos de this son copiados.
Definition: tpl_dynDlist.H:690
Dnode< T > * remove_prev()
Elimina anterior a this y retorna su dirección.
Definition: tpl_dnode.H:34
void split_list(DynDlist &l, DynDlist &r)
Definition: tpl_dynDlist.H:313
void append_list(const DynDlist &list)
Definition: tpl_dynDlist.H:546
T & get_last()
Retorna una referencia al último elemento de la lista.
Definition: tpl_dynDlist.H:202
T & top() const
Si this es una pila, entonces retorna el tope.
Definition: tpl_dynDlist.H:268
void erase(T &data)
Definition: tpl_dynDlist.H:282
size_t insert_list(const DynDlist &list)
Definition: tpl_dynDlist.H:131
Dnode< T > * get_current() const
retorna puntero al nodo actual
Definition: tpl_dnode.H:181
size_t append_list(DynDlist &list)
Definition: tpl_dynDlist.H:168
T & get_current() const
Retorna el elemento actual del iterador.
Definition: tpl_dynDlist.H:427
DynDlist Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_dynDlist.H:33
Iterator & operator=(Dnode *head)
Asigna al iterador la lista apuntada por head */.
Definition: tpl_dnode.H:175
T del()
Definition: tpl_dynDlist.H:568
Definition: List.H:23
T remove_first()
Definition: tpl_dynDlist.H:218
void append(const T &item)
Definition: tpl_dynDlist.H:479
Iterator(DynDlist< T > &_list)
Constructor de iterador sobre lista _list.
Definition: tpl_dynDlist.H:397
T & insert(const T &item)
Definition: tpl_dynDlist.H:86
T & get_data()
Retorna referencia a dato contenido en el nodo.
Definition: tpl_dnode.H:126
T & append(const T &item)
Definition: tpl_dynDlist.H:106
Nodo perteneciente a lista doblemente enlazada circular.
Definition: tpl_dnode.H:19

Leandro Rabindranath León