dune-common 2.1.1
|
00001 // $Id: sllist.hh 6538 2011-12-06 17:25:52Z sander $ 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 }// namespace Dune 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 }//namespace std 00560 00561 namespace Dune 00562 { 00563 00564 template<typename T, class A> 00565 SLList<T,A>::Element::Element(const MemberType& 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 MemberType& 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 // Save old next element 00678 Element* tmp = current->next_; 00679 00680 assert(!changeTail || !tmp); 00681 00682 // Allocate space 00683 current->next_ = allocator_.allocate(1, 0); 00684 00685 // Use copy constructor to initialize memory 00686 allocator_.construct(current->next_, Element(item,tmp)); 00687 00688 //::new(static_cast<void*>(&(current->next_->item_))) T(item); 00689 00690 if(!current->next_->next_){ 00691 // Update tail 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 MemberType& item) 00701 { 00702 if(tail_ == &beforeHead_){ 00703 // list was empty 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 // deleting last element changes tail! 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 // update the tail! 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