00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_DYNDLIST_H
00045 # define TPL_DYNDLIST_H
00046
00047 # include <tpl_dlist.H>
00048
00049 using namespace Aleph;
00050
00051 namespace Aleph {
00052
00064 template <typename T>
00065 class DynDlist : public Dlist<T>
00066 {
00067
00068 size_t num_elem;
00069 public:
00070
00072 const size_t & size() const { return num_elem; }
00074 DynDlist() : num_elem(0) { }
00084 void insert(const T & _data)
00085
00086 throw(std::exception, std::bad_alloc)
00087
00088 {
00089 typename Dlist<T>::Node* ptr = new typename Dlist<T>::Node (_data);
00090 Dlist<T>::insert(ptr);
00091 ++num_elem;
00092 }
00093
00103 void append(const T & _data)
00104
00105 throw(std::exception, std::bad_alloc)
00106
00107 {
00108 typename Dlist<T>::Node* ptr = new typename Dlist<T>::Node (_data);
00109 Dlist<T>::append(ptr);
00110 ++num_elem;
00111 }
00127 size_t insert_list(DynDlist & list)
00128 {
00129 Dlink::insert_list(&list);
00130 num_elem += list.num_elem;
00131 list.num_elem = 0;
00132
00133
00134 I(list.is_empty());
00135
00136 return num_elem;
00137 }
00138
00154 size_t append_list(DynDlist & list)
00155 {
00156 Dlink::append_list(&list);
00157 num_elem += list.num_elem;
00158 list.num_elem = 0;
00159
00160
00161 I(list.is_empty());
00162
00163 return num_elem;
00164 }
00166 T & get_first()
00167
00168 throw(std::exception, std::underflow_error)
00169
00170 {
00171 return Dlist<T>::get_first()->get_data();
00172 }
00173
00175 T & get_last()
00176
00177 throw(std::exception, std::underflow_error)
00178
00179 {
00180 return Dlist<T>::get_last()->get_data();
00181 }
00188 T remove_first()
00189
00190 throw(std::exception, std::underflow_error)
00191
00192 {
00193 typename Dlist<T>::Node* ptr = Dlist<T>::remove_first();
00194 T retVal = ptr->get_data();
00195 delete ptr;
00196
00197 --num_elem;
00198
00199 return retVal;
00200 }
00201
00208 T remove_last()
00209
00210 throw(std::exception, std::underflow_error)
00211
00212 {
00213 typename Dlist<T>::Node* ptr = Dlist<T>::remove_last();
00214 T retVal = ptr->get_data();
00215 delete ptr;
00216
00217 --num_elem;
00218
00219 return retVal;
00220 }
00221 void empty()
00222 {
00223 while (not this->is_empty())
00224 {
00225 typename Dlist<T>::Node* ptr = Dlist<T>::remove_first();
00226
00227 delete ptr;
00228 }
00229
00230 num_elem = 0;
00231 }
00232 ~DynDlist()
00233 {
00234 empty();
00235 }
00244 void swap(DynDlist & l)
00245 {
00246 Aleph::swap(num_elem, l.num_elem);
00247 this->Dlink::swap(&l);
00248 }
00261 void split_list(DynDlist & l, DynDlist & r)
00262
00263 throw(std::exception, std::domain_error)
00264
00265 {
00266
00267 if ((not l.is_empty()) or (not r.is_empty()))
00268 throw std::domain_error("lists are not empty");
00269
00270 Dlink::split_list(l, r);
00271
00272 l.num_elem = r.num_elem = num_elem/2;
00273
00274 if (num_elem % 2 == 1)
00275 l.num_elem++;
00276
00277 num_elem = 0;
00278 }
00283 class Iterator : public Dlist<T>::Iterator
00284 {
00285 DynDlist * list_ptr;
00286 int pos;
00287
00288 public:
00289
00290
00292 const int & get_pos() const { return pos; }
00298 const int & next()
00299 {
00300 Dlist<T>::Iterator::next();
00301 pos++;
00302
00303 return pos;
00304 }
00305
00311 const int & prev()
00312 {
00313 Dlist<T>::Iterator::prev();
00314 pos--;
00315
00316 return pos;
00317 }
00318
00323 const int & reset_first()
00324 {
00325 Dlist<T>::Iterator::reset_first();
00326 pos = 0;
00327
00328 return pos;
00329 }
00330
00336 const int & reset_last()
00337 {
00338 Dlist<T>::Iterator::reset_last();
00339 pos = list_ptr->num_elem - 1;
00340
00341 return pos;
00342 }
00344 Iterator(DynDlist<T> & _list)
00345 : Dlist<T>::Iterator(_list), list_ptr(&_list), pos(0)
00346 { }
00347
00349 Iterator(const DynDlist<T> & _list)
00350 : Dlist<T>::Iterator(const_cast<DynDlist<T>&>(_list)),
00351 list_ptr(&const_cast<DynDlist<T>&>(_list)), pos(0)
00352 { }
00353
00354
00356 Iterator(const Iterator & it)
00357 : Dlist<T>::Iterator(it), list_ptr(it.list_ptr), pos(it.pos)
00358 { }
00359
00360 Iterator() : list_ptr(NULL){ }
00361
00363 Iterator & operator = (const Iterator & it)
00364 {
00365 Dlist<T>::Iterator::operator = (it);
00366 list_ptr = it.list_ptr;
00367 pos = it.pos;
00368
00369 return *this;
00370 }
00372 T & get_current() { return Dlist<T>::Iterator::get_current()->get_data(); }
00383 void insert(const T & _data)
00384
00385 throw(std::exception, std::overflow_error, std::bad_alloc)
00386
00387 {
00388
00389 if (not this->has_current())
00390 throw std::overflow_error ("DynDlist Iterator has not current");
00391
00392 typename Dlist<T>::Node* node = new typename Dlist<T>::Node (_data);
00393 Dlist<T>::Iterator::get_current()->insert(node);
00394 ++list_ptr->num_elem;
00395 }
00396
00407 void append(const T & _data)
00408
00409 throw(std::exception, std::overflow_error, std::bad_alloc)
00410
00411 {
00412
00413 if (not this->has_current())
00414 throw std::overflow_error ("DynDlist Iterator has not current");
00415
00416 typename Dlist<T>::Node* node = new typename Dlist<T>::Node (_data);
00417 Dlist<T>::Iterator::get_current()->append(node);
00418 ++list_ptr->num_elem;
00419 }
00436 void insert_list(const DynDlist & list)
00437
00438 throw(std::exception, std::overflow_error)
00439
00440 {
00441
00442 if (not this->has_current())
00443 throw std::overflow_error ("DynDlist Iterator has not current");
00444
00445 Dlist<T>::Iterator::get_current()->insert_list(&list);
00446 list_ptr->num_elem += list.num_elem;
00447 list.num_elem = 0;
00448
00449 I(list.is_empty());
00450
00451 }
00452
00469 void append_list(const DynDlist & list)
00470
00471 throw(std::exception, std::overflow_error)
00472
00473 {
00474
00475 if (not this->has_current())
00476 throw std::overflow_error ("DynDlist Iterator has not current");
00477
00478 Dlist<T>::Iterator::get_current()->append_list(&list);
00479 list_ptr->num_elem += list.num_elem;
00480 list.num_elem = 0;
00481
00482 I(list.is_empty());
00483
00484 }
00494 T del()
00495
00496 throw(std::exception, std::overflow_error)
00497
00498 {
00499
00500 if (not this->has_current())
00501 throw std::overflow_error ("DynDlist Iterator has not current");
00502
00503 typename Dlist<T>::Node* ptr = Dlist<T>::Iterator::get_current();
00504
00505 T ret_val = ptr->get_data();
00506
00507 Dlist<T>::Iterator::next();
00508
00509 ptr->del();
00510 delete ptr;
00511
00512 --list_ptr->num_elem;
00513
00514 return ret_val;
00515 }
00526 T remove_prev()
00527
00528 throw(std::exception, std::overflow_error)
00529
00530 {
00531
00532 if (not this->has_current())
00533 throw std::overflow_error ("DynDlist Iterator has not current");
00534
00535 Dnode<T> * curr_ptr = Dlist<T>::Iterator::get_current();
00536
00537 Dnode<T> * ptr = curr_ptr->remove_prev();
00538
00539 T ret_val = ptr->get_data();
00540
00541 delete ptr;
00542
00543 --list_ptr->num_elem;
00544
00545 return ret_val;
00546 }
00547
00558 T remove_next()
00559
00560 throw(std::exception, std::overflow_error)
00561
00562 {
00563
00564 if (not this->has_current())
00565 throw std::overflow_error ("DynDlist Iterator has not current");
00566
00567 Dnode<T> * curr_ptr = Dlist<T>::Iterator::get_current();
00568
00569 Dnode<T> * ptr = curr_ptr->remove_next();
00570
00571 T ret_val = ptr->get_data();
00572
00573 delete ptr;
00574
00575 --list_ptr->num_elem;
00576
00577 return ret_val;
00578 }
00600 size_t cut_list(DynDlist & list)
00601 {
00602
00603 if (not this->has_current())
00604 throw std::overflow_error ("DynDlist Iterator has not current");
00605
00606 list_ptr->Dlist<T>::cut_list(Dlist<T>::Iterator::get_current(),
00607 &list);
00608
00609 list.num_elem = list_ptr->num_elem - pos;
00610 list_ptr->num_elem -= pos;
00611
00612 return list.num_elem;
00613 }
00614 };
00623 DynDlist<T> & operator = (const DynDlist & list)
00624 {
00625
00626 if (this == &list)
00627 return *this;
00628
00629 while (not this->is_empty())
00630 this->remove_first();
00631
00632
00633 I(this->is_empty());
00634
00635 typename DynDlist<T>::Iterator itor(const_cast<DynDlist&>(list));
00636
00637 while (itor.has_current())
00638 {
00639 this->append(itor.get_current());
00640
00641 itor.next();
00642 }
00643
00644 return *this;
00645 }
00647 DynDlist(const DynDlist & list) : Dlist<T>(list)
00648 {
00649 this->reset();
00650
00651 I(this->is_empty());
00652
00653 typename DynDlist<T>::Iterator itor(const_cast<DynDlist&>(list));
00654
00655 while (itor.has_current())
00656 {
00657 this->append(itor.get_current());
00658
00659 itor.next();
00660 }
00661 }
00662 };
00663
00664 }
00665
00666 # endif
00667