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
00106 inline void push_back(const MemberType& item);
00107
00112 inline void push_front(const MemberType& item);
00113
00117 inline void pop_front();
00118
00120 inline void clear();
00121
00129 inline iterator begin();
00130
00138 inline const_iterator begin() const;
00139
00147 inline ModifyIterator beginModify();
00148
00156 inline ModifyIterator endModify();
00157
00164 inline iterator end();
00165
00172 inline const_iterator end() const;
00173
00179 inline bool empty() const;
00180
00185 inline int size() const;
00186
00187 private:
00189 struct Element
00190 {
00194 Element* next_;
00198 MemberType item_;
00199
00200 Element(const MemberType& item);
00201
00202 Element();
00203
00204 };
00205
00206 template<typename T1, typename A1>
00207 SLList<T,A>& operator=(SLList<T1,A1>& other)
00208 {
00209 return *this;
00210 }
00211
00212 SLList<T,A>& operator=(SLList<T,A>& other)
00213 {
00214 return *this;
00215 }
00216
00221 void deleteNext(Element* current);
00222
00227 template<class T1, class A1>
00228 void copyElements(const SLList<T1,A1>& 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)
00566 : next_(0), 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>::SLList()
00576 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00577 {
00578 beforeHead_.next_=0;
00579 assert(&beforeHead_==tail_);
00580 assert(tail_->next_==0);
00581 }
00582
00583 template<typename T, class A>
00584 SLList<T,A>::SLList(const SLList<T,A>& other)
00585 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00586 {
00587 copyElements(other);
00588 }
00589
00590 template<typename T, class A>
00591 template<typename T1, class A1>
00592 SLList<T,A>::SLList(const SLList<T1,A1>& other)
00593 : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
00594 {
00595 copyElements(other);
00596 }
00597
00598 template<typename T, typename A>
00599 template<typename T1, class A1>
00600 void SLList<T,A>::copyElements(const SLList<T1,A1>& other)
00601 {
00602 assert(tail_==&beforeHead_);
00603 assert(size_==0);
00604 typedef typename SLList<T,A>::const_iterator Iterator;
00605 Iterator iend = other.end();
00606 for(Iterator element=other.begin(); element != iend; ++element)
00607 push_back(*element);
00608
00609 assert(other.size()==size());
00610 }
00611
00612 template<typename T, class A>
00613 SLList<T,A>::~SLList()
00614 {
00615 clear();
00616 }
00617
00618 template<typename T, class A>
00619 inline void SLList<T,A>::push_back(const T& item)
00620 {
00621 assert(size_>0 || tail_==&beforeHead_);
00622 tail_->next_ = allocator_.allocate(1, 0);
00623 assert(size_>0 || tail_==&beforeHead_);
00624 tail_ = tail_->next_;
00625 ::new (static_cast<void*>(&(tail_->item_))) T(item);
00626 tail_->next_=0;
00627 assert(tail_->next_==0);
00628 ++size_;
00629 }
00630
00631 template<typename T, class A>
00632 inline void SLList<T,A>::insertAfter(Element* current, const T& item)
00633 {
00634 assert(current);
00635
00636 #ifndef NDEBUG
00637 bool changeTail = (current == tail_);
00638 #endif
00639
00640
00641 Element* tmp = current->next_;
00642
00643 assert(!changeTail || !tmp);
00644
00645
00646 current->next_ = allocator_.allocate(1, 0);
00647
00648
00649 ::new(static_cast<void*>(&(current->next_->item_))) T(item);
00650
00651
00652 current->next_->next_=tmp;
00653
00654 if(!current->next_->next_){
00655
00656 assert(changeTail);
00657 tail_ = current->next_;
00658 }
00659 ++size_;
00660 assert(!tail_->next_);
00661 }
00662
00663 template<typename T, class A>
00664 inline void SLList<T,A>::push_front(const T& item)
00665 {
00666 if(tail_ == &beforeHead_){
00667
00668 beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
00669 ::new(static_cast<void*>(&beforeHead_.next_->item_)) T(item);
00670 beforeHead_.next_->next_=0;
00671 }else{
00672 Element* added = allocator_.allocate(1, 0);
00673 ::new(static_cast<void*>(&added->item_)) T(item);
00674 added->next_=beforeHead_.next_;
00675 beforeHead_.next_=added;
00676 }
00677 assert(tail_->next_==0);
00678 ++size_;
00679 }
00680
00681
00682 template<typename T, class A>
00683 inline void SLList<T,A>::deleteNext(Element* current)
00684 {
00685 this->template deleteNext<true>(current);
00686 }
00687
00688 template<typename T, class A>
00689 template<bool watchForTail>
00690 inline void SLList<T,A>::deleteNext(Element* current)
00691 {
00692 assert(current->next_);
00693 Element* next = current->next_;
00694
00695 if(watchForTail)
00696 if(next == tail_){
00697
00698 tail_ = current;
00699 }
00700
00701 current->next_ = next->next_;
00702 next->item_.~T();
00703 next->next_ = 0;
00704 allocator_.deallocate(next, 1);
00705 --size_;
00706 assert(!watchForTail || &beforeHead_ != tail_ || size_==0);
00707 }
00708
00709 template<typename T, class A>
00710 inline void SLList<T,A>::pop_front()
00711 {
00712 deleteNext(&beforeHead_);
00713 }
00714
00715 template<typename T, class A>
00716 inline void SLList<T,A>::clear()
00717 {
00718 while(beforeHead_.next_ ){
00719 this->template deleteNext<false>(&beforeHead_);
00720 }
00721
00722 #ifdef NDEBUG
00723 size_=0;
00724 #endif
00725 assert(size_==0);
00726
00727 tail_ = &beforeHead_;
00728 }
00729
00730 template<typename T, class A>
00731 inline bool SLList<T,A>::empty() const
00732 {
00733 return (&beforeHead_ == tail_);
00734 }
00735
00736 template<typename T, class A>
00737 inline int SLList<T,A>::size() const
00738 {
00739 return size_;
00740 }
00741
00742 template<typename T, class A>
00743 inline SLListIterator<T,A> SLList<T,A>::begin()
00744 {
00745 return iterator(beforeHead_.next_, this);
00746 }
00747
00748 template<typename T, class A>
00749 inline SLListConstIterator<T,A> SLList<T,A>::begin() const
00750 {
00751 return const_iterator(beforeHead_.next_);
00752 }
00753
00754 template<typename T, class A>
00755 inline SLListIterator<T,A> SLList<T,A>::end()
00756 {
00757 return iterator();
00758 }
00759
00760 template<typename T, class A>
00761 inline SLListModifyIterator<T,A> SLList<T,A>::endModify()
00762 {
00763 return SLListModifyIterator<T,A>(iterator(tail_, this),iterator());
00764 }
00765
00766
00767 template<typename T, class A>
00768 inline SLListModifyIterator<T,A> SLList<T,A>::beginModify()
00769 {
00770 return SLListModifyIterator<T,A>(iterator(&beforeHead_, this),
00771 iterator(beforeHead_.next_, this));
00772 }
00773
00774 template<typename T, class A>
00775 inline SLListConstIterator<T,A> SLList<T,A>::end() const
00776 {
00777 return const_iterator();
00778 }
00779
00781 }
00782 #endif