00001 #ifndef DUNE_BASEARRAY_HH
00002 #define DUNE_BASEARRAY_HH
00003
00004 #include "assert.h"
00005 #include<cmath>
00006 #include<complex>
00007 #include<cstddef>
00008
00009 #include "istlexception.hh"
00010 #include "allocator.hh"
00011 #include <dune/common/iteratorfacades.hh>
00012
00017 namespace Dune {
00018
00037 template<class B, class A=ISTLAllocator>
00038 class base_array_unmanaged
00039 {
00040 public:
00041
00042
00043
00045 typedef B member_type;
00046
00048 typedef A allocator_type;
00049
00051 typedef typename A::size_type size_type;
00052
00053
00054
00055
00057 B& operator[] (size_type i)
00058 {
00059 #ifdef DUNE_ISTL_WITH_CHECKING
00060 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
00061 #endif
00062 return p[i];
00063 }
00064
00066 const B& operator[] (size_type i) const
00067 {
00068 #ifdef DUNE_ISTL_WITH_CHECKING
00069 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
00070 #endif
00071 return p[i];
00072 }
00073
00075 template<class T>
00076 class RealIterator
00077 : public BidirectionalIteratorFacade<RealIterator<T>, T>
00078 {
00079 public:
00081 typedef typename remove_const<T>::type ValueType;
00082
00083 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
00084 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
00085 friend class RealIterator<const ValueType>;
00086 friend class RealIterator<ValueType>;
00087
00089 RealIterator ()
00090 : p(0), i(0)
00091 {}
00092
00093 RealIterator (const B* _p, B* _i) : p(_p), i(_i)
00094 { }
00095
00096 RealIterator(const RealIterator<ValueType>& it)
00097 : p(it.p), i(it.i)
00098 {}
00099
00101 size_type index () const
00102 {
00103 return i-p;
00104 }
00105
00107 bool equals (const RealIterator<ValueType>& other) const
00108 {
00109 assert(other.p==p);
00110 return i==other.i;
00111 }
00112
00114 bool equals (const RealIterator<const ValueType>& other) const
00115 {
00116 assert(other.p==p);
00117 return i==other.i;
00118 }
00119
00120 private:
00122 void increment()
00123 {
00124 ++i;
00125 }
00126
00128 void decrement()
00129 {
00130 --i;
00131 }
00132
00134 B& dereference () const
00135 {
00136 return *i;
00137 }
00138
00139 const B* p;
00140 B* i;
00141 };
00142
00144 typedef RealIterator<B> iterator;
00145
00146
00148 iterator begin ()
00149 {
00150 return iterator(p,p);
00151 }
00152
00154 iterator end ()
00155 {
00156 return iterator(p,p+n);
00157 }
00158
00160 iterator rbegin ()
00161 {
00162 return iterator(p,p+n-1);
00163 }
00164
00166 iterator rend ()
00167 {
00168 return iterator(p,p-1);
00169 }
00170
00172 iterator find (size_type i)
00173 {
00174 if (i<n)
00175 return iterator(p,p+i);
00176 else
00177 return iterator(p,p+n);
00178 }
00179
00181 typedef RealIterator<const B> const_iterator;
00182
00184 const_iterator begin () const
00185 {
00186 return const_iterator(p,p+0);
00187 }
00188
00190 const_iterator end () const
00191 {
00192 return const_iterator(p,p+n);
00193 }
00194
00196 const_iterator rbegin () const
00197 {
00198 return const_iterator(p,p+n-1);
00199 }
00200
00202 const_iterator rend () const
00203 {
00204 return const_iterator(p,p-1);
00205 }
00206
00208 const_iterator find (size_type i) const
00209 {
00210 if (i<n)
00211 return const_iterator(p,p+i);
00212 else
00213 return const_iterator(p,p+n);
00214 }
00215
00216
00217
00218
00220 size_type size () const
00221 {
00222 return n;
00223 }
00224
00225 protected:
00227 base_array_unmanaged ()
00228 : n(0), p(0)
00229 {}
00231 base_array_unmanaged (size_type n_, B* p_)
00232 : n(n_), p(p_)
00233 {}
00234 size_type n;
00235 B *p;
00236 };
00237
00238
00239
00254 template<class B, class A=ISTLAllocator>
00255 class base_array_window : public base_array_unmanaged<B,A>
00256 {
00257 public:
00258
00259
00260
00262 typedef B member_type;
00263
00265 typedef A allocator_type;
00266
00268 typedef typename base_array_unmanaged<B,A>::iterator iterator;
00269
00271 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator;
00272
00274 typedef typename base_array_unmanaged<B,A>::size_type size_type;
00275
00277 typedef typename A::difference_type difference_type;
00278
00279
00280
00282 base_array_window ()
00283 : base_array_unmanaged<B,A>()
00284 { }
00285
00287 base_array_window (B* _p, size_type _n)
00288 : base_array_unmanaged<B,A>(_n ,_p)
00289 {}
00290
00291
00292
00294 void set (size_type _n, B* _p)
00295 {
00296 this->n = _n;
00297 this->p = _p;
00298 }
00299
00301 void advance (difference_type newsize)
00302 {
00303 this->p += this->n;
00304 this->n = newsize;
00305 }
00306
00308 void move (difference_type offset, size_type newsize)
00309 {
00310 this->p += offset;
00311 this->n = newsize;
00312 }
00313
00315 void move (difference_type offset)
00316 {
00317 this->p += offset;
00318 }
00319
00321 B* getptr ()
00322 {
00323 return this->p;
00324 }
00325 };
00326
00327
00328
00344 template<class B, class A=ISTLAllocator>
00345 class base_array : public base_array_unmanaged<B,A>
00346 {
00347 public:
00348
00349
00350
00352 typedef B member_type;
00353
00355 typedef A allocator_type;
00356
00358 typedef typename base_array_unmanaged<B,A>::iterator iterator;
00359
00361 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator;
00362
00364 typedef typename base_array_unmanaged<B,A>::size_type size_type;
00365
00367 typedef typename A::difference_type difference_type;
00368
00369
00370
00372 base_array ()
00373 : base_array_unmanaged<B,A>()
00374 {}
00375
00377 base_array (size_type _n)
00378 : base_array_unmanaged<B,A>(_n, 0)
00379 {
00380 if (this->n>0)
00381 this->p = A::template malloc<B>(this->n);
00382 else
00383 {
00384 this->n = 0;
00385 this->p = 0;
00386 }
00387 }
00388
00390 base_array (const base_array& a)
00391 {
00392
00393 this->n = a.n;
00394
00395 if (this->n>0)
00396 this->p = A::template malloc<B>(this->n);
00397 else
00398 {
00399 this->n = 0;
00400 this->p = 0;
00401 }
00402
00403
00404 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00405 }
00406
00408 base_array (const base_array_unmanaged<B,A>& _a)
00409 {
00410 const base_array& a = static_cast<const base_array&>(_a);
00411
00412
00413 this->n = a.n;
00414 if (this->n>0)
00415 this->p = A::template malloc<B>(this->n);
00416 else
00417 {
00418 this->n = 0;
00419 this->p = 0;
00420 }
00421
00422
00423 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00424 }
00425
00426
00428 ~base_array ()
00429 {
00430 if (this->n>0) A::template free<B>(this->p);
00431 }
00432
00434 void resize (size_type _n)
00435 {
00436 if (this->n==_n) return;
00437
00438 if (this->n>0) A::template free<B>(this->p);
00439 this->n = _n;
00440 if (this->n>0)
00441 this->p = A::template malloc<B>(this->n);
00442 else
00443 {
00444 this->n = 0;
00445 this->p = 0;
00446 }
00447 }
00448
00450 base_array& operator= (const base_array& a)
00451 {
00452 if (&a!=this)
00453 {
00454
00455 if (this->n!=a.n)
00456 {
00457 if (this->n>0) A::template free<B>(this->p);
00458 this->n = a.n;
00459 if (this->n>0)
00460 this->p = A::template malloc<B>(this->n);
00461 else
00462 {
00463 this->n = 0;
00464 this->p = 0;
00465 }
00466 }
00467
00468 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00469 }
00470 return *this;
00471 }
00472
00474 base_array& operator= (const base_array_unmanaged<B,A>& a)
00475 {
00476 return this->operator=(static_cast<const base_array&>(a));
00477 }
00478
00479 };
00480
00481
00482
00483
00503 template<class B, class A=ISTLAllocator>
00504 class compressed_base_array_unmanaged
00505 {
00506 public:
00507
00508
00509
00511 typedef B member_type;
00512
00514 typedef A allocator_type;
00515
00517 typedef typename A::size_type size_type;
00518
00519
00520
00522 B& operator[] (size_type i)
00523 {
00524 size_type l=0, r=n-1;
00525 while (l<r)
00526 {
00527 size_type q = (l+r)/2;
00528 if (i <= j[q]) r=q;
00529 else l = q+1;
00530 }
00531 if (j[l]!=i) DUNE_THROW(ISTLError,"index not in compressed array");
00532 return p[l];
00533 }
00534
00536 const B& operator[] (size_type i) const
00537 {
00538 size_type l=0, r=n-1;
00539 while (l<r)
00540 {
00541 size_type q = (l+r)/2;
00542 if (i <= j[q]) r=q;
00543 else l = q+1;
00544 }
00545 if (j[l]!=i) DUNE_THROW(ISTLError,"index not in compressed array");
00546 return p[l];
00547 }
00548
00550 template<class T>
00551 class RealIterator
00552 : public BidirectionalIteratorFacade<RealIterator<T>, T>
00553 {
00554 public:
00556 typedef typename remove_const<T>::type ValueType;
00557
00558 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
00559 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
00560 friend class RealIterator<const ValueType>;
00561 friend class RealIterator<ValueType>;
00562
00564 RealIterator ()
00565 : p(0), j(0), i(0)
00566 {}
00567
00569 RealIterator (B* _p, size_type* _j, size_type _i)
00570 : p(_p), j(_j), i(_i)
00571 { }
00572
00576 RealIterator(const RealIterator<ValueType>& it)
00577 : p(it.p), j(it.j), i(it.i)
00578 {}
00579
00580
00582 bool equals (const RealIterator<ValueType>& it) const
00583 {
00584 assert(p==it.p);
00585 return (i)==(it.i);
00586 }
00587
00589 bool equals (const RealIterator<const ValueType>& it) const
00590 {
00591 assert(p==it.p);
00592 return (i)==(it.i);
00593 }
00594
00595
00597 size_type index () const
00598 {
00599 return j[i];
00600 }
00601
00603 void setindex (size_type k)
00604 {
00605 return j[i] = k;
00606 }
00607
00615 size_type offset () const
00616 {
00617 return i;
00618 }
00619
00620 private:
00622 void increment()
00623 {
00624 ++i;
00625 }
00626
00628 void decrement()
00629 {
00630 --i;
00631 }
00632
00634 B& dereference () const
00635 {
00636 return p[i];
00637 }
00638
00639 B* p;
00640 size_type* j;
00641 size_type i;
00642 };
00643
00645 typedef RealIterator<B> iterator;
00646
00648 iterator begin ()
00649 {
00650 return iterator(p,j,0);
00651 }
00652
00654 iterator end ()
00655 {
00656 return iterator(p,j,n);
00657 }
00658
00660 iterator rbegin ()
00661 {
00662 return iterator(p,j,n-1);
00663 }
00664
00666 iterator rend ()
00667 {
00668 return iterator(p,j,-1);
00669 }
00670
00672 iterator find (size_type i)
00673 {
00674 size_type l=0, r=n-1;
00675 while (l<r)
00676 {
00677 size_type q = (l+r)/2;
00678 if (i <= j[q]) r=q;
00679 else l = q+1;
00680 }
00681
00682 if (n && i==j[l])
00683 return iterator(p,j,l);
00684 else
00685 return iterator(p,j,n);
00686 }
00687
00689 typedef RealIterator<const B> const_iterator;
00690
00692 const_iterator begin () const
00693 {
00694 return const_iterator(p,j,0);
00695 }
00696
00698 const_iterator end () const
00699 {
00700 return const_iterator(p,j,n);
00701 }
00702
00704 const_iterator rbegin () const
00705 {
00706 return const_iterator(p,j,n-1);
00707 }
00708
00710 const_iterator rend () const
00711 {
00712 return const_iterator(p,j,-1);
00713 }
00714
00716 const_iterator find (size_type i) const
00717 {
00718 size_type l=0, r=n-1;
00719 while (l<r)
00720 {
00721 size_type q = (l+r)/2;
00722 if (i <= j[q]) r=q;
00723 else l = q+1;
00724 }
00725
00726 if (n && i==j[l])
00727 return const_iterator(p,j,l);
00728 else
00729 return const_iterator(p,j,n);
00730 }
00731
00732
00733
00735 size_type size () const
00736 {
00737 return n;
00738 }
00739
00740 protected:
00742 compressed_base_array_unmanaged ()
00743 : n(0), p(0), j(0)
00744 {}
00745
00746 size_type n;
00747 B *p;
00748 size_type* j;
00749 };
00750
00751 }
00752
00753 #endif