00001
00002
00003 #ifndef DUNE_ARRAYLIST_HH
00004 #define DUNE_ARRAYLIST_HH
00005
00006 #include<cassert>
00007 #include<vector>
00008 #include"smartpointer.hh"
00009 #include"fixedarray.hh"
00010 #include"iteratorfacades.hh"
00011
00012 namespace Dune
00013 {
00014
00015 template<class T, int N, class A>
00016 class ArrayListIterator;
00017
00018 template<class T, int N, class A>
00019 class ConstArrayListIterator;
00020
00055 template<class T, int N=100, class A=std::allocator<T> >
00056 class ArrayList
00057 {
00058 public:
00064 typedef T MemberType;
00065
00069 typedef T value_type;
00070
00074 typedef T& reference;
00075
00079 typedef const T& const_reference;
00080
00084 typedef T* pointer;
00085
00089 typedef const T* const_pointer;
00090
00091 enum
00092 {
00097 chunkSize_ = (N > 0)? N : 1
00098 };
00099
00103 typedef ArrayListIterator<MemberType,N,A> iterator;
00104
00108 typedef ConstArrayListIterator<MemberType,N,A> const_iterator;
00109
00113 typedef std::size_t size_type;
00114
00118 typedef std::ptrdiff_t difference_type;
00119
00124 iterator begin();
00125
00131 const_iterator begin() const;
00132
00137 iterator end();
00138
00143 const_iterator end() const;
00144
00149 inline void push_back(const_reference entry);
00150
00156 inline reference operator[](size_type i);
00157
00163 inline const_reference operator[](size_type i) const;
00164
00169 inline size_type size() const;
00170
00175 inline size_type capacity() const;
00176
00184 inline void purge();
00185
00189 inline void clear();
00193 ArrayList();
00194
00195 private:
00196
00200 typedef typename A::template rebind<SmartPointer<array<MemberType,chunkSize_> > >::other
00201 SmartPointerAllocator;
00202
00206 friend class ArrayListIterator<T,N,A>;
00207 friend class ConstArrayListIterator<T,N,A>;
00208
00210 std::vector<SmartPointer<array<MemberType,chunkSize_> >,
00211 SmartPointerAllocator> chunks_;
00213 size_type capacity_;
00215 size_type size_;
00217 size_type start_;
00226 inline reference elementAt(size_type i);
00227
00236 inline const_reference elementAt(size_type i) const;
00237 };
00238
00239
00243 template<class T, int N, class A>
00244 class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
00245 typename A::value_type,
00246 typename A::reference,
00247 typename A::difference_type>
00248 {
00249
00250 friend class ArrayList<T,N,A>;
00251 friend class ConstArrayListIterator<T,N,A>;
00252 public:
00256 typedef typename A::value_type MemberType;
00257
00258 typedef typename A::difference_type difference_type;
00259
00260 typedef typename A::size_type size_type;
00261
00262 enum
00263 {
00269 chunkSize_ = (N > 0)? N : 1
00270 };
00271
00272
00278 inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const;
00279
00285 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00286
00290 inline void increment();
00291
00295 inline void decrement();
00296
00301 inline MemberType& elementAt(size_type i)const;
00302
00307 inline MemberType& dereference()const;
00308
00320 inline void eraseToHere();
00321
00323 inline size_type position(){return position_;}
00324
00326 inline void advance(difference_type n);
00327
00329 inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const;
00330
00332 inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other);
00333
00335 inline ArrayListIterator() : position_(0)
00336 {}
00337
00338 private:
00344 inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
00345
00349 size_type position_;
00353 ArrayList<T,N,A>* list_;
00354 };
00355
00359 template<class T, int N, class A>
00360 class ConstArrayListIterator
00361 : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>,
00362 const typename A::value_type,
00363 typename A::const_reference,
00364 typename A::difference_type>
00365 {
00366
00367 friend class ArrayList<T,N,A>;
00368 friend class ArrayListIterator<T,N,A>;
00369
00370 public:
00374 typedef typename A::value_type MemberType;
00375
00376 typedef typename A::difference_type difference_type;
00377
00378 typedef typename A::size_type size_type;
00379
00380 enum
00381 {
00387 chunkSize_ = (N > 0)? N : 1
00388 };
00389
00395 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00396
00400 inline void increment();
00401
00405 inline void decrement();
00406
00408 inline void advance(difference_type n);
00409
00411 inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const;
00412
00417 inline const MemberType& elementAt(size_type i)const;
00418
00423 inline const MemberType& dereference()const;
00424
00425 inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other);
00426
00427 inline ConstArrayListIterator() : position_(0)
00428 {}
00429
00430 inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other);
00431
00432 private:
00433
00439 inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
00440
00444 size_type position_;
00448 const ArrayList<T,N,A>* list_;
00449 };
00450
00451
00452 template<class T, int N, class A>
00453 ArrayList<T,N,A>::ArrayList()
00454 : capacity_(0), size_(0), start_(0)
00455 {
00456 chunks_.reserve(100);
00457 }
00458
00459 template<class T, int N, class A>
00460 void ArrayList<T,N,A>::clear(){
00461 capacity_=0;
00462 size_=0;
00463 start_=0;
00464 chunks_.clear();
00465 }
00466
00467 template<class T, int N, class A>
00468 size_t ArrayList<T,N,A>::size() const
00469 {
00470 return size_;
00471 }
00472
00473 template<class T, int N, class A>
00474 size_t ArrayList<T,N,A>::capacity() const
00475 {
00476 return capacity_;
00477 }
00478
00479 template<class T, int N, class A>
00480 void ArrayList<T,N,A>::push_back(const_reference entry)
00481 {
00482 size_t index=start_+size_;
00483 if(index==capacity_)
00484 {
00485 chunks_.push_back(SmartPointer<array<MemberType,chunkSize_> >());
00486 capacity_ += chunkSize_;
00487 }
00488 elementAt(index)=entry;
00489 ++size_;
00490 }
00491
00492 template<class T, int N, class A>
00493 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i)
00494 {
00495 return elementAt(start_+i);
00496 }
00497
00498
00499 template<class T, int N, class A>
00500 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const
00501 {
00502 return elementAt(start_+i);
00503 }
00504
00505 template<class T, int N, class A>
00506 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i)
00507 {
00508 return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00509 }
00510
00511
00512 template<class T, int N, class A>
00513 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const
00514 {
00515 return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00516 }
00517
00518 template<class T, int N, class A>
00519 ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin()
00520 {
00521 return ArrayListIterator<T,N,A>(*this, start_);
00522 }
00523
00524 template<class T, int N, class A>
00525 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const
00526 {
00527 return ConstArrayListIterator<T,N,A>(*this, start_);
00528 }
00529
00530 template<class T, int N, class A>
00531 ArrayListIterator<T,N,A> ArrayList<T,N,A>::end()
00532 {
00533 return ArrayListIterator<T,N,A>(*this, start_+size_);
00534 }
00535
00536 template<class T, int N, class A>
00537 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const
00538 {
00539 return ConstArrayListIterator<T,N,A>(*this, start_+size_);
00540 }
00541
00542 template<class T, int N, class A>
00543 void ArrayList<T,N,A>::purge()
00544 {
00545
00546 size_t distance = start_/chunkSize_;
00547 if(distance>0){
00548
00549 size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
00550
00551 typedef typename std::vector<SmartPointer<array<MemberType,
00552 chunkSize_> > >::iterator iterator;
00553
00554
00555 std::copy(chunks_.begin()+distance,
00556 chunks_.begin()+(distance+chunks), chunks_.begin());
00557
00558
00559 start_ = start_ % chunkSize_;
00560
00561 }
00562 }
00563
00564 template<class T, int N, class A>
00565 void ArrayListIterator<T,N,A>::advance(difference_type i)
00566 {
00567 position_+=i;
00568 }
00569
00570 template<class T, int N, class A>
00571 void ConstArrayListIterator<T,N,A>::advance(difference_type i)
00572 {
00573 position_+=i;
00574 }
00575
00576
00577 template<class T, int N, class A>
00578 bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const
00579 {
00580
00581 assert(list_==(other.list_));
00582 return position_==other.position_ ;
00583 }
00584
00585
00586 template<class T, int N, class A>
00587 bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00588 {
00589
00590 assert(list_==(other.list_));
00591 return position_==other.position_ ;
00592 }
00593
00594
00595 template<class T, int N, class A>
00596 bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00597 {
00598
00599 assert(list_==(other.list_));
00600 return position_==other.position_ ;
00601 }
00602
00603 template<class T, int N, class A>
00604 void ArrayListIterator<T,N,A>::increment()
00605 {
00606 ++position_;
00607 }
00608
00609 template<class T, int N, class A>
00610 void ConstArrayListIterator<T,N,A>::increment()
00611 {
00612 ++position_;
00613 }
00614
00615 template<class T, int N, class A>
00616 void ArrayListIterator<T,N,A>::decrement()
00617 {
00618 --position_;
00619 }
00620
00621 template<class T, int N, class A>
00622 void ConstArrayListIterator<T,N,A>::decrement()
00623 {
00624 --position_;
00625 }
00626
00627 template<class T, int N, class A>
00628 typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::elementAt(size_type i) const
00629 {
00630 i+=position_;
00631 return list_->elementAt(i+position_);
00632 }
00633
00634 template<class T, int N, class A>
00635 const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::elementAt(size_type i) const
00636 {
00637 return list_->elementAt(i+position_);
00638 }
00639
00640 template<class T, int N, class A>
00641 typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::dereference() const
00642 {
00643 return list_->elementAt(position_);
00644 }
00645
00646 template<class T, int N, class A>
00647 const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::dereference() const
00648 {
00649 return list_->elementAt(position_);
00650 }
00651
00652 template<class T, int N, class A>
00653 typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
00654 {
00655
00656 assert(list_==(other.list_));
00657 return other.position_ - position_;
00658 }
00659
00660 template<class T, int N, class A>
00661 typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
00662 {
00663
00664 assert(list_==(other.list_));
00665 return other.position_ - position_;
00666 }
00667
00668 template<class T, int N, class A>
00669 ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other)
00670 {
00671 position_=other.position_;
00672 list_=other.list_;
00673 return *this;
00674 }
00675
00676 template<class T, int N, class A>
00677 const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other)
00678 {
00679 position_=other.position_;
00680 list_=other.list_;
00681 return *this;
00682 }
00683
00684 template<class T, int N, class A>
00685 void ArrayListIterator<T,N,A>::eraseToHere()
00686 {
00687 list_->size_ -= ++position_ - list_->start_;
00688
00689 size_t posChunkStart = position_ / chunkSize_;
00690
00691 size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
00692 / chunkSize_;
00693 list_->start_ = position_;
00694
00695
00696 for(size_t chunk=0; chunk<chunks;chunk++)
00697 list_->chunks_[--posChunkStart].deallocate();
00698
00699
00700 list_->capacity_-=chunks*chunkSize_;
00701 }
00702
00703 template<class T, int N, class A>
00704 ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position)
00705 : position_(position), list_(&arrayList)
00706 {}
00707
00708
00709 template<class T, int N, class A>
00710 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList,
00711 size_type position)
00712 : position_(position), list_(&arrayList)
00713 {}
00714
00715 template<class T, int N, class A>
00716 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
00717 : position_(other.position_), list_(other.list_)
00718 {}
00719
00720
00722 }
00723 #endif