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 bool operator==(const SLList& sl) const;
00194
00195
00196 bool operator!=(const SLList& sl) const;
00197
00198 private:
00200 struct Element
00201 {
00205 Element* next_;
00209 MemberType item_;
00210
00211 Element(const MemberType& item, Element* next_=0);
00212
00213 Element();
00214
00215 ~Element();
00216 };
00217
00222 void deleteNext(Element* current);
00223
00228 void copyElements(const SLList<T,A>& other);
00229
00237 template<bool watchForTail>
00238 void deleteNext(Element* current);
00244 void insertAfter(Element* current, const T& item);
00245
00247 Element beforeHead_;
00248
00254 Element* tail_;
00255
00257 Allocator allocator_;
00258
00260 int size_;
00261 };
00262
00266 template<typename T, class A>
00267 class SLListIterator : public Dune::ForwardIteratorFacade<SLListIterator<T,A>, T, T&, std::size_t>
00268 {
00269 friend class SLListConstIterator<T,A>;
00270 friend class SLListModifyIterator<T,A>;
00271 friend class SLList<T,A>;
00272
00273 public:
00274 inline SLListIterator(typename SLList<T,A>::Element* item,
00275 SLList<T,A>* sllist)
00276 : current_(item), list_(sllist)
00277 {}
00278
00279 inline SLListIterator()
00280 : current_(0), list_(0)
00281 {}
00282
00283 inline SLListIterator(const SLListModifyIterator<T,A>& other)
00284 : current_(other.iterator_.current_), list_(other.iterator_.list_)
00285 {}
00286
00291 inline T& dereference() const
00292 {
00293 return current_->item_;
00294 }
00295
00301 inline bool equals(const SLListConstIterator<T,A>& other) const
00302 {
00303 return current_==other.current_;
00304 }
00305
00311 inline bool equals(const SLListIterator<T,A>& other) const
00312 {
00313 return current_==other.current_;
00314 }
00315
00321 inline bool equals(const SLListModifyIterator<T,A>& other) const
00322 {
00323 return current_==other.iterator_.current_;
00324 }
00325
00329 inline void increment()
00330 {
00331 current_ = current_->next_;
00332 }
00333
00339 inline void insertAfter(const T& v)const
00340 {
00341 assert(list_ );
00342 list_->insertAfter(current_, v);
00343 }
00344
00350 inline void deleteNext() const
00351 {
00352 assert(list_);
00353 list_->deleteNext(current_);
00354 }
00355
00356 private:
00358 typename SLList<T,A>::Element* current_;
00360 SLList<T,A>* list_;
00361 };
00362
00366 template<class T, class A>
00367 class SLListConstIterator : public Dune::ForwardIteratorFacade<SLListConstIterator<T,A>, const T, const T&, std::size_t>
00368 {
00369 friend class SLListIterator<T,A>;
00370 friend class SLList<T,A>;
00371
00372 public:
00373 inline SLListConstIterator()
00374 : current_(0)
00375 {}
00376
00377 inline SLListConstIterator(typename SLList<T,A>::Element* item)
00378 : current_(item)
00379 {}
00380
00381 inline SLListConstIterator(const SLListIterator<T,A>& other)
00382 : current_(other.current_)
00383 {}
00384
00385 inline SLListConstIterator(const SLListConstIterator<T,A>& other)
00386 : current_(other.current_)
00387 {}
00388
00389 inline SLListConstIterator(const SLListModifyIterator<T,A>& other)
00390 : current_(other.iterator_.current_)
00391 {}
00392
00397 inline const T& dereference() const
00398 {
00399 return current_->item_;
00400 }
00401
00407 inline bool equals(const SLListConstIterator<T,A>& other) const
00408 {
00409 return current_==other.current_;
00410 }
00411
00415 inline void increment()
00416 {
00417 current_ = current_->next_;
00418 }
00419
00420 private:
00422 typename SLList<T,A>::Element* current_;
00423 };
00424
00428 template<typename T, class A>
00429 class SLListModifyIterator : public Dune::ForwardIteratorFacade<SLListModifyIterator<T,A>, T, T&, std::size_t>
00430 {
00431 friend class SLListConstIterator<T,A>;
00432 friend class SLListIterator<T,A>;
00433 public:
00434 inline SLListModifyIterator(SLListIterator<T,A> beforeIterator,
00435 SLListIterator<T,A> _iterator)
00436 : beforeIterator_(beforeIterator), iterator_(_iterator)
00437 {}
00438
00439 inline SLListModifyIterator(const SLListModifyIterator<T,A>& other)
00440 : beforeIterator_(other.beforeIterator_), iterator_(other.iterator_)
00441 {}
00442
00443 inline SLListModifyIterator()
00444 : beforeIterator_(), iterator_()
00445 {}
00446
00451 inline T& dereference() const
00452 {
00453 return *iterator_;
00454 }
00455
00461 inline bool equals(const SLListConstIterator<T,A>& other) const
00462 {
00463 return iterator_== other;
00464 }
00465
00466
00472 inline bool equals(const SLListIterator<T,A>& other) const
00473 {
00474 return iterator_== other;
00475 }
00476
00477
00483 inline bool equals(const SLListModifyIterator<T,A>& other) const
00484 {
00485 return iterator_== other.iterator_;
00486 }
00487
00491 inline void increment()
00492 {
00493 ++iterator_;
00494 ++beforeIterator_;
00495 }
00496
00510 inline void insert(const T& v)
00511 {
00512 beforeIterator_.insertAfter(v);
00513 ++beforeIterator_;
00514 }
00515
00523 inline void remove()
00524 {
00525 ++iterator_;
00526 beforeIterator_.deleteNext();
00527 }
00528
00529 private:
00531 SLListIterator<T,A> beforeIterator_;
00533 SLListIterator<T,A> iterator_;
00534 };
00535 }
00536
00537 namespace std
00538 {
00539
00540 template<typename T, typename A>
00541 ostream& operator<<(ostream& os, const Dune::SLList<T,A> sllist)
00542 {
00543 typedef typename Dune::SLList<T,A>::const_iterator Iterator;
00544 Iterator end = sllist.end();
00545 Iterator current= sllist.begin();
00546
00547 os << "{ ";
00548
00549 if(current!=end){
00550 os<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
00551 ++current;
00552
00553 for(; current != end; ++current)
00554 os<<", "<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
00555 }
00556 os<<"} ";
00557 return os;
00558 }
00559 }
00560
00561 namespace Dune
00562 {
00563
00564 template<typename T, class A>
00565 SLList<T,A>::Element::Element(const T& item, Element* next)
00566 : next_(next), item_(item)
00567 {}
00568
00569 template<typename T, class A>
00570 SLList<T,A>::Element::Element()
00571 : next_(0), item_()
00572 {}
00573
00574 template<typename T, class A>
00575 SLList<T,A>::Element::~Element()
00576 {
00577 next_=0;
00578 }
00579
00580 template<typename T, class A>
00581 SLList<T,A>::SLList()
00582 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00583 {
00584 beforeHead_.next_=0;
00585 assert(&beforeHead_==tail_);
00586 assert(tail_->next_==0);
00587 }
00588
00589 template<typename T, class A>
00590 SLList<T,A>::SLList(const SLList<T,A>& other)
00591 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00592 {
00593 copyElements(other);
00594 }
00595
00596 template<typename T, class A>
00597 template<typename T1, class A1>
00598 SLList<T,A>::SLList(const SLList<T1,A1>& other)
00599 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00600 {
00601 copyElements(other);
00602 }
00603
00604 template<typename T, typename A>
00605 void SLList<T,A>::copyElements(const SLList<T,A>& other)
00606 {
00607 assert(tail_==&beforeHead_);
00608 assert(size_==0);
00609 typedef typename SLList<T,A>::const_iterator Iterator;
00610 Iterator iend = other.end();
00611 for(Iterator element=other.begin(); element != iend; ++element)
00612 push_back(*element);
00613
00614 assert(other.size()==size());
00615 }
00616
00617 template<typename T, class A>
00618 SLList<T,A>::~SLList()
00619 {
00620 clear();
00621 }
00622
00623 template<typename T, class A>
00624 bool SLList<T,A>::operator==(const SLList& other) const
00625 {
00626 if(size!=other.size())
00627 return false;
00628 for(const_iterator iter=begin(), oiter=other.begin();
00629 iter != end(); ++iter, ++oiter)
00630 if(*iter!=*oiter)
00631 return false;
00632 return true;
00633 }
00634
00635 template<typename T, class A>
00636 bool SLList<T,A>::operator!=(const SLList& other) const
00637 {
00638 if(size()==other.size()){
00639 for(const_iterator iter=begin(), oiter=other.begin();
00640 iter != end(); ++iter, ++oiter)
00641 if(*iter!=*oiter)
00642 return true;
00643 return false;
00644 }else
00645 return true;
00646 }
00647 template<typename T, class A>
00648 SLList<T,A>& SLList<T,A>::operator=(const SLList<T,A>& other)
00649 {
00650 clear();
00651 copyElements(other);
00652 return *this;
00653 }
00654
00655 template<typename T, class A>
00656 inline void SLList<T,A>::push_back(const T& item)
00657 {
00658 assert(size_>0 || tail_==&beforeHead_);
00659 tail_->next_ = allocator_.allocate(1, 0);
00660 assert(size_>0 || tail_==&beforeHead_);
00661 tail_ = tail_->next_;
00662 ::new (static_cast<void*>(&(tail_->item_))) T(item);
00663 tail_->next_=0;
00664 assert(tail_->next_==0);
00665 ++size_;
00666 }
00667
00668 template<typename T, class A>
00669 inline void SLList<T,A>::insertAfter(Element* current, const T& item)
00670 {
00671 assert(current);
00672
00673 #ifndef NDEBUG
00674 bool changeTail = (current == tail_);
00675 #endif
00676
00677
00678 Element* tmp = current->next_;
00679
00680 assert(!changeTail || !tmp);
00681
00682
00683 current->next_ = allocator_.allocate(1, 0);
00684
00685
00686 allocator_.construct(current->next_, Element(item,tmp));
00687
00688
00689
00690 if(!current->next_->next_){
00691
00692 assert(changeTail);
00693 tail_ = current->next_;
00694 }
00695 ++size_;
00696 assert(!tail_->next_);
00697 }
00698
00699 template<typename T, class A>
00700 inline void SLList<T,A>::push_front(const T& item)
00701 {
00702 if(tail_ == &beforeHead_){
00703
00704 beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
00705 ::new(static_cast<void*>(&beforeHead_.next_->item_)) T(item);
00706 beforeHead_.next_->next_=0;
00707 }else{
00708 Element* added = allocator_.allocate(1, 0);
00709 ::new(static_cast<void*>(&added->item_)) T(item);
00710 added->next_=beforeHead_.next_;
00711 beforeHead_.next_=added;
00712 }
00713 assert(tail_->next_==0);
00714 ++size_;
00715 }
00716
00717
00718 template<typename T, class A>
00719 inline void SLList<T,A>::deleteNext(Element* current)
00720 {
00721 this->template deleteNext<true>(current);
00722 }
00723
00724 template<typename T, class A>
00725 template<bool watchForTail>
00726 inline void SLList<T,A>::deleteNext(Element* current)
00727 {
00728 assert(current->next_);
00729 Element* next = current->next_;
00730
00731 if(watchForTail)
00732 if(next == tail_){
00733
00734 tail_ = current;
00735 }
00736
00737 current->next_ = next->next_;
00738 allocator_.destroy(next);
00739 allocator_.deallocate(next, 1);
00740 --size_;
00741 assert(!watchForTail || &beforeHead_ != tail_ || size_==0);
00742 }
00743
00744 template<typename T, class A>
00745 inline void SLList<T,A>::pop_front()
00746 {
00747 deleteNext(&beforeHead_);
00748 }
00749
00750 template<typename T, class A>
00751 inline void SLList<T,A>::clear()
00752 {
00753 while(beforeHead_.next_ ){
00754 this->template deleteNext<false>(&beforeHead_);
00755 }
00756
00757 assert(size_==0);
00758
00759 tail_ = &beforeHead_;
00760 }
00761
00762 template<typename T, class A>
00763 inline bool SLList<T,A>::empty() const
00764 {
00765 return (&beforeHead_ == tail_);
00766 }
00767
00768 template<typename T, class A>
00769 inline int SLList<T,A>::size() const
00770 {
00771 return size_;
00772 }
00773
00774 template<typename T, class A>
00775 inline SLListIterator<T,A> SLList<T,A>::begin()
00776 {
00777 return iterator(beforeHead_.next_, this);
00778 }
00779
00780 template<typename T, class A>
00781 inline SLListConstIterator<T,A> SLList<T,A>::begin() const
00782 {
00783 return const_iterator(beforeHead_.next_);
00784 }
00785
00786 template<typename T, class A>
00787 inline SLListIterator<T,A> SLList<T,A>::end()
00788 {
00789 return iterator();
00790 }
00791
00792 template<typename T, class A>
00793 inline SLListModifyIterator<T,A> SLList<T,A>::endModify()
00794 {
00795 return SLListModifyIterator<T,A>(iterator(tail_, this),iterator());
00796 }
00797
00798
00799 template<typename T, class A>
00800 inline SLListModifyIterator<T,A> SLList<T,A>::beginModify()
00801 {
00802 return SLListModifyIterator<T,A>(iterator(&beforeHead_, this),
00803 iterator(beforeHead_.next_, this));
00804 }
00805
00806 template<typename T, class A>
00807 inline SLListConstIterator<T,A> SLList<T,A>::end() const
00808 {
00809 return const_iterator();
00810 }
00811
00813 }
00814 #endif