00001
00002 #ifndef DUNE__SLLIST_HH
00003 #define DUNE__SLLIST_HH
00004
00005 #include<memory>
00006 #include <cassert>
00007 #include"iteratorfacades.hh"
00008 #include<ostream>
00009
00010 namespace Dune
00011 {
00023 template<typename T, class A>
00024 class SLListIterator;
00025
00026 template<typename T, class A>
00027 class SLListConstIterator;
00028
00029 template<typename T, class A>
00030 class SLListModifyIterator;
00031
00039 template<typename T, class A=std::allocator<T> >
00040 class SLList
00041 {
00042 class Element;
00043 friend class SLListIterator<T,A>;
00044 friend class SLListConstIterator<T,A>;
00045
00046 public:
00047
00051 typedef typename A::size_type size_type;
00052
00056 typedef T MemberType;
00057
00061 typedef typename A::template rebind<Element>::other Allocator;
00062
00066 typedef SLListIterator<T,A> iterator;
00067
00071 typedef SLListConstIterator<T,A> const_iterator;
00072
00076 SLList();
00077
00081 template<typename T1, typename A1>
00082 SLList(const SLList<T1,A1>& other);
00083
00087 SLList(const SLList<T,A>& other);
00088
00094 ~SLList();
00095
00100 typedef SLListModifyIterator<T,A> ModifyIterator;
00101
00105 SLList<T,A>& operator=(const SLList<T,A>& other);
00106
00107
00112 inline void push_back(const MemberType& item);
00113
00118 inline void push_front(const MemberType& item);
00119
00123 inline void pop_front();
00124
00126 inline void clear();
00127
00135 inline iterator begin();
00136
00144 inline const_iterator begin() const;
00145
00153 inline ModifyIterator beginModify();
00154
00162 inline ModifyIterator endModify();
00163
00170 inline iterator end();
00171
00178 inline const_iterator end() const;
00179
00185 inline bool empty() const;
00186
00191 inline int size() const;
00192
00193 private:
00195 struct Element
00196 {
00200 Element* next_;
00204 MemberType item_;
00205
00206 Element(const MemberType& item);
00207
00208 Element();
00209
00210 };
00211
00216 void deleteNext(Element* current);
00217
00222 void copyElements(const SLList<T,A>& other);
00223
00231 template<bool watchForTail>
00232 void deleteNext(Element* current);
00238 void insertAfter(Element* current, const T& item);
00239
00241 Element beforeHead_;
00242
00248 Element* tail_;
00249
00251 Allocator allocator_;
00252
00254 int size_;
00255 };
00256
00260 template<typename T, class A>
00261 class SLListIterator : public Dune::ForwardIteratorFacade<SLListIterator<T,A>, T, T&, std::size_t>
00262 {
00263 friend class SLListConstIterator<T,A>;
00264 friend class SLListModifyIterator<T,A>;
00265 friend class SLList<T,A>;
00266
00267 public:
00268 inline SLListIterator(typename SLList<T,A>::Element* item,
00269 SLList<T,A>* sllist)
00270 : current_(item), list_(sllist)
00271 {}
00272
00273 inline SLListIterator()
00274 : current_(0), list_(0)
00275 {}
00276
00277 inline SLListIterator(const SLListModifyIterator<T,A>& other)
00278 : current_(other.iterator_.current_), list_(other.iterator_.list_)
00279 {}
00280
00285 inline T& dereference() const
00286 {
00287 return current_->item_;
00288 }
00289
00295 inline bool equals(const SLListConstIterator<T,A>& other) const
00296 {
00297 return current_==other.current_;
00298 }
00299
00305 inline bool equals(const SLListIterator<T,A>& other) const
00306 {
00307 return current_==other.current_;
00308 }
00309
00315 inline bool equals(const SLListModifyIterator<T,A>& other) const
00316 {
00317 return current_==other.iterator_.current_;
00318 }
00319
00323 inline void increment()
00324 {
00325 current_ = current_->next_;
00326 }
00327
00333 inline void insertAfter(const T& v)const
00334 {
00335 assert(list_ );
00336 list_->insertAfter(current_, v);
00337 }
00338
00344 inline void deleteNext() const
00345 {
00346 assert(list_);
00347 list_->deleteNext(current_);
00348 }
00349
00350 private:
00352 typename SLList<T,A>::Element* current_;
00354 SLList<T,A>* list_;
00355 };
00356
00360 template<class T, class A>
00361 class SLListConstIterator : public Dune::ForwardIteratorFacade<SLListConstIterator<T,A>, const T, const T&, std::size_t>
00362 {
00363 friend class SLListIterator<T,A>;
00364 friend class SLList<T,A>;
00365
00366 public:
00367 inline SLListConstIterator()
00368 : current_(0)
00369 {}
00370
00371 inline SLListConstIterator(typename SLList<T,A>::Element* item)
00372 : current_(item)
00373 {}
00374
00375 inline SLListConstIterator(const SLListIterator<T,A>& other)
00376 : current_(other.current_)
00377 {}
00378
00379 inline SLListConstIterator(const SLListConstIterator<T,A>& other)
00380 : current_(other.current_)
00381 {}
00382
00383 inline SLListConstIterator(const SLListModifyIterator<T,A>& other)
00384 : current_(other.iterator_.current_)
00385 {}
00386
00391 inline const T& dereference() const
00392 {
00393 return current_->item_;
00394 }
00395
00401 inline bool equals(const SLListConstIterator<T,A>& other) const
00402 {
00403 return current_==other.current_;
00404 }
00405
00409 inline void increment()
00410 {
00411 current_ = current_->next_;
00412 }
00413
00414 private:
00416 typename SLList<T,A>::Element* current_;
00417 };
00418
00422 template<typename T, class A>
00423 class SLListModifyIterator : public Dune::ForwardIteratorFacade<SLListModifyIterator<T,A>, T, T&, std::size_t>
00424 {
00425 friend class SLListConstIterator<T,A>;
00426 friend class SLListIterator<T,A>;
00427 public:
00428 inline SLListModifyIterator(SLListIterator<T,A> beforeIterator,
00429 SLListIterator<T,A> _iterator)
00430 : beforeIterator_(beforeIterator), iterator_(_iterator)
00431 {}
00432
00433 inline SLListModifyIterator(const SLListModifyIterator<T,A>& other)
00434 : beforeIterator_(other.beforeIterator_), iterator_(other.iterator_)
00435 {}
00436
00437 inline SLListModifyIterator()
00438 : beforeIterator_(), iterator_()
00439 {}
00440
00445 inline T& dereference() const
00446 {
00447 return *iterator_;
00448 }
00449
00455 inline bool equals(const SLListConstIterator<T,A>& other) const
00456 {
00457 return iterator_== other;
00458 }
00459
00460
00466 inline bool equals(const SLListIterator<T,A>& other) const
00467 {
00468 return iterator_== other;
00469 }
00470
00471
00477 inline bool equals(const SLListModifyIterator<T,A>& other) const
00478 {
00479 return iterator_== other.iterator_;
00480 }
00481
00485 inline void increment()
00486 {
00487 ++iterator_;
00488 ++beforeIterator_;
00489 }
00490
00504 inline void insert(const T& v)
00505 {
00506 beforeIterator_.insertAfter(v);
00507 ++beforeIterator_;
00508 }
00509
00517 inline void remove()
00518 {
00519 ++iterator_;
00520 beforeIterator_.deleteNext();
00521 }
00522
00523 private:
00525 SLListIterator<T,A> beforeIterator_;
00527 SLListIterator<T,A> iterator_;
00528 };
00529 }
00530
00531 namespace std
00532 {
00533
00534 template<typename T, typename A>
00535 ostream& operator<<(ostream& os, const Dune::SLList<T,A> sllist)
00536 {
00537 typedef typename Dune::SLList<T,A>::const_iterator Iterator;
00538 Iterator end = sllist.end();
00539 Iterator current= sllist.begin();
00540
00541 os << "{ ";
00542
00543 if(current!=end){
00544 os<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
00545 ++current;
00546
00547 for(; current != end; ++current)
00548 os<<", "<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
00549 }
00550 os<<"} ";
00551 return os;
00552 }
00553 }
00554
00555 namespace Dune
00556 {
00557
00558 template<typename T, class A>
00559 SLList<T,A>::Element::Element(const T& item)
00560 : next_(0), item_(item)
00561 {}
00562
00563 template<typename T, class A>
00564 SLList<T,A>::Element::Element()
00565 : next_(0), item_()
00566 {}
00567
00568 template<typename T, class A>
00569 SLList<T,A>::SLList()
00570 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00571 {
00572 beforeHead_.next_=0;
00573 assert(&beforeHead_==tail_);
00574 assert(tail_->next_==0);
00575 }
00576
00577 template<typename T, class A>
00578 SLList<T,A>::SLList(const SLList<T,A>& other)
00579 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00580 {
00581 copyElements(other);
00582 }
00583
00584 template<typename T, class A>
00585 template<typename T1, class A1>
00586 SLList<T,A>::SLList(const SLList<T1,A1>& other)
00587 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00588 {
00589 copyElements(other);
00590 }
00591
00592 template<typename T, typename A>
00593 void SLList<T,A>::copyElements(const SLList<T,A>& other)
00594 {
00595 assert(tail_==&beforeHead_);
00596 assert(size_==0);
00597 typedef typename SLList<T,A>::const_iterator Iterator;
00598 Iterator iend = other.end();
00599 for(Iterator element=other.begin(); element != iend; ++element)
00600 push_back(*element);
00601
00602 assert(other.size()==size());
00603 }
00604
00605 template<typename T, class A>
00606 SLList<T,A>::~SLList()
00607 {
00608 clear();
00609 }
00610
00611 template<typename T, class A>
00612 SLList<T,A>& SLList<T,A>::operator=(const SLList<T,A>& other)
00613 {
00614 clear();
00615 copyElements(other);
00616 return *this;
00617 }
00618
00619 template<typename T, class A>
00620 inline void SLList<T,A>::push_back(const T& item)
00621 {
00622 assert(size_>0 || tail_==&beforeHead_);
00623 tail_->next_ = allocator_.allocate(1, 0);
00624 assert(size_>0 || tail_==&beforeHead_);
00625 tail_ = tail_->next_;
00626 ::new (static_cast<void*>(&(tail_->item_))) T(item);
00627 tail_->next_=0;
00628 assert(tail_->next_==0);
00629 ++size_;
00630 }
00631
00632 template<typename T, class A>
00633 inline void SLList<T,A>::insertAfter(Element* current, const T& item)
00634 {
00635 assert(current);
00636
00637 #ifndef NDEBUG
00638 bool changeTail = (current == tail_);
00639 #endif
00640
00641
00642 Element* tmp = current->next_;
00643
00644 assert(!changeTail || !tmp);
00645
00646
00647 current->next_ = allocator_.allocate(1, 0);
00648
00649
00650 ::new(static_cast<void*>(&(current->next_->item_))) T(item);
00651
00652
00653 current->next_->next_=tmp;
00654
00655 if(!current->next_->next_){
00656
00657 assert(changeTail);
00658 tail_ = current->next_;
00659 }
00660 ++size_;
00661 assert(!tail_->next_);
00662 }
00663
00664 template<typename T, class A>
00665 inline void SLList<T,A>::push_front(const T& item)
00666 {
00667 if(tail_ == &beforeHead_){
00668
00669 beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
00670 ::new(static_cast<void*>(&beforeHead_.next_->item_)) T(item);
00671 beforeHead_.next_->next_=0;
00672 }else{
00673 Element* added = allocator_.allocate(1, 0);
00674 ::new(static_cast<void*>(&added->item_)) T(item);
00675 added->next_=beforeHead_.next_;
00676 beforeHead_.next_=added;
00677 }
00678 assert(tail_->next_==0);
00679 ++size_;
00680 }
00681
00682
00683 template<typename T, class A>
00684 inline void SLList<T,A>::deleteNext(Element* current)
00685 {
00686 this->template deleteNext<true>(current);
00687 }
00688
00689 template<typename T, class A>
00690 template<bool watchForTail>
00691 inline void SLList<T,A>::deleteNext(Element* current)
00692 {
00693 assert(current->next_);
00694 Element* next = current->next_;
00695
00696 if(watchForTail)
00697 if(next == tail_){
00698
00699 tail_ = current;
00700 }
00701
00702 current->next_ = next->next_;
00703 next->item_.~T();
00704 next->next_ = 0;
00705 allocator_.deallocate(next, 1);
00706 --size_;
00707 assert(!watchForTail || &beforeHead_ != tail_ || size_==0);
00708 }
00709
00710 template<typename T, class A>
00711 inline void SLList<T,A>::pop_front()
00712 {
00713 deleteNext(&beforeHead_);
00714 }
00715
00716 template<typename T, class A>
00717 inline void SLList<T,A>::clear()
00718 {
00719 while(beforeHead_.next_ ){
00720 this->template deleteNext<false>(&beforeHead_);
00721 }
00722
00723 assert(size_==0);
00724
00725 tail_ = &beforeHead_;
00726 }
00727
00728 template<typename T, class A>
00729 inline bool SLList<T,A>::empty() const
00730 {
00731 return (&beforeHead_ == tail_);
00732 }
00733
00734 template<typename T, class A>
00735 inline int SLList<T,A>::size() const
00736 {
00737 return size_;
00738 }
00739
00740 template<typename T, class A>
00741 inline SLListIterator<T,A> SLList<T,A>::begin()
00742 {
00743 return iterator(beforeHead_.next_, this);
00744 }
00745
00746 template<typename T, class A>
00747 inline SLListConstIterator<T,A> SLList<T,A>::begin() const
00748 {
00749 return const_iterator(beforeHead_.next_);
00750 }
00751
00752 template<typename T, class A>
00753 inline SLListIterator<T,A> SLList<T,A>::end()
00754 {
00755 return iterator();
00756 }
00757
00758 template<typename T, class A>
00759 inline SLListModifyIterator<T,A> SLList<T,A>::endModify()
00760 {
00761 return SLListModifyIterator<T,A>(iterator(tail_, this),iterator());
00762 }
00763
00764
00765 template<typename T, class A>
00766 inline SLListModifyIterator<T,A> SLList<T,A>::beginModify()
00767 {
00768 return SLListModifyIterator<T,A>(iterator(&beforeHead_, this),
00769 iterator(beforeHead_.next_, this));
00770 }
00771
00772 template<typename T, class A>
00773 inline SLListConstIterator<T,A> SLList<T,A>::end() const
00774 {
00775 return const_iterator();
00776 }
00777
00779 }
00780 #endif