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