dune-istl
2.1.1
|
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=4 sw=2 sts=2: 00003 #ifndef DUNE_BASEARRAY_HH 00004 #define DUNE_BASEARRAY_HH 00005 00006 #include "assert.h" 00007 #include<cmath> 00008 #include<complex> 00009 #include<cstddef> 00010 #include<memory> 00011 00012 #include "istlexception.hh" 00013 #include <dune/common/iteratorfacades.hh> 00014 00019 namespace Dune { 00020 00039 template<class B, class A=std::allocator<B> > 00040 class base_array_unmanaged 00041 { 00042 public: 00043 00044 //===== type definitions and constants 00045 00047 typedef B member_type; 00048 00050 typedef A allocator_type; 00051 00053 typedef typename A::size_type size_type; 00054 00055 00056 //===== access to components 00057 00059 B& operator[] (size_type i) 00060 { 00061 #ifdef DUNE_ISTL_WITH_CHECKING 00062 if (i>=n) DUNE_THROW(ISTLError,"index out of range"); 00063 #endif 00064 return p[i]; 00065 } 00066 00068 const B& operator[] (size_type i) const 00069 { 00070 #ifdef DUNE_ISTL_WITH_CHECKING 00071 if (i>=n) DUNE_THROW(ISTLError,"index out of range"); 00072 #endif 00073 return p[i]; 00074 } 00075 00077 template<class T> 00078 class RealIterator 00079 : public RandomAccessIteratorFacade<RealIterator<T>, T> 00080 { 00081 public: 00083 typedef typename remove_const<T>::type ValueType; 00084 00085 friend class RandomAccessIteratorFacade<RealIterator<const ValueType>, const ValueType>; 00086 friend class RandomAccessIteratorFacade<RealIterator<ValueType>, ValueType>; 00087 friend class RealIterator<const ValueType>; 00088 friend class RealIterator<ValueType>; 00089 00091 RealIterator () 00092 : p(0), i(0) 00093 {} 00094 00095 RealIterator (const B* _p, B* _i) : p(_p), i(_i) 00096 { } 00097 00098 RealIterator(const RealIterator<ValueType>& it) 00099 : p(it.p), i(it.i) 00100 {} 00101 00103 size_type index () const 00104 { 00105 return i-p; 00106 } 00107 00109 bool equals (const RealIterator<ValueType>& other) const 00110 { 00111 assert(other.p==p); 00112 return i==other.i; 00113 } 00114 00116 bool equals (const RealIterator<const ValueType>& other) const 00117 { 00118 assert(other.p==p); 00119 return i==other.i; 00120 } 00121 00122 std::ptrdiff_t distanceTo(const RealIterator& o) const 00123 { 00124 return o.i-i; 00125 } 00126 00127 private: 00129 void increment() 00130 { 00131 ++i; 00132 } 00133 00135 void decrement() 00136 { 00137 --i; 00138 } 00139 00141 B& dereference () const 00142 { 00143 return *i; 00144 } 00145 00146 void advance(std::ptrdiff_t d) 00147 { 00148 i+=d; 00149 } 00150 00151 const B* p; 00152 B* i; 00153 }; 00154 00156 typedef RealIterator<B> iterator; 00157 00158 00160 iterator begin () 00161 { 00162 return iterator(p,p); 00163 } 00164 00166 iterator end () 00167 { 00168 return iterator(p,p+n); 00169 } 00170 00175 iterator rbegin() DUNE_DEPRECATED 00176 { 00177 return beforeEnd(); 00178 } 00179 00180 00183 iterator beforeEnd () 00184 { 00185 return iterator(p,p+n-1); 00186 } 00187 00192 iterator rend () DUNE_DEPRECATED 00193 { 00194 return beforeBegin(); 00195 } 00196 00199 iterator beforeBegin () 00200 { 00201 return iterator(p,p-1); 00202 } 00203 00205 iterator find (size_type i) 00206 { 00207 if (i<n) 00208 return iterator(p,p+i); 00209 else 00210 return iterator(p,p+n); 00211 } 00212 00214 typedef RealIterator<const B> const_iterator; 00215 00217 const_iterator begin () const 00218 { 00219 return const_iterator(p,p+0); 00220 } 00221 00223 const_iterator end () const 00224 { 00225 return const_iterator(p,p+n); 00226 } 00227 00232 const_iterator rbegin() const DUNE_DEPRECATED 00233 { 00234 return beforeEnd(); 00235 } 00236 00239 const_iterator beforeEnd () const 00240 { 00241 return const_iterator(p,p+n-1); 00242 } 00243 00248 const_iterator rend () const DUNE_DEPRECATED 00249 { 00250 return beforeBegin(); 00251 } 00252 00255 const_iterator beforeBegin () const 00256 { 00257 return const_iterator(p,p-1); 00258 } 00259 00261 const_iterator find (size_type i) const 00262 { 00263 if (i<n) 00264 return const_iterator(p,p+i); 00265 else 00266 return const_iterator(p,p+n); 00267 } 00268 00269 00270 //===== sizes 00271 00273 size_type size () const 00274 { 00275 return n; 00276 } 00277 00278 protected: 00280 base_array_unmanaged () 00281 : n(0), p(0) 00282 {} 00284 base_array_unmanaged (size_type n_, B* p_) 00285 : n(n_), p(p_) 00286 {} 00287 size_type n; // number of elements in array 00288 B *p; // pointer to dynamically allocated built-in array 00289 }; 00290 00291 00292 00307 template<class B, class A=std::allocator<B> > 00308 class base_array_window : public base_array_unmanaged<B,A> 00309 { 00310 public: 00311 00312 //===== type definitions and constants 00313 00315 typedef B member_type; 00316 00318 typedef A allocator_type; 00319 00321 typedef typename base_array_unmanaged<B,A>::iterator iterator; 00322 00324 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator; 00325 00327 typedef typename base_array_unmanaged<B,A>::size_type size_type; 00328 00330 typedef typename A::difference_type difference_type; 00331 00332 //===== constructors and such 00333 00335 base_array_window () 00336 : base_array_unmanaged<B,A>() 00337 { } 00338 00340 base_array_window (B* _p, size_type _n) 00341 : base_array_unmanaged<B,A>(_n ,_p) 00342 {} 00343 00344 //===== window manipulation methods 00345 00347 void set (size_type _n, B* _p) 00348 { 00349 this->n = _n; 00350 this->p = _p; 00351 } 00352 00354 void advance (difference_type newsize) 00355 { 00356 this->p += this->n; 00357 this->n = newsize; 00358 } 00359 00361 void move (difference_type offset, size_type newsize) 00362 { 00363 this->p += offset; 00364 this->n = newsize; 00365 } 00366 00368 void move (difference_type offset) 00369 { 00370 this->p += offset; 00371 } 00372 00374 B* getptr () 00375 { 00376 return this->p; 00377 } 00378 }; 00379 00380 00381 00397 template<class B, class A=std::allocator<B> > 00398 class base_array : public base_array_unmanaged<B,A> 00399 { 00400 public: 00401 00402 //===== type definitions and constants 00403 00405 typedef B member_type; 00406 00408 typedef A allocator_type; 00409 00411 typedef typename base_array_unmanaged<B,A>::iterator iterator; 00412 00414 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator; 00415 00417 typedef typename base_array_unmanaged<B,A>::size_type size_type; 00418 00420 typedef typename A::difference_type difference_type; 00421 00422 //===== constructors and such 00423 00425 base_array () 00426 : base_array_unmanaged<B,A>() 00427 {} 00428 00430 base_array (size_type _n) 00431 : base_array_unmanaged<B,A>(_n, 0) 00432 { 00433 if (this->n>0) { 00434 this->p = allocator_.allocate(this->n); 00435 new (this->p) B[this->n]; 00436 } else 00437 { 00438 this->n = 0; 00439 this->p = 0; 00440 } 00441 } 00442 00444 base_array (const base_array& a) 00445 { 00446 // allocate memory with same size as a 00447 this->n = a.n; 00448 00449 if (this->n>0) { 00450 this->p = allocator_.allocate(this->n); 00451 new (this->p) B[this->n]; 00452 } else 00453 { 00454 this->n = 0; 00455 this->p = 0; 00456 } 00457 00458 // and copy elements 00459 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00460 } 00461 00463 base_array (const base_array_unmanaged<B,A>& _a) 00464 { 00465 const base_array& a = static_cast<const base_array&>(_a); 00466 00467 // allocate memory with same size as a 00468 this->n = a.n; 00469 if (this->n>0) { 00470 this->p = allocator_.allocate(this->n); 00471 new (this->p) B[this->n]; 00472 } else 00473 { 00474 this->n = 0; 00475 this->p = 0; 00476 } 00477 00478 // and copy elements 00479 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00480 } 00481 00482 00484 ~base_array () 00485 { 00486 if (this->n>0) { 00487 int i=this->n; 00488 while (i) 00489 this->p[--i].~B(); 00490 allocator_.deallocate(this->p,this->n); 00491 } 00492 } 00493 00495 void resize (size_type _n) 00496 { 00497 if (this->n==_n) return; 00498 00499 if (this->n>0) { 00500 int i=this->n; 00501 while (i) 00502 this->p[--i].~B(); 00503 allocator_.deallocate(this->p,this->n); 00504 } 00505 this->n = _n; 00506 if (this->n>0) { 00507 this->p = allocator_.allocate(this->n); 00508 new (this->p) B[this->n]; 00509 } else 00510 { 00511 this->n = 0; 00512 this->p = 0; 00513 } 00514 } 00515 00517 base_array& operator= (const base_array& a) 00518 { 00519 if (&a!=this) // check if this and a are different objects 00520 { 00521 // adjust size of array 00522 if (this->n!=a.n) // check if size is different 00523 { 00524 if (this->n>0) { 00525 int i=this->n; 00526 while (i) 00527 this->p[--i].~B(); 00528 allocator_.deallocate(this->p,this->n); // delete old memory 00529 } 00530 this->n = a.n; 00531 if (this->n>0) { 00532 this->p = allocator_.allocate(this->n); 00533 new (this->p) B[this->n]; 00534 } else 00535 { 00536 this->n = 0; 00537 this->p = 0; 00538 } 00539 } 00540 // copy data 00541 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00542 } 00543 return *this; 00544 } 00545 00547 base_array& operator= (const base_array_unmanaged<B,A>& a) 00548 { 00549 return this->operator=(static_cast<const base_array&>(a)); 00550 } 00551 00552 protected: 00553 00554 A allocator_; 00555 }; 00556 00557 00558 00559 00579 template<class B, class A=std::allocator<B> > 00580 class compressed_base_array_unmanaged 00581 { 00582 public: 00583 00584 //===== type definitions and constants 00585 00587 typedef B member_type; 00588 00590 typedef A allocator_type; 00591 00593 typedef typename A::size_type size_type; 00594 00595 //===== access to components 00596 00598 B& operator[] (size_type i) 00599 { 00600 size_type l=0, r=n-1; 00601 while (l<r) 00602 { 00603 size_type q = (l+r)/2; 00604 if (i <= j[q]) r=q; 00605 else l = q+1; 00606 } 00607 if (j[l]!=i){ 00608 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array"); 00609 } 00610 return p[l]; 00611 } 00612 00614 const B& operator[] (size_type i) const 00615 { 00616 size_type l=0, r=n-1; 00617 while (l<r) 00618 { 00619 size_type q = (l+r)/2; 00620 if (i <= j[q]) r=q; 00621 else l = q+1; 00622 } 00623 if (j[l]!=i){ 00624 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array"); 00625 } 00626 return p[l]; 00627 } 00628 00630 template<class T> 00631 class RealIterator 00632 : public BidirectionalIteratorFacade<RealIterator<T>, T> 00633 { 00634 public: 00636 typedef typename remove_const<T>::type ValueType; 00637 00638 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>; 00639 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>; 00640 friend class RealIterator<const ValueType>; 00641 friend class RealIterator<ValueType>; 00642 00644 RealIterator () 00645 : p(0), j(0), i(0) 00646 {} 00647 00649 RealIterator (B* _p, size_type* _j, size_type _i) 00650 : p(_p), j(_j), i(_i) 00651 { } 00652 00656 RealIterator(const RealIterator<ValueType>& it) 00657 : p(it.p), j(it.j), i(it.i) 00658 {} 00659 00660 00662 bool equals (const RealIterator<ValueType>& it) const 00663 { 00664 assert(p==it.p); 00665 return (i)==(it.i); 00666 } 00667 00669 bool equals (const RealIterator<const ValueType>& it) const 00670 { 00671 assert(p==it.p); 00672 return (i)==(it.i); 00673 } 00674 00675 00677 size_type index () const 00678 { 00679 return j[i]; 00680 } 00681 00683 void setindex (size_type k) 00684 { 00685 return j[i] = k; 00686 } 00687 00695 size_type offset () const 00696 { 00697 return i; 00698 } 00699 00700 private: 00702 void increment() 00703 { 00704 ++i; 00705 } 00706 00708 void decrement() 00709 { 00710 --i; 00711 } 00712 00714 B& dereference () const 00715 { 00716 return p[i]; 00717 } 00718 00719 B* p; 00720 size_type* j; 00721 size_type i; 00722 }; 00723 00725 typedef RealIterator<B> iterator; 00726 00728 iterator begin () 00729 { 00730 return iterator(p,j,0); 00731 } 00732 00734 iterator end () 00735 { 00736 return iterator(p,j,n); 00737 } 00738 00743 iterator rbegin() DUNE_DEPRECATED 00744 { 00745 return beforeEnd(); 00746 } 00747 00750 iterator beforeEnd () 00751 { 00752 return iterator(p,j,n-1); 00753 } 00754 00759 iterator rend () DUNE_DEPRECATED 00760 { 00761 return beforeBegin(); 00762 } 00763 00766 iterator beforeBegin () 00767 { 00768 return iterator(p,j,-1); 00769 } 00770 00772 iterator find (size_type i) 00773 { 00774 size_type l=0, r=n-1; 00775 while (l<r) 00776 { 00777 size_type q = (l+r)/2; 00778 if (i <= j[q]) r=q; 00779 else l = q+1; 00780 } 00781 00782 if (n && i==j[l]) 00783 return iterator(p,j,l); 00784 else 00785 return iterator(p,j,n); 00786 } 00787 00789 typedef RealIterator<const B> const_iterator; 00790 00792 const_iterator begin () const 00793 { 00794 return const_iterator(p,j,0); 00795 } 00796 00798 const_iterator end () const 00799 { 00800 return const_iterator(p,j,n); 00801 } 00802 00807 const_iterator rbegin() const DUNE_DEPRECATED 00808 { 00809 return beforeEnd(); 00810 } 00811 00814 const_iterator beforeEnd () const 00815 { 00816 return const_iterator(p,j,n-1); 00817 } 00818 00823 const_iterator rend () const DUNE_DEPRECATED 00824 { 00825 return beforeBegin(); 00826 } 00827 00830 const_iterator beforeBegin () const 00831 { 00832 return const_iterator(p,j,-1); 00833 } 00834 00836 const_iterator find (size_type i) const 00837 { 00838 size_type l=0, r=n-1; 00839 while (l<r) 00840 { 00841 size_type q = (l+r)/2; 00842 if (i <= j[q]) r=q; 00843 else l = q+1; 00844 } 00845 00846 if (n && i==j[l]) 00847 return const_iterator(p,j,l); 00848 else 00849 return const_iterator(p,j,n); 00850 } 00851 00852 //===== sizes 00853 00855 size_type size () const 00856 { 00857 return n; 00858 } 00859 00860 protected: 00862 compressed_base_array_unmanaged () 00863 : n(0), p(0), j(0) 00864 {} 00865 00866 size_type n; // number of elements in array 00867 B *p; // pointer to dynamically allocated built-in array 00868 size_type* j; // the index set 00869 }; 00870 00871 } // end namespace 00872 00873 #endif