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
00044 template<class T, int N=100, class A=std::allocator<T> >
00045 class ArrayList
00046 {
00047 public:
00053 typedef T MemberType;
00054
00058 typedef T value_type;
00059
00063 typedef T& reference;
00064
00068 typedef const T& const_reference;
00069
00073 typedef T* pointer;
00074
00078 typedef const T* const_pointer;
00079
00080 enum
00081 {
00086 chunkSize_ = (N > 0)? N : 1
00087 };
00088
00092 typedef ArrayListIterator<MemberType,N,A> iterator;
00093
00097 typedef ConstArrayListIterator<MemberType,N,A> const_iterator;
00098
00102 typedef std::size_t size_type;
00103
00107 typedef std::ptrdiff_t difference_type;
00108
00113 iterator begin();
00114
00120 const_iterator begin() const;
00121
00126 iterator end();
00127
00132 const_iterator end() const;
00133
00138 inline void push_back(const_reference entry);
00139
00145 inline reference operator[](size_type i);
00146
00152 inline const_reference operator[](size_type i) const;
00153
00158 inline size_type size() const;
00159
00164 inline size_type capacity() const;
00165
00173 inline void purge();
00174
00178 inline void clear();
00182 ArrayList();
00183
00184 private:
00185
00189 typedef typename A::template rebind<SmartPointer<array<MemberType,chunkSize_> > >::other
00190 SmartPointerAllocator;
00191
00195 friend class ArrayListIterator<T,N,A>;
00196 friend class ConstArrayListIterator<T,N,A>;
00197
00199 std::vector<SmartPointer<array<MemberType,chunkSize_> >,
00200 SmartPointerAllocator> chunks_;
00202 size_type capacity_;
00204 size_type size_;
00206 size_type start_;
00215 inline reference elementAt(size_type i);
00216
00225 inline const_reference elementAt(size_type i) const;
00226 };
00227
00228
00232 template<class T, int N, class A>
00233 class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
00234 typename A::value_type,
00235 typename A::reference,
00236 typename A::difference_type>
00237 {
00238
00239 friend class ArrayList<T,N,A>;
00240 friend class ConstArrayListIterator<T,N,A>;
00241 public:
00245 typedef typename A::value_type MemberType;
00246
00247 typedef typename A::difference_type difference_type;
00248
00249 typedef typename A::size_type size_type;
00250
00251 enum
00252 {
00258 chunkSize_ = (N > 0)? N : 1
00259 };
00260
00261
00267 inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const;
00268
00274 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00275
00279 inline void increment();
00280
00284 inline void decrement();
00285
00290 inline MemberType& elementAt(size_type i)const;
00291
00296 inline MemberType& dereference()const;
00297
00309 inline void eraseToHere();
00310
00312 inline size_type position(){return position_;}
00313
00315 inline void advance(difference_type n);
00316
00318 inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const;
00319
00321 inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other);
00322
00324 inline ArrayListIterator() : position_(0)
00325 {}
00326
00327 private:
00333 inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
00334
00338 size_type position_;
00342 ArrayList<T,N,A>* list_;
00343 };
00344
00348 template<class T, int N, class A>
00349 class ConstArrayListIterator
00350 : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>,
00351 const typename A::value_type,
00352 typename A::const_reference,
00353 typename A::difference_type>
00354 {
00355
00356 friend class ArrayList<T,N,A>;
00357 friend class ArrayListIterator<T,N,A>;
00358
00359 public:
00363 typedef typename A::value_type MemberType;
00364
00365 typedef typename A::difference_type difference_type;
00366
00367 typedef typename A::size_type size_type;
00368
00369 enum
00370 {
00376 chunkSize_ = (N > 0)? N : 1
00377 };
00378
00384 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00385
00389 inline void increment();
00390
00394 inline void decrement();
00395
00397 inline void advance(difference_type n);
00398
00400 inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const;
00401
00406 inline const MemberType& elementAt(size_type i)const;
00407
00412 inline const MemberType& dereference()const;
00413
00414 inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other);
00415
00416 inline ConstArrayListIterator() : position_(0)
00417 {}
00418
00419 inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other);
00420
00421 private:
00422
00428 inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
00429
00433 size_type position_;
00437 const ArrayList<T,N,A>* list_;
00438 };
00439
00440
00441 template<class T, int N, class A>
00442 ArrayList<T,N,A>::ArrayList()
00443 : capacity_(0), size_(0), start_(0)
00444 {
00445 chunks_.reserve(100);
00446 }
00447
00448 template<class T, int N, class A>
00449 void ArrayList<T,N,A>::clear(){
00450 capacity_=0;
00451 size_=0;
00452 start_=0;
00453 chunks_.clear();
00454 }
00455
00456 template<class T, int N, class A>
00457 size_t ArrayList<T,N,A>::size() const
00458 {
00459 return size_;
00460 }
00461
00462 template<class T, int N, class A>
00463 size_t ArrayList<T,N,A>::capacity() const
00464 {
00465 return capacity_;
00466 }
00467
00468 template<class T, int N, class A>
00469 void ArrayList<T,N,A>::push_back(const_reference entry)
00470 {
00471 size_t index=start_+size_;
00472 if(index==capacity_)
00473 {
00474 chunks_.push_back(SmartPointer<array<MemberType,chunkSize_> >());
00475 capacity_ += chunkSize_;
00476 }
00477 elementAt(index)=entry;
00478 ++size_;
00479 }
00480
00481 template<class T, int N, class A>
00482 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i)
00483 {
00484 return elementAt(start_+i);
00485 }
00486
00487
00488 template<class T, int N, class A>
00489 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const
00490 {
00491 return elementAt(start_+i);
00492 }
00493
00494 template<class T, int N, class A>
00495 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i)
00496 {
00497 return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00498 }
00499
00500
00501 template<class T, int N, class A>
00502 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const
00503 {
00504 return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00505 }
00506
00507 template<class T, int N, class A>
00508 ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin()
00509 {
00510 return ArrayListIterator<T,N,A>(*this, start_);
00511 }
00512
00513 template<class T, int N, class A>
00514 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const
00515 {
00516 return ConstArrayListIterator<T,N,A>(*this, start_);
00517 }
00518
00519 template<class T, int N, class A>
00520 ArrayListIterator<T,N,A> ArrayList<T,N,A>::end()
00521 {
00522 return ArrayListIterator<T,N,A>(*this, start_+size_);
00523 }
00524
00525 template<class T, int N, class A>
00526 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const
00527 {
00528 return ConstArrayListIterator<T,N,A>(*this, start_+size_);
00529 }
00530
00531 template<class T, int N, class A>
00532 void ArrayList<T,N,A>::purge()
00533 {
00534
00535 size_t distance = start_/chunkSize_;
00536 if(distance>0){
00537
00538 size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
00539
00540 typedef typename std::vector<SmartPointer<array<MemberType,
00541 chunkSize_> > >::iterator iterator;
00542
00543
00544 std::copy(chunks_.begin()+distance,
00545 chunks_.begin()+(distance+chunks), chunks_.begin());
00546
00547
00548 start_ = start_ % chunkSize_;
00549
00550 }
00551 }
00552
00553 template<class T, int N, class A>
00554 void ArrayListIterator<T,N,A>::advance(difference_type i)
00555 {
00556 position_+=i;
00557 }
00558
00559 template<class T, int N, class A>
00560 void ConstArrayListIterator<T,N,A>::advance(difference_type i)
00561 {
00562 position_+=i;
00563 }
00564
00565
00566 template<class T, int N, class A>
00567 bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const
00568 {
00569
00570 assert(list_==(other.list_));
00571 return position_==other.position_ ;
00572 }
00573
00574
00575 template<class T, int N, class A>
00576 bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00577 {
00578
00579 assert(list_==(other.list_));
00580 return position_==other.position_ ;
00581 }
00582
00583
00584 template<class T, int N, class A>
00585 bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00586 {
00587
00588 assert(list_==(other.list_));
00589 return position_==other.position_ ;
00590 }
00591
00592 template<class T, int N, class A>
00593 void ArrayListIterator<T,N,A>::increment()
00594 {
00595 ++position_;
00596 }
00597
00598 template<class T, int N, class A>
00599 void ConstArrayListIterator<T,N,A>::increment()
00600 {
00601 ++position_;
00602 }
00603
00604 template<class T, int N, class A>
00605 void ArrayListIterator<T,N,A>::decrement()
00606 {
00607 --position_;
00608 }
00609
00610 template<class T, int N, class A>
00611 void ConstArrayListIterator<T,N,A>::decrement()
00612 {
00613 --position_;
00614 }
00615
00616 template<class T, int N, class A>
00617 typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::elementAt(size_type i) const
00618 {
00619 i+=position_;
00620 return list_->elementAt(i+position_);
00621 }
00622
00623 template<class T, int N, class A>
00624 const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::elementAt(size_type i) const
00625 {
00626 return list_->elementAt(i+position_);
00627 }
00628
00629 template<class T, int N, class A>
00630 typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::dereference() const
00631 {
00632 return list_->elementAt(position_);
00633 }
00634
00635 template<class T, int N, class A>
00636 const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::dereference() const
00637 {
00638 return list_->elementAt(position_);
00639 }
00640
00641 template<class T, int N, class A>
00642 typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
00643 {
00644
00645 assert(list_==(other.list_));
00646 return other.position_ - position_;
00647 }
00648
00649 template<class T, int N, class A>
00650 typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
00651 {
00652
00653 assert(list_==(other.list_));
00654 return other.position_ - position_;
00655 }
00656
00657 template<class T, int N, class A>
00658 ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other)
00659 {
00660 position_=other.position_;
00661 list_=other.list_;
00662 return *this;
00663 }
00664
00665 template<class T, int N, class A>
00666 const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other)
00667 {
00668 position_=other.position_;
00669 list_=other.list_;
00670 return *this;
00671 }
00672
00673 template<class T, int N, class A>
00674 void ArrayListIterator<T,N,A>::eraseToHere()
00675 {
00676 list_->size_ -= ++position_ - list_->start_;
00677
00678 size_t posChunkStart = position_ / chunkSize_;
00679
00680 size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
00681 / chunkSize_;
00682 list_->start_ = position_;
00683
00684
00685 for(size_t chunk=0; chunk<chunks;chunk++)
00686 list_->chunks_[--posChunkStart].deallocate();
00687
00688
00689 list_->capacity_-=chunks*chunkSize_;
00690 }
00691
00692 template<class T, int N, class A>
00693 ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position)
00694 : position_(position), list_(&arrayList)
00695 {}
00696
00697
00698 template<class T, int N, class A>
00699 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList,
00700 size_type position)
00701 : position_(position), list_(&arrayList)
00702 {}
00703
00704 template<class T, int N, class A>
00705 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
00706 : position_(other.position_), list_(other.list_)
00707 {}
00708
00709
00711 }
00712 #endif