From 5289d56e93cf86c9a4d3b7535c7b3e3fc7376525 Mon Sep 17 00:00:00 2001 From: Markus Blatt <mblatt@dune-project.org> Date: Sat, 6 Nov 2004 14:13:59 +0000 Subject: [PATCH] adapted iterators to iterator facades. [[Imported from SVN: r1032]] --- common/arraylist.hh | 446 ++++++++++++++++++++--------------- common/test/.gitignore | 3 +- common/test/arraylisttest.cc | 9 +- 3 files changed, 259 insertions(+), 199 deletions(-) diff --git a/common/arraylist.hh b/common/arraylist.hh index 7d8ef93aa..842362aa2 100644 --- a/common/arraylist.hh +++ b/common/arraylist.hh @@ -7,27 +7,16 @@ #include <vector> #include <dune/common/fixedarray.hh> -namespace Dune { +#include <dune/common/iteratorfacades.hh> +namespace Dune +{ // forward declaration template<class T, int N> class ArrayListIterator; -} -namespace std { - /** - * @brief Iterator traits for the Dune::ArrayListIterator. - */ - template<class T, int N> - struct iterator_traits<Dune::ArrayListIterator<T,N> >{ - typedef T value_type; - typedef int difference_type; - typedef random_access_iterator_tag iterator_category; - typedef T* pointer; - typedef T& reference; - }; -} -namespace Dune { + template<class T, int N> + class ConstArrayListIterator; /** * @file @@ -37,7 +26,8 @@ namespace Dune { * by the stl for sorting and other algorithms. * @author Markus Blatt */ - /** @addtogroup Common + /** + * @addtogroup Common * * @{ */ @@ -51,12 +41,14 @@ namespace Dune { * we provide the same interface as the stl random access containers. */ template<class T, int N=100> - class ArrayList { + class ArrayList + { /** * @brief The iterator needs access to the private variables. */ friend class ArrayListIterator<T,N>; + friend class ConstArrayListIterator<T,N>; public: /** @@ -64,9 +56,10 @@ namespace Dune { * * Has to be assignable and has to have an empty constructor. */ - typedef T memberType; + typedef T MemberType; - enum { + enum + { /** * @brief The number of elements in one chunk of the list. * This has to be at least one. The default is 100. @@ -77,12 +70,12 @@ namespace Dune { /** * @brief A random access iterator. */ - typedef ArrayListIterator<memberType,N> iterator; + typedef ArrayListIterator<MemberType,N> iterator; /** * @brief A constant random access iterator. */ - typedef const ArrayListIterator<memberType,N> const_iterator; + typedef ConstArrayListIterator<MemberType,N> const_iterator; /** @@ -114,8 +107,21 @@ namespace Dune { * @brief Append an entry to the list. * @param entry The new entry. */ - void push_back(const T& entry); + inline void push_back(const T& entry); + /** + * @brief Get the element at specific position. + * @param i The index of the position. + * @return The element at that position. + */ + inline T& operator[](int i); + + /** + * @brief Get the element at specific position. + * @param i The index of the position. + * @return The element at that position. + */ + inline const T& operator[](int i) const; /** * @brief Constructs an Array list with one chunk. */ @@ -127,7 +133,7 @@ namespace Dune { ~ArrayList(); protected: /** @brief the data chunks of our list. */ - std::vector<FixedArray<memberType,chunkSize_>* > chunks_; + std::vector<FixedArray<MemberType,chunkSize_>* > chunks_; /** @brief The current data capacity. */ int capacity_; /** @brief The current number of elements in our data structure. */ @@ -136,62 +142,122 @@ namespace Dune { int start_; }; + + /** + * @brief A random access iterator for the Dune::ArrayList class. + */ template<class T, int N> - int operator-(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N>,T> + { + friend class ArrayList<T,N>; + friend class ConstArrayListIterator<T,N>; + public: + /** + * @brief The member type. + */ + typedef T MemberType; - template<class T, int N> - int operator+(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); - template<class T, int N> - ArrayListIterator<T,N> operator+(int i, const ArrayListIterator<T,N>& a); + enum + { + /** + * @brief The number of elements in one chunk of the list. + * + * This has to be at least one. The default is 100. + */ + chunkSize_ = (N > 0) ? N : 1 + }; - template<class T, int N> - ArrayListIterator<T,N> operator-(int i, const ArrayListIterator<T,N>& a); - template<class T, int N> - ArrayListIterator<T,N> operator+(const ArrayListIterator<T,N>& a, int i); + /** + * @brief Comares two iterators. + * @return True if the iterators are for the same list and + * at the position. + */ + inline bool equals(const ArrayListIterator<MemberType,N>& other) const; - template<class T, int N> - ArrayListIterator<T,N> operator-(const ArrayListIterator<T,N>& a, int i); + /** + * @brief Comares two iterators. + * @return True if the iterators are for the same list and + * at the position. + */ + inline bool equals(const ConstArrayListIterator<MemberType,N>& other) const; - template<class T, int N> - bool operator<(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + /** + * @brief Increment the iterator. + */ + inline void increment(); - template<class T, int N> - bool operator<=(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + /** + * @brief decrement the iterator. + */ + inline void decrement(); - template<class T, int N> - bool operator>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + /** + * @brief Get the value of the list at an arbitrary position. + * @return The value at that postion. + */ + inline MemberType& elementAt(int i) const; - template<class T, int N> - bool operator>=(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + /** + * @brief Access the element at the current position. + * @return The element at the current position. + */ + inline MemberType& dereference() const; + + /** + * @brief Removes all indices before the current position. + */ + inline void removeUpToHere(); + + inline void advance(int n); + + inline int distanceTo(const ArrayListIterator<MemberType,N>& other) const; + + inline const ArrayListIterator<MemberType,N>& operator=(const ArrayListIterator<MemberType,N>& other); + + inline ArrayListIterator() : position_(0), list_(list_) + {} + + private: + /** + * @brief Constructor. + * @param list The list we are an iterator for. + * @param position The initial position of the iterator. + */ + inline ArrayListIterator(ArrayList<T,N>& arrayList, int position); + + /** + * @brief The current postion. + */ + int position_; + /** + * @brief The list we are an iterator for. + */ + ArrayList<T,N>* list_; + }; /** - * @brief A random access iterator for the Dune::ArrayList class. + * @brief A constant random access iterator for the Dune::ArrayList class. */ template<class T, int N> - class ArrayListIterator { + class ConstArrayListIterator + : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N>, const T> + { friend class ArrayList<T,N>; - friend int operator-<>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); - friend ArrayListIterator<T,N> operator+<>(const ArrayListIterator<T,N>& a, int i); - friend ArrayListIterator<T,N> operator-<>(const ArrayListIterator<T,N>& a, int i); - friend ArrayListIterator<T,N> operator+<>(int i, const ArrayListIterator<T,N>& a); - friend ArrayListIterator<T,N> operator-<>(int i, const ArrayListIterator<T,N>& a); - friend bool operator< <>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); - friend bool operator<=<>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); - friend bool operator><>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); - friend bool operator>=<>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b); + friend class ArrayListIterator<T,N>; public: /** * @brief The member type. */ - typedef T memberType; + typedef T MemberType; - enum { + enum + { /** * @brief The number of elements in one chunk of the list. * @@ -205,82 +271,49 @@ namespace Dune { * @return true if the iterators are for the same list and * at the position. */ - bool operator==(const ArrayListIterator<memberType,N>& other) const; - - /** - * @brief Checks wether to iterator are different. - * @return True if the position or list differ. - */ - bool operator!=(const ArrayListIterator<memberType,N>& other) const; - + inline bool equals(const ConstArrayListIterator<MemberType,N>& other) const; /** * @brief Increment the iterator. */ - ArrayListIterator<memberType,N>& operator++(); - - /** - * @brief Increment the iterator. - */ - ArrayListIterator<memberType,N> operator++(int i); + inline void increment(); /** * @brief decrement the iterator. */ - ArrayListIterator<memberType,N>& operator--(); + inline void decrement(); - /** - * @brief decrement the iterator. - */ - ArrayListIterator<memberType,N> operator--(int i); + inline void advance(int n); - /** - * @brief Increments the iterator by an arbitrary value of positions. - * @param count The number of positions to advance. - * @return The iterator at that position. - */ - const ArrayListIterator<memberType,N>& operator+=(int count); - - /** - * @brief Decrements the iterator by an arbitrary value of positions. - * @param count The number of positions to decrement. - * @return The iterator at that position. - */ - const ArrayListIterator<memberType,N>& operator-=(int count); + inline int distanceTo(const ConstArrayListIterator<MemberType,N>& other) const; /** * @brief Get the value of the list at an arbitrary position. * @return The value at that postion. */ - memberType& operator[](int i) const; + inline const MemberType& elementAt(int i) const; /** * @brief Access the element at the current position. * @return The element at the current position. */ - memberType& operator*() const; + inline const MemberType& dereference() const; - /** - * @brief Returns a pointer to the current entry. - * @return A pointer to the current entry. - */ - memberType* operator->() const; + inline const ConstArrayListIterator<MemberType,N>& operator=(const ConstArrayListIterator<MemberType,N>& other); - /** - * @brief Removes all indices before the current position. - */ - void removeUpToHere(); + inline ConstArrayListIterator() : position_(0), list_(list_) + {} - const ArrayListIterator<memberType,N>& operator=(const ArrayListIterator<memberType,N>& other); + inline ConstArrayListIterator(const ArrayListIterator<MemberType,N>& other); - ArrayListIterator(const ArrayListIterator<memberType,N>& other); private: + /** * @brief Constructor. * @param list The list we are an iterator for. * @param position The initial position of the iterator. */ - ArrayListIterator(ArrayList<T,N>& arrayList, int position); + inline ConstArrayListIterator(const ArrayList<T,N>& arrayList, int position); /** * @brief The current postion. @@ -289,207 +322,230 @@ namespace Dune { /** * @brief The list we are an iterator for. */ - ArrayList<T,N>& list_; + const ArrayList<T,N>* list_; }; template<class T, int N> - ArrayList<T,N>::ArrayList() : capacity_(0), size_(0), start_(0){ + ArrayList<T,N>::ArrayList() + : capacity_(0), size_(0), start_(0) + { chunks_.reserve(100); } template<class T, int N> - ArrayList<T,N>::~ArrayList(){ + ArrayList<T,N>::~ArrayList() + { for(int chunk=capacity_/chunkSize_-1; chunk>=0; chunk--) delete chunks_[chunk]; } template<class T, int N> - void ArrayList<T,N>::push_back(const T& entry){ + void ArrayList<T,N>::push_back(const T& entry) + { int chunk = (start_+size_)/chunkSize_; - if((start_+size_)==capacity_) { - chunks_[chunk] = new FixedArray<memberType,chunkSize_>(); + if((start_+size_)==capacity_) + { + chunks_[chunk] = new FixedArray<MemberType,chunkSize_>(); capacity_ += chunkSize_; } chunks_[chunk]->operator[]((start_+(size_++))%chunkSize_)=entry; } template<class T, int N> - ArrayListIterator<T,N> ArrayList<T,N>::begin(){ - return ArrayListIterator<T,N>(*this, start_); + T& ArrayList<T,N>::operator[](int i) + { + int index = start_+i; + return chunks_[index/chunkSize_]->operator[](index%chunkSize_); } - template<class T, int N> - const ArrayListIterator<T,N> ArrayList<T,N>::begin() const { - return ArrayListIterator<T,N>(*this, start_); - } - - template<class T, int N> - ArrayListIterator<T,N> ArrayList<T,N>::end(){ - return ArrayListIterator<T,N>(*this, start_+size_); - } template<class T, int N> - const ArrayListIterator<T,N> ArrayList<T,N>::end() const { - return ArrayListIterator<T,N>(*this, start_+size_); + const T& ArrayList<T,N>::operator[](int i) const + { + int index = start_+i; + return chunks_[index/chunkSize_]->operator[](index%chunkSize_); } template<class T, int N> - int operator-(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ - b.position_; + ArrayListIterator<T,N> ArrayList<T,N>::begin() + { + return ArrayListIterator<T,N>(*this, start_); } template<class T, int N> - int operator+(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ + b.position_; + ConstArrayListIterator<T,N> ArrayList<T,N>::begin() const + { + return ConstArrayListIterator<T,N>(*this, start_); } template<class T, int N> - ArrayListIterator<T,N> operator+(const ArrayListIterator<T,N>& a, int i){ - ArrayListIterator<T,N> b=a; - b.position_+=i; - return b; + ArrayListIterator<T,N> ArrayList<T,N>::end() + { + return ArrayListIterator<T,N>(*this, start_+size_); } template<class T, int N> - ArrayListIterator<T,N> operator-(const ArrayListIterator<T,N>& a, int i){ - ArrayListIterator<T,N> b=a; - b.position_-=i; - return b; + ConstArrayListIterator<T,N> ArrayList<T,N>::end() const + { + return ConstArrayListIterator<T,N>(*this, start_+size_); } template<class T, int N> - ArrayListIterator<T,N> operator+(int i, const ArrayListIterator<T,N>& a){ - ArrayListIterator<T,N> b=a; - b.position_+=i; - return b; + void ArrayListIterator<T,N>::advance(int i) + { + position_+=i; } template<class T, int N> - ArrayListIterator<T,N> operator-(int i, const ArrayListIterator<T,N>& a){ - ArrayListIterator<T,N> b=a; - b.position_-=i; - return b; + void ConstArrayListIterator<T,N>::advance(int i) + { + position_+=i; } - template<class T, int N> - bool operator<(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ < b.position_; - } template<class T, int N> - bool operator<=(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ <= b.position_; + bool ArrayListIterator<T,N>::equals(const ArrayListIterator<MemberType,N>& other) const + { + // Makes only sense if we reference a common list + assert(list_==(other.list_)); + return position_==other.position_ ; } - template<class T, int N> - bool operator>(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ > b.position_; - } template<class T, int N> - bool operator>=(const ArrayListIterator<T,N>& a, const ArrayListIterator<T,N>& b){ - return a.position_ >= b.position_; + bool ArrayListIterator<T,N>::equals(const ConstArrayListIterator<MemberType,N>& other) const + { + // Makes only sense if we reference a common list + assert(list_==(other.list_)); + return position_==other.position_ ; } + template<class T, int N> - bool ArrayListIterator<T,N>::operator==(const ArrayListIterator<memberType,N>& other) const { + bool ConstArrayListIterator<T,N>::equals(const ConstArrayListIterator<MemberType,N>& other) const + { // Makes only sense if we reference a common list - assert((&list_)==(&(other.list_))); + assert(list_==(other.list_)); return position_==other.position_ ; } template<class T, int N> - bool ArrayListIterator<T,N>::operator!=(const ArrayListIterator<memberType,N>& other) const { - // Makes only sense if we reference a common list - assert((&list_)==(&(other.list_))); - return position_!=other.position_; + void ArrayListIterator<T,N>::increment() + { + ++position_; } template<class T, int N> - ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator++(){ + void ConstArrayListIterator<T,N>::increment() + { ++position_; - return *this; } template<class T, int N> - ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator--(){ + void ArrayListIterator<T,N>::decrement() + { --position_; - return *this; } template<class T, int N> - ArrayListIterator<T,N> ArrayListIterator<T,N>::operator++(int i) { - ArrayListIterator<T,N> al=*this; - ++position_; - return al; + void ConstArrayListIterator<T,N>::decrement() + { + --position_; } template<class T, int N> - ArrayListIterator<T,N> ArrayListIterator<T,N>::operator--(int i){ - ArrayListIterator<T,N> al=*this; - --position_; - return al; + T& ArrayListIterator<T,N>::elementAt(int i) const + { + i+=position_; + return list_->operator[](i+position_); } template<class T, int N> - const ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator+=(int count){ - position_ += count; - return *this; + const T& ConstArrayListIterator<T,N>::elementAt(int i) const + { + return list_->operator[](i+position_); } template<class T, int N> - const ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator-=(int count){ - position_ -= count; - return *this; + T& ArrayListIterator<T,N>::dereference() const + { + return list_->operator[](position_); } template<class T, int N> - T& ArrayListIterator<T,N>::operator[](int i) const { - i+=position_; - return list_.chunks_[i/chunkSize_]->operator[](i%chunkSize_); + const T& ConstArrayListIterator<T,N>::dereference() const + { + return list_->operator[](position_); + } + + template<class T, int N> + int ArrayListIterator<T,N>::distanceTo(const ArrayListIterator<T,N>& other) const + { + // Makes only sense if we reference a common list + assert(list_==(other.list_)); + return other.position_ - position_; } template<class T, int N> - T& ArrayListIterator<T,N>::operator*() const { - return list_.chunks_[position_/chunkSize_]->operator[](position_%chunkSize_); + int ConstArrayListIterator<T,N>::distanceTo(const ConstArrayListIterator<T,N>& other) const + { + // Makes only sense if we reference a common list + assert(list_==(other.list_)); + return other.position_ - position_; } template<class T, int N> - T *ArrayListIterator<T,N>::operator->() const { - return &(list_.chunks_[position_/chunkSize_]->operator[](position_%chunkSize_)); + const ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator=(const ArrayListIterator<T,N>& other) + { + position_=other.position_; + list_=other.list_; + return *this; } template<class T, int N> - const ArrayListIterator<T,N>& ArrayListIterator<T,N>::operator=(const ArrayListIterator<T,N>& other){ + const ConstArrayListIterator<T,N>& ConstArrayListIterator<T,N>::operator=(const ConstArrayListIterator<T,N>& other) + { position_=other.position_; list_=other.list_; return *this; } template<class T, int N> - void ArrayListIterator<T,N>::removeUpToHere(){ + void ArrayListIterator<T,N>::removeUpToHere() + { int chunks = position_/chunkSize_; - typedef typename std::vector<FixedArray<memberType,chunkSize_>* >::iterator iterator; - iterator chunk=list_.chunks_.begin(); + typedef typename std::vector<FixedArray<MemberType,chunkSize_>* >::iterator iterator; + iterator chunk=list_->chunks_.begin(); - for(int i=0; i < chunks; i++) { + for(int i=0; i < chunks; i++) + { delete (*chunk); - chunk = list_.chunks_.erase(chunk); + chunk = list_->chunks_.erase(chunk); } - list_.start_ = position_ % chunkSize_; - position_ = list_.start_; + list_->start_ = position_ % chunkSize_; + position_ = list_->start_; } template<class T, int N> - ArrayListIterator<T,N>::ArrayListIterator(ArrayList<T,N>& arrayList, int position) : position_(position), list_(arrayList){} + ArrayListIterator<T,N>::ArrayListIterator(ArrayList<T,N>& arrayList, int position) + : position_(position), list_(&arrayList) + {} + + + template<class T, int N> + ConstArrayListIterator<T,N>::ConstArrayListIterator(const ArrayList<T,N>& arrayList, int position) + : position_(position), list_(&arrayList) + {} template<class T, int N> - ArrayListIterator<T,N>::ArrayListIterator(const ArrayListIterator<T,N>& other) - : position_(other.position_), list_(other.list_){} + ConstArrayListIterator<T,N>::ConstArrayListIterator(const ArrayListIterator<T,N>& other) + : position_(other.position_), list_(other.list_) + {} + /** @} */ } diff --git a/common/test/.gitignore b/common/test/.gitignore index ab73500fa..d4d9f5d27 100644 --- a/common/test/.gitignore +++ b/common/test/.gitignore @@ -6,4 +6,5 @@ semantic.cache parsetest test-stack arraylisttest -smartpointertest \ No newline at end of file +smartpointertest +iteratorfacadetest \ No newline at end of file diff --git a/common/test/arraylisttest.cc b/common/test/arraylisttest.cc index 67c87b169..70a1cd4e1 100644 --- a/common/test/arraylisttest.cc +++ b/common/test/arraylisttest.cc @@ -2,6 +2,7 @@ // vi: set et ts=4 sw=2 sts=2: // $Id$ #include <dune/common/arraylist.hh> +#include <dune/common/test/iteratortest.hh> #include <iostream> #include <cstdlib> #include <algorithm> @@ -50,6 +51,7 @@ int testSorting(){ return 1; } } + return 0; } @@ -123,9 +125,8 @@ int testComparison(){ initConsecutive(alist); ArrayList<double,10>::iterator iter=alist.begin(), iter1=alist.begin(); - iter1=5+iter; + iter1=iter+5; iter1=iter-5; - iter1=5-iter; iter1=iter+5; @@ -165,8 +166,10 @@ int testComparison(){ int main(){ using namespace Dune; using namespace std; + ArrayList<double,100> alist; - int ret=0; + randomizeList(alist); + int ret=testIterator(alist); if(0!=testComparison()) { ret++; -- GitLab