Dune Core Modules (2.6.0)

sllist.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_SLLIST_HH
4 #define DUNE_SLLIST_HH
5 
6 #include <memory>
7 #include <cassert>
8 #include "iteratorfacades.hh"
9 #include <ostream>
10 
11 namespace Dune
12 {
24  template<typename T, class A>
25  class SLListIterator;
26 
27  template<typename T, class A>
28  class SLListConstIterator;
29 
30  template<typename T, class A>
31  class SLListModifyIterator;
32 
40  template<typename T, class A=std::allocator<T> >
41  class SLList
42  {
43  struct Element;
44  friend class SLListIterator<T,A>;
45  friend class SLListConstIterator<T,A>;
46 
47  public:
48 
52  typedef typename A::size_type size_type;
53 
57  typedef T MemberType;
58 
62  typedef typename A::template rebind<Element>::other Allocator;
63 
68 
73 
77  SLList();
78 
82  template<typename T1, typename A1>
83  SLList(const SLList<T1,A1>& other);
84 
88  SLList(const SLList<T,A>& other);
89 
96 
102 
107 
108 
113  inline void push_back(const MemberType& item);
114 
119  inline void push_front(const MemberType& item);
120 
124  inline void pop_front();
125 
127  inline void clear();
128 
136  inline iterator begin();
137 
145  inline const_iterator begin() const;
146 
155 
164 
171  inline iterator end();
172 
179  inline const_iterator end() const;
180 
186  inline bool empty() const;
187 
192  inline int size() const;
193 
194  bool operator==(const SLList& sl) const;
195 
196 
197  bool operator!=(const SLList& sl) const;
198 
199  private:
201  struct Element
202  {
206  Element* next_;
211 
212  Element(const MemberType& item, Element* next_=0);
213 
214  Element();
215 
216  ~Element();
217  };
218 
223  void deleteNext(Element* current);
224 
229  void copyElements(const SLList<T,A>& other);
230 
238  template<bool watchForTail>
239  void deleteNext(Element* current);
245  void insertAfter(Element* current, const T& item);
246 
248  Element beforeHead_;
249 
255  Element* tail_;
256 
258  Allocator allocator_;
259 
261  int size_;
262  };
263 
267  template<typename T, class A>
268  class SLListIterator : public Dune::ForwardIteratorFacade<SLListIterator<T,A>, T, T&, std::size_t>
269  {
270  friend class SLListConstIterator<T,A>;
271  friend class SLListModifyIterator<T,A>;
272  friend class SLList<T,A>;
273 
274  public:
275  inline SLListIterator(typename SLList<T,A>::Element* item,
276  SLList<T,A>* sllist)
277  : current_(item), list_(sllist)
278  {}
279 
280  inline SLListIterator()
281  : current_(0), list_(0)
282  {}
283 
284  inline SLListIterator(const SLListModifyIterator<T,A>& other)
285  : current_(other.iterator_.current_), list_(other.iterator_.list_)
286  {}
287 
292  inline T& dereference() const
293  {
294  return current_->item_;
295  }
296 
302  inline bool equals(const SLListConstIterator<T,A>& other) const
303  {
304  return current_==other.current_;
305  }
306 
312  inline bool equals(const SLListIterator<T,A>& other) const
313  {
314  return current_==other.current_;
315  }
316 
322  inline bool equals(const SLListModifyIterator<T,A>& other) const
323  {
324  return current_==other.iterator_.current_;
325  }
326 
330  inline void increment()
331  {
332  current_ = current_->next_;
333  }
334 
340  inline void insertAfter(const T& v) const
341  {
342  assert(list_ );
343  list_->insertAfter(current_, v);
344  }
345 
351  inline void deleteNext() const
352  {
353  assert(list_);
354  list_->deleteNext(current_);
355  }
356 
357  private:
359  typename SLList<T,A>::Element* current_;
361  SLList<T,A>* list_;
362  };
363 
367  template<class T, class A>
368  class SLListConstIterator : public Dune::ForwardIteratorFacade<SLListConstIterator<T,A>, const T, const T&, std::size_t>
369  {
370  friend class SLListIterator<T,A>;
371  friend class SLList<T,A>;
372 
373  public:
374  inline SLListConstIterator()
375  : current_(0)
376  {}
377 
378  inline SLListConstIterator(typename SLList<T,A>::Element* item)
379  : current_(item)
380  {}
381 
382  inline SLListConstIterator(const SLListIterator<T,A>& other)
383  : current_(other.current_)
384  {}
385 
386  inline SLListConstIterator(const SLListConstIterator<T,A>& other)
387  : current_(other.current_)
388  {}
389 
391  : current_(other.iterator_.current_)
392  {}
393 
398  inline const T& dereference() const
399  {
400  return current_->item_;
401  }
402 
408  inline bool equals(const SLListConstIterator<T,A>& other) const
409  {
410  return current_==other.current_;
411  }
412 
416  inline void increment()
417  {
418  current_ = current_->next_;
419  }
420 
421  private:
423  typename SLList<T,A>::Element* current_;
424  };
425 
429  template<typename T, class A>
430  class SLListModifyIterator : public Dune::ForwardIteratorFacade<SLListModifyIterator<T,A>, T, T&, std::size_t>
431  {
432  friend class SLListConstIterator<T,A>;
433  friend class SLListIterator<T,A>;
434  public:
435  inline SLListModifyIterator(SLListIterator<T,A> beforeIterator,
436  SLListIterator<T,A> _iterator)
437  : beforeIterator_(beforeIterator), iterator_(_iterator)
438  {}
439 
441  : beforeIterator_(other.beforeIterator_), iterator_(other.iterator_)
442  {}
443 
444  inline SLListModifyIterator()
445  : beforeIterator_(), iterator_()
446  {}
447 
452  inline T& dereference() const
453  {
454  return *iterator_;
455  }
456 
462  inline bool equals(const SLListConstIterator<T,A>& other) const
463  {
464  return iterator_== other;
465  }
466 
467 
473  inline bool equals(const SLListIterator<T,A>& other) const
474  {
475  return iterator_== other;
476  }
477 
478 
484  inline bool equals(const SLListModifyIterator<T,A>& other) const
485  {
486  return iterator_== other.iterator_;
487  }
488 
492  inline void increment()
493  {
494  ++iterator_;
495  ++beforeIterator_;
496  }
497 
511  inline void insert(const T& v)
512  {
513  beforeIterator_.insertAfter(v);
514  ++beforeIterator_;
515  }
516 
524  inline void remove()
525  {
526  ++iterator_;
527  beforeIterator_.deleteNext();
528  }
529 
530  private:
532  SLListIterator<T,A> beforeIterator_;
534  SLListIterator<T,A> iterator_;
535  };
536 } // namespace Dune
537 
538 namespace std
539 {
540 
541  template<typename T, typename A>
542  ostream& operator<<(ostream& os, const Dune::SLList<T,A> sllist)
543  {
544  typedef typename Dune::SLList<T,A>::const_iterator Iterator;
545  Iterator end = sllist.end();
546  Iterator current= sllist.begin();
547 
548  os << "{ ";
549 
550  if(current!=end) {
551  os<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
552  ++current;
553 
554  for(; current != end; ++current)
555  os<<", "<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
556  }
557  os<<"} ";
558  return os;
559  }
560 } //namespace std
561 
562 namespace Dune
563 {
564 
565  template<typename T, class A>
566  SLList<T,A>::Element::Element(const MemberType& item, Element* next)
567  : next_(next), item_(item)
568  {}
569 
570  template<typename T, class A>
571  SLList<T,A>::Element::Element()
572  : next_(0), item_()
573  {}
574 
575  template<typename T, class A>
576  SLList<T,A>::Element::~Element()
577  {
578  next_=0;
579  }
580 
581  template<typename T, class A>
583  : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
584  {
585  beforeHead_.next_=0;
586  assert(&beforeHead_==tail_);
587  assert(tail_->next_==0);
588  }
589 
590  template<typename T, class A>
592  : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
593  {
594  copyElements(other);
595  }
596 
597  template<typename T, class A>
598  template<typename T1, class A1>
600  : beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
601  {
602  copyElements(other);
603  }
604 
605  template<typename T, typename A>
606  void SLList<T,A>::copyElements(const SLList<T,A>& other)
607  {
608  assert(tail_==&beforeHead_);
609  assert(size_==0);
610  typedef typename SLList<T,A>::const_iterator Iterator;
611  Iterator iend = other.end();
612  for(Iterator element=other.begin(); element != iend; ++element)
613  push_back(*element);
614 
615  assert(other.size()==size());
616  }
617 
618  template<typename T, class A>
620  {
621  clear();
622  }
623 
624  template<typename T, class A>
625  bool SLList<T,A>::operator==(const SLList& other) const
626  {
627  if(size()!=other.size())
628  return false;
629  for(const_iterator iter=begin(), oiter=other.begin();
630  iter != end(); ++iter, ++oiter)
631  if(*iter!=*oiter)
632  return false;
633  return true;
634  }
635 
636  template<typename T, class A>
637  bool SLList<T,A>::operator!=(const SLList& other) const
638  {
639  if(size()==other.size()) {
640  for(const_iterator iter=begin(), oiter=other.begin();
641  iter != end(); ++iter, ++oiter)
642  if(*iter!=*oiter)
643  return true;
644  return false;
645  }else
646  return true;
647  }
648  template<typename T, class A>
650  {
651  clear();
652  copyElements(other);
653  return *this;
654  }
655 
656  template<typename T, class A>
657  inline void SLList<T,A>::push_back(const MemberType& item)
658  {
659  assert(size_>0 || tail_==&beforeHead_);
660  tail_->next_ = allocator_.allocate(1, 0);
661  assert(size_>0 || tail_==&beforeHead_);
662  tail_ = tail_->next_;
663  ::new (static_cast<void*>(&(tail_->item_)))T(item);
664  tail_->next_=0;
665  assert(tail_->next_==0);
666  ++size_;
667  }
668 
669  template<typename T, class A>
670  inline void SLList<T,A>::insertAfter(Element* current, const T& item)
671  {
672  assert(current);
673 
674 #ifndef NDEBUG
675  bool changeTail = (current == tail_);
676 #endif
677 
678  // Save old next element
679  Element* tmp = current->next_;
680 
681  assert(!changeTail || !tmp);
682 
683  // Allocate space
684  current->next_ = allocator_.allocate(1, 0);
685 
686  // Use copy constructor to initialize memory
687  allocator_.construct(current->next_, Element(item,tmp));
688 
689  //::new(static_cast<void*>(&(current->next_->item_))) T(item);
690 
691  if(!current->next_->next_) {
692  // Update tail
693  assert(changeTail);
694  tail_ = current->next_;
695  }
696  ++size_;
697  assert(!tail_->next_);
698  }
699 
700  template<typename T, class A>
701  inline void SLList<T,A>::push_front(const MemberType& item)
702  {
703  if(tail_ == &beforeHead_) {
704  // list was empty
705  beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
706  ::new(static_cast<void*>(&beforeHead_.next_->item_))T(item);
707  beforeHead_.next_->next_=0;
708  }else{
709  Element* added = allocator_.allocate(1, 0);
710  ::new(static_cast<void*>(&added->item_))T(item);
711  added->next_=beforeHead_.next_;
712  beforeHead_.next_=added;
713  }
714  assert(tail_->next_==0);
715  ++size_;
716  }
717 
718 
719  template<typename T, class A>
720  inline void SLList<T,A>::deleteNext(Element* current)
721  {
722  this->template deleteNext<true>(current);
723  }
724 
725  template<typename T, class A>
726  template<bool watchForTail>
727  inline void SLList<T,A>::deleteNext(Element* current)
728  {
729  assert(current->next_);
730  Element* next = current->next_;
731 
732  if(watchForTail)
733  if(next == tail_) {
734  // deleting last element changes tail!
735  tail_ = current;
736  }
737 
738  current->next_ = next->next_;
739  allocator_.destroy(next);
740  allocator_.deallocate(next, 1);
741  --size_;
742  assert(!watchForTail || &beforeHead_ != tail_ || size_==0);
743  }
744 
745  template<typename T, class A>
747  {
748  deleteNext(&beforeHead_);
749  }
750 
751  template<typename T, class A>
752  inline void SLList<T,A>::clear()
753  {
754  while(beforeHead_.next_ ) {
755  this->template deleteNext<false>(&beforeHead_);
756  }
757 
758  assert(size_==0);
759  // update the tail!
760  tail_ = &beforeHead_;
761  }
762 
763  template<typename T, class A>
764  inline bool SLList<T,A>::empty() const
765  {
766  return (&beforeHead_ == tail_);
767  }
768 
769  template<typename T, class A>
770  inline int SLList<T,A>::size() const
771  {
772  return size_;
773  }
774 
775  template<typename T, class A>
777  {
778  return iterator(beforeHead_.next_, this);
779  }
780 
781  template<typename T, class A>
783  {
784  return const_iterator(beforeHead_.next_);
785  }
786 
787  template<typename T, class A>
789  {
790  return iterator();
791  }
792 
793  template<typename T, class A>
795  {
796  return SLListModifyIterator<T,A>(iterator(tail_, this),iterator());
797  }
798 
799 
800  template<typename T, class A>
802  {
803  return SLListModifyIterator<T,A>(iterator(&beforeHead_, this),
804  iterator(beforeHead_.next_, this));
805  }
806 
807  template<typename T, class A>
809  {
810  return const_iterator();
811  }
812 
814 }
815 #endif
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:144
A constant iterator for the SLList.
Definition: sllist.hh:369
A mutable iterator for the SLList.
Definition: sllist.hh:269
A mutable iterator for the SLList.
Definition: sllist.hh:431
A single linked list.
Definition: sllist.hh:42
void push_front(const MemberType &item)
Add a new entry to the beginning of the list.
Definition: sllist.hh:701
bool equals(const SLListConstIterator< T, A > &other) const
Equality test for the iterator facade.
Definition: sllist.hh:408
void push_back(const MemberType &item)
Add a new entry to the end of the list.
Definition: sllist.hh:657
T & dereference() const
Dereferencing function for the iterator facade.
Definition: sllist.hh:452
ModifyIterator endModify()
Get an iterator capable of deleting and inserting elements.
Definition: sllist.hh:794
const T & dereference() const
Dereferencing function for the facade.
Definition: sllist.hh:398
MemberType item_
The element we hold.
Definition: sllist.hh:210
void insertAfter(const T &v) const
Insert an element in the underlying list after the current position.
Definition: sllist.hh:340
A::template rebind< Element >::other Allocator
The allocator to use.
Definition: sllist.hh:62
SLListIterator< T, A > iterator
The mutable iterator of the list.
Definition: sllist.hh:67
void deleteNext() const
Delete the entry after the current position.
Definition: sllist.hh:351
SLList(const SLList< T, A > &other)
Copy constructor.
Definition: sllist.hh:591
bool equals(const SLListModifyIterator< T, A > &other) const
Equality test for the iterator facade.
Definition: sllist.hh:322
int size() const
Get the number of elements the list contains.
Definition: sllist.hh:770
const_iterator begin() const
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:782
iterator end()
Get an iterator pointing to the end of the list.
Definition: sllist.hh:788
void clear()
Remove all elements from the list.
Definition: sllist.hh:752
T & dereference() const
Dereferencing function for the iterator facade.
Definition: sllist.hh:292
SLList(const SLList< T1, A1 > &other)
Copy constructor with type conversion.
Definition: sllist.hh:599
T MemberType
The type we store.
Definition: sllist.hh:57
bool equals(const SLListModifyIterator< T, A > &other) const
Test whether another iterator is equal.
Definition: sllist.hh:484
ModifyIterator beginModify()
Get an iterator capable of deleting and inserting elements.
Definition: sllist.hh:801
SLList< T, A > & operator=(const SLList< T, A > &other)
Assignment operator.
Definition: sllist.hh:649
SLListConstIterator< T, A > const_iterator
The constant iterator of the list.
Definition: sllist.hh:72
bool empty() const
Check whether the list is empty.
Definition: sllist.hh:764
bool equals(const SLListConstIterator< T, A > &other) const
Equality test for the iterator facade.
Definition: sllist.hh:302
bool equals(const SLListConstIterator< T, A > &other) const
Test whether another iterator is equal.
Definition: sllist.hh:462
SLListModifyIterator< T, A > ModifyIterator
The type of the iterator capable of deletion and insertion.
Definition: sllist.hh:101
const_iterator end() const
Get an iterator pointing to the end of the list.
Definition: sllist.hh:808
SLList()
Constructor.
Definition: sllist.hh:582
void insert(const T &v)
Insert an element at the current position.
Definition: sllist.hh:511
void pop_front()
Remove the first item in the list.
Definition: sllist.hh:746
void increment()
Increment function for the iterator facade.
Definition: sllist.hh:330
A::size_type size_type
The size type.
Definition: sllist.hh:52
void remove()
Delete the entry at the current position.
Definition: sllist.hh:524
Element * next_
The next element in the list.
Definition: sllist.hh:206
void increment()
Increment function for the iterator facade.
Definition: sllist.hh:492
void increment()
Increment function for the iterator facade.
Definition: sllist.hh:416
~SLList()
Destructor.
Definition: sllist.hh:619
bool equals(const SLListIterator< T, A > &other) const
Test whether another iterator is equal.
Definition: sllist.hh:473
iterator begin()
Get an iterator pointing to the first element in the list.
Definition: sllist.hh:776
bool equals(const SLListIterator< T, A > &other) const
Equality test for the iterator facade.
Definition: sllist.hh:312
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:255
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:233
This file implements iterator facade classes for writing stl conformant iterators.
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 25, 22:37, 2024)