- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 // $Id$ 00002 00003 #ifndef DUNE_ARRAYLIST_HH 00004 #define DUNE_ARRAYLIST_HH 00005 00006 #include<cassert> 00007 #include<vector> 00008 #include"shared_ptr.hh" 00009 #include"array.hh" 00010 #include"iteratorfacades.hh" 00011 00012 namespace Dune 00013 { 00014 // forward declaration 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 00178 inline void purge(); 00179 00183 inline void clear(); 00187 ArrayList(); 00188 00189 private: 00190 00194 typedef typename A::template rebind<shared_ptr<array<MemberType,chunkSize_> > >::other 00195 SmartPointerAllocator; 00196 00200 typedef typename A::template rebind<array<MemberType,chunkSize_> >::other 00201 ArrayAllocator; 00202 00206 friend class ArrayListIterator<T,N,A>; 00207 friend class ConstArrayListIterator<T,N,A>; 00208 00210 std::vector<shared_ptr<array<MemberType,chunkSize_> >, 00211 SmartPointerAllocator> chunks_; 00220 size_type capacity_; 00222 size_type size_; 00224 size_type start_; 00233 inline reference elementAt(size_type i); 00234 00243 inline const_reference elementAt(size_type i) const; 00244 }; 00245 00246 00250 template<class T, int N, class A> 00251 class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>, 00252 typename A::value_type, 00253 typename A::reference, 00254 typename A::difference_type> 00255 { 00256 00257 friend class ArrayList<T,N,A>; 00258 friend class ConstArrayListIterator<T,N,A>; 00259 public: 00263 typedef typename A::value_type MemberType; 00264 00265 typedef typename A::difference_type difference_type; 00266 00267 typedef typename A::size_type size_type; 00268 00269 typedef typename A::reference reference; 00270 00271 typedef typename A::const_reference const_reference; 00272 00273 enum 00274 { 00280 chunkSize_ = (N > 0)? N : 1 00281 }; 00282 00283 00289 inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const; 00290 00296 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const; 00297 00301 inline void increment(); 00302 00306 inline void decrement(); 00307 00312 inline reference elementAt(size_type i)const; 00313 00318 inline reference dereference()const; 00319 00331 inline void eraseToHere(); 00332 00334 inline size_type position(){return position_;} 00335 00337 inline void advance(difference_type n); 00338 00340 inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const; 00341 00343 inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other); 00344 00346 inline ArrayListIterator() : position_(0) 00347 {} 00348 00349 private: 00355 inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position); 00356 00360 size_type position_; 00364 ArrayList<T,N,A>* list_; 00365 }; 00366 00370 template<class T, int N, class A> 00371 class ConstArrayListIterator 00372 : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>, 00373 const typename A::value_type, 00374 typename A::const_reference, 00375 typename A::difference_type> 00376 { 00377 00378 friend class ArrayList<T,N,A>; 00379 friend class ArrayListIterator<T,N,A>; 00380 00381 public: 00385 typedef typename A::value_type MemberType; 00386 00387 typedef typename A::difference_type difference_type; 00388 00389 typedef typename A::size_type size_type; 00390 00391 typedef typename A::reference reference; 00392 00393 typedef typename A::const_reference const_reference; 00394 enum 00395 { 00401 chunkSize_ = (N > 0)? N : 1 00402 }; 00403 00409 inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const; 00410 00414 inline void increment(); 00415 00419 inline void decrement(); 00420 00422 inline void advance(difference_type n); 00423 00425 inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const; 00426 00431 inline const_reference elementAt(size_type i)const; 00432 00437 inline const_reference dereference()const; 00438 00439 inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other); 00440 00441 inline ConstArrayListIterator() : position_(0) 00442 {} 00443 00444 inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other); 00445 00446 private: 00447 00453 inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position); 00454 00458 size_type position_; 00462 const ArrayList<T,N,A>* list_; 00463 }; 00464 00465 00466 template<class T, int N, class A> 00467 ArrayList<T,N,A>::ArrayList() 00468 : capacity_(0), size_(0), start_(0) 00469 { 00470 chunks_.reserve(100); 00471 } 00472 00473 template<class T, int N, class A> 00474 void ArrayList<T,N,A>::clear(){ 00475 capacity_=0; 00476 size_=0; 00477 start_=0; 00478 chunks_.clear(); 00479 } 00480 00481 template<class T, int N, class A> 00482 size_t ArrayList<T,N,A>::size() const 00483 { 00484 return size_; 00485 } 00486 00487 template<class T, int N, class A> 00488 void ArrayList<T,N,A>::push_back(const_reference entry) 00489 { 00490 size_t index=start_+size_; 00491 if(index==capacity_) 00492 { 00493 chunks_.push_back(shared_ptr<array<MemberType,chunkSize_> >(new array<MemberType,chunkSize_>())); 00494 capacity_ += chunkSize_; 00495 } 00496 elementAt(index)=entry; 00497 ++size_; 00498 } 00499 00500 template<class T, int N, class A> 00501 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i) 00502 { 00503 return elementAt(start_+i); 00504 } 00505 00506 00507 template<class T, int N, class A> 00508 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const 00509 { 00510 return elementAt(start_+i); 00511 } 00512 00513 template<class T, int N, class A> 00514 typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i) 00515 { 00516 return chunks_[i/chunkSize_]->operator[](i%chunkSize_); 00517 } 00518 00519 00520 template<class T, int N, class A> 00521 typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const 00522 { 00523 return chunks_[i/chunkSize_]->operator[](i%chunkSize_); 00524 } 00525 00526 template<class T, int N, class A> 00527 ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() 00528 { 00529 return ArrayListIterator<T,N,A>(*this, start_); 00530 } 00531 00532 template<class T, int N, class A> 00533 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const 00534 { 00535 return ConstArrayListIterator<T,N,A>(*this, start_); 00536 } 00537 00538 template<class T, int N, class A> 00539 ArrayListIterator<T,N,A> ArrayList<T,N,A>::end() 00540 { 00541 return ArrayListIterator<T,N,A>(*this, start_+size_); 00542 } 00543 00544 template<class T, int N, class A> 00545 ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const 00546 { 00547 return ConstArrayListIterator<T,N,A>(*this, start_+size_); 00548 } 00549 00550 template<class T, int N, class A> 00551 void ArrayList<T,N,A>::purge() 00552 { 00553 // Distance to copy to the left. 00554 size_t distance = start_/chunkSize_; 00555 if(distance>0){ 00556 // Number of chunks with entries in it; 00557 size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ ); 00558 00559 typedef typename std::vector<shared_ptr<array<MemberType, 00560 chunkSize_> > >::iterator iterator; 00561 00562 // Copy chunks to the left. 00563 std::copy(chunks_.begin()+distance, 00564 chunks_.begin()+(distance+chunks), chunks_.begin()); 00565 00566 // Calculate new parameters 00567 start_ = start_ % chunkSize_; 00568 //capacity += distance * chunkSize_; 00569 } 00570 } 00571 00572 template<class T, int N, class A> 00573 void ArrayListIterator<T,N,A>::advance(difference_type i) 00574 { 00575 position_+=i; 00576 } 00577 00578 template<class T, int N, class A> 00579 void ConstArrayListIterator<T,N,A>::advance(difference_type i) 00580 { 00581 position_+=i; 00582 } 00583 00584 00585 template<class T, int N, class A> 00586 bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const 00587 { 00588 // Makes only sense if we reference a common list 00589 assert(list_==(other.list_)); 00590 return position_==other.position_ ; 00591 } 00592 00593 00594 template<class T, int N, class A> 00595 bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const 00596 { 00597 // Makes only sense if we reference a common list 00598 assert(list_==(other.list_)); 00599 return position_==other.position_ ; 00600 } 00601 00602 00603 template<class T, int N, class A> 00604 bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const 00605 { 00606 // Makes only sense if we reference a common list 00607 assert(list_==(other.list_)); 00608 return position_==other.position_ ; 00609 } 00610 00611 template<class T, int N, class A> 00612 void ArrayListIterator<T,N,A>::increment() 00613 { 00614 ++position_; 00615 } 00616 00617 template<class T, int N, class A> 00618 void ConstArrayListIterator<T,N,A>::increment() 00619 { 00620 ++position_; 00621 } 00622 00623 template<class T, int N, class A> 00624 void ArrayListIterator<T,N,A>::decrement() 00625 { 00626 --position_; 00627 } 00628 00629 template<class T, int N, class A> 00630 void ConstArrayListIterator<T,N,A>::decrement() 00631 { 00632 --position_; 00633 } 00634 00635 template<class T, int N, class A> 00636 typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::elementAt(size_type i) const 00637 { 00638 return list_->elementAt(i+position_); 00639 } 00640 00641 template<class T, int N, class A> 00642 typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::elementAt(size_type i) const 00643 { 00644 return list_->elementAt(i+position_); 00645 } 00646 00647 template<class T, int N, class A> 00648 typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::dereference() const 00649 { 00650 return list_->elementAt(position_); 00651 } 00652 00653 template<class T, int N, class A> 00654 typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::dereference() const 00655 { 00656 return list_->elementAt(position_); 00657 } 00658 00659 template<class T, int N, class A> 00660 typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const 00661 { 00662 // Makes only sense if we reference a common list 00663 assert(list_==(other.list_)); 00664 return other.position_ - position_; 00665 } 00666 00667 template<class T, int N, class A> 00668 typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const 00669 { 00670 // Makes only sense if we reference a common list 00671 assert(list_==(other.list_)); 00672 return other.position_ - position_; 00673 } 00674 00675 template<class T, int N, class A> 00676 ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other) 00677 { 00678 position_=other.position_; 00679 list_=other.list_; 00680 return *this; 00681 } 00682 00683 template<class T, int N, class A> 00684 const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other) 00685 { 00686 position_=other.position_; 00687 list_=other.list_; 00688 return *this; 00689 } 00690 00691 template<class T, int N, class A> 00692 void ArrayListIterator<T,N,A>::eraseToHere() 00693 { 00694 list_->size_ -= ++position_ - list_->start_; 00695 // chunk number of the new position. 00696 size_t posChunkStart = position_ / chunkSize_; 00697 // number of chunks to deallocate 00698 size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_) 00699 / chunkSize_; 00700 list_->start_ = position_; 00701 00702 // Deallocate memory not needed any more. 00703 for(size_t chunk=0; chunk<chunks;chunk++) { 00704 --posChunkStart; 00705 list_->chunks_[posChunkStart].reset(); 00706 } 00707 00708 // Capacity stays the same as the chunks before us 00709 // are still there. They null pointers. 00710 assert(list_->start_+list_->size_<=list_->capacity_); 00711 } 00712 00713 template<class T, int N, class A> 00714 ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position) 00715 : position_(position), list_(&arrayList) 00716 {} 00717 00718 00719 template<class T, int N, class A> 00720 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, 00721 size_type position) 00722 : position_(position), list_(&arrayList) 00723 {} 00724 00725 template<class T, int N, class A> 00726 ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other) 00727 : position_(other.position_), list_(other.list_) 00728 {} 00729 00730 00732 } 00733 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].