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 RandomAccessIteratorFacade<RealIterator<T>, T>
00078 {
00079 public:
00081 typedef typename remove_const<T>::type ValueType;
00082
00083 friend class RandomAccessIteratorFacade<RealIterator<const ValueType>, const ValueType>;
00084 friend class RandomAccessIteratorFacade<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 std::ptrdiff_t distanceTo(const RealIterator& o) const
00121 {
00122 return o.i-i;
00123 }
00124
00125 private:
00127 void increment()
00128 {
00129 ++i;
00130 }
00131
00133 void decrement()
00134 {
00135 --i;
00136 }
00137
00139 B& dereference () const
00140 {
00141 return *i;
00142 }
00143
00144 void advance(std::ptrdiff_t d)
00145 {
00146 i+=d;
00147 }
00148
00149 const B* p;
00150 B* i;
00151 };
00152
00154 typedef RealIterator<B> iterator;
00155
00156
00158 iterator begin ()
00159 {
00160 return iterator(p,p);
00161 }
00162
00164 iterator end ()
00165 {
00166 return iterator(p,p+n);
00167 }
00168
00170 iterator rbegin ()
00171 {
00172 return iterator(p,p+n-1);
00173 }
00174
00176 iterator rend ()
00177 {
00178 return iterator(p,p-1);
00179 }
00180
00182 iterator find (size_type i)
00183 {
00184 if (i<n)
00185 return iterator(p,p+i);
00186 else
00187 return iterator(p,p+n);
00188 }
00189
00191 typedef RealIterator<const B> const_iterator;
00192
00194 const_iterator begin () const
00195 {
00196 return const_iterator(p,p+0);
00197 }
00198
00200 const_iterator end () const
00201 {
00202 return const_iterator(p,p+n);
00203 }
00204
00206 const_iterator rbegin () const
00207 {
00208 return const_iterator(p,p+n-1);
00209 }
00210
00212 const_iterator rend () const
00213 {
00214 return const_iterator(p,p-1);
00215 }
00216
00218 const_iterator find (size_type i) const
00219 {
00220 if (i<n)
00221 return const_iterator(p,p+i);
00222 else
00223 return const_iterator(p,p+n);
00224 }
00225
00226
00227
00228
00230 size_type size () const
00231 {
00232 return n;
00233 }
00234
00235 protected:
00237 base_array_unmanaged ()
00238 : n(0), p(0)
00239 {}
00241 base_array_unmanaged (size_type n_, B* p_)
00242 : n(n_), p(p_)
00243 {}
00244 size_type n;
00245 B *p;
00246 };
00247
00248
00249
00264 template<class B, class A=ISTLAllocator>
00265 class base_array_window : public base_array_unmanaged<B,A>
00266 {
00267 public:
00268
00269
00270
00272 typedef B member_type;
00273
00275 typedef A allocator_type;
00276
00278 typedef typename base_array_unmanaged<B,A>::iterator iterator;
00279
00281 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator;
00282
00284 typedef typename base_array_unmanaged<B,A>::size_type size_type;
00285
00287 typedef typename A::difference_type difference_type;
00288
00289
00290
00292 base_array_window ()
00293 : base_array_unmanaged<B,A>()
00294 { }
00295
00297 base_array_window (B* _p, size_type _n)
00298 : base_array_unmanaged<B,A>(_n ,_p)
00299 {}
00300
00301
00302
00304 void set (size_type _n, B* _p)
00305 {
00306 this->n = _n;
00307 this->p = _p;
00308 }
00309
00311 void advance (difference_type newsize)
00312 {
00313 this->p += this->n;
00314 this->n = newsize;
00315 }
00316
00318 void move (difference_type offset, size_type newsize)
00319 {
00320 this->p += offset;
00321 this->n = newsize;
00322 }
00323
00325 void move (difference_type offset)
00326 {
00327 this->p += offset;
00328 }
00329
00331 B* getptr ()
00332 {
00333 return this->p;
00334 }
00335 };
00336
00337
00338
00354 template<class B, class A=ISTLAllocator>
00355 class base_array : public base_array_unmanaged<B,A>
00356 {
00357 public:
00358
00359
00360
00362 typedef B member_type;
00363
00365 typedef A allocator_type;
00366
00368 typedef typename base_array_unmanaged<B,A>::iterator iterator;
00369
00371 typedef typename base_array_unmanaged<B,A>::const_iterator const_iterator;
00372
00374 typedef typename base_array_unmanaged<B,A>::size_type size_type;
00375
00377 typedef typename A::difference_type difference_type;
00378
00379
00380
00382 base_array ()
00383 : base_array_unmanaged<B,A>()
00384 {}
00385
00387 base_array (size_type _n)
00388 : base_array_unmanaged<B,A>(_n, 0)
00389 {
00390 if (this->n>0)
00391 this->p = A::template malloc<B>(this->n);
00392 else
00393 {
00394 this->n = 0;
00395 this->p = 0;
00396 }
00397 }
00398
00400 base_array (const base_array& a)
00401 {
00402
00403 this->n = a.n;
00404
00405 if (this->n>0)
00406 this->p = A::template malloc<B>(this->n);
00407 else
00408 {
00409 this->n = 0;
00410 this->p = 0;
00411 }
00412
00413
00414 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00415 }
00416
00418 base_array (const base_array_unmanaged<B,A>& _a)
00419 {
00420 const base_array& a = static_cast<const base_array&>(_a);
00421
00422
00423 this->n = a.n;
00424 if (this->n>0)
00425 this->p = A::template malloc<B>(this->n);
00426 else
00427 {
00428 this->n = 0;
00429 this->p = 0;
00430 }
00431
00432
00433 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00434 }
00435
00436
00438 ~base_array ()
00439 {
00440 if (this->n>0) A::template free<B>(this->p);
00441 }
00442
00444 void resize (size_type _n)
00445 {
00446 if (this->n==_n) return;
00447
00448 if (this->n>0) A::template free<B>(this->p);
00449 this->n = _n;
00450 if (this->n>0)
00451 this->p = A::template malloc<B>(this->n);
00452 else
00453 {
00454 this->n = 0;
00455 this->p = 0;
00456 }
00457 }
00458
00460 base_array& operator= (const base_array& a)
00461 {
00462 if (&a!=this)
00463 {
00464
00465 if (this->n!=a.n)
00466 {
00467 if (this->n>0) A::template free<B>(this->p);
00468 this->n = a.n;
00469 if (this->n>0)
00470 this->p = A::template malloc<B>(this->n);
00471 else
00472 {
00473 this->n = 0;
00474 this->p = 0;
00475 }
00476 }
00477
00478 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00479 }
00480 return *this;
00481 }
00482
00484 base_array& operator= (const base_array_unmanaged<B,A>& a)
00485 {
00486 return this->operator=(static_cast<const base_array&>(a));
00487 }
00488
00489 };
00490
00491
00492
00493
00513 template<class B, class A=ISTLAllocator>
00514 class compressed_base_array_unmanaged
00515 {
00516 public:
00517
00518
00519
00521 typedef B member_type;
00522
00524 typedef A allocator_type;
00525
00527 typedef typename A::size_type size_type;
00528
00529
00530
00532 B& operator[] (size_type i)
00533 {
00534 size_type l=0, r=n-1;
00535 while (l<r)
00536 {
00537 size_type q = (l+r)/2;
00538 if (i <= j[q]) r=q;
00539 else l = q+1;
00540 }
00541 if (j[l]!=i){
00542 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
00543 }
00544 return p[l];
00545 }
00546
00548 const B& operator[] (size_type i) const
00549 {
00550 size_type l=0, r=n-1;
00551 while (l<r)
00552 {
00553 size_type q = (l+r)/2;
00554 if (i <= j[q]) r=q;
00555 else l = q+1;
00556 }
00557 if (j[l]!=i){
00558 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
00559 }
00560 return p[l];
00561 }
00562
00564 template<class T>
00565 class RealIterator
00566 : public BidirectionalIteratorFacade<RealIterator<T>, T>
00567 {
00568 public:
00570 typedef typename remove_const<T>::type ValueType;
00571
00572 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
00573 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
00574 friend class RealIterator<const ValueType>;
00575 friend class RealIterator<ValueType>;
00576
00578 RealIterator ()
00579 : p(0), j(0), i(0)
00580 {}
00581
00583 RealIterator (B* _p, size_type* _j, size_type _i)
00584 : p(_p), j(_j), i(_i)
00585 { }
00586
00590 RealIterator(const RealIterator<ValueType>& it)
00591 : p(it.p), j(it.j), i(it.i)
00592 {}
00593
00594
00596 bool equals (const RealIterator<ValueType>& it) const
00597 {
00598 assert(p==it.p);
00599 return (i)==(it.i);
00600 }
00601
00603 bool equals (const RealIterator<const ValueType>& it) const
00604 {
00605 assert(p==it.p);
00606 return (i)==(it.i);
00607 }
00608
00609
00611 size_type index () const
00612 {
00613 return j[i];
00614 }
00615
00617 void setindex (size_type k)
00618 {
00619 return j[i] = k;
00620 }
00621
00629 size_type offset () const
00630 {
00631 return i;
00632 }
00633
00634 private:
00636 void increment()
00637 {
00638 ++i;
00639 }
00640
00642 void decrement()
00643 {
00644 --i;
00645 }
00646
00648 B& dereference () const
00649 {
00650 return p[i];
00651 }
00652
00653 B* p;
00654 size_type* j;
00655 size_type i;
00656 };
00657
00659 typedef RealIterator<B> iterator;
00660
00662 iterator begin ()
00663 {
00664 return iterator(p,j,0);
00665 }
00666
00668 iterator end ()
00669 {
00670 return iterator(p,j,n);
00671 }
00672
00674 iterator rbegin ()
00675 {
00676 return iterator(p,j,n-1);
00677 }
00678
00680 iterator rend ()
00681 {
00682 return iterator(p,j,-1);
00683 }
00684
00686 iterator find (size_type i)
00687 {
00688 size_type l=0, r=n-1;
00689 while (l<r)
00690 {
00691 size_type q = (l+r)/2;
00692 if (i <= j[q]) r=q;
00693 else l = q+1;
00694 }
00695
00696 if (n && i==j[l])
00697 return iterator(p,j,l);
00698 else
00699 return iterator(p,j,n);
00700 }
00701
00703 typedef RealIterator<const B> const_iterator;
00704
00706 const_iterator begin () const
00707 {
00708 return const_iterator(p,j,0);
00709 }
00710
00712 const_iterator end () const
00713 {
00714 return const_iterator(p,j,n);
00715 }
00716
00718 const_iterator rbegin () const
00719 {
00720 return const_iterator(p,j,n-1);
00721 }
00722
00724 const_iterator rend () const
00725 {
00726 return const_iterator(p,j,-1);
00727 }
00728
00730 const_iterator find (size_type i) const
00731 {
00732 size_type l=0, r=n-1;
00733 while (l<r)
00734 {
00735 size_type q = (l+r)/2;
00736 if (i <= j[q]) r=q;
00737 else l = q+1;
00738 }
00739
00740 if (n && i==j[l])
00741 return const_iterator(p,j,l);
00742 else
00743 return const_iterator(p,j,n);
00744 }
00745
00746
00747
00749 size_type size () const
00750 {
00751 return n;
00752 }
00753
00754 protected:
00756 compressed_base_array_unmanaged ()
00757 : n(0), p(0), j(0)
00758 {}
00759
00760 size_type n;
00761 B *p;
00762 size_type* j;
00763 };
00764
00765 }
00766
00767 #endif