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) DUNE_THROW(ISTLError,"index not in compressed array");
00542 return p[l];
00543 }
00544
00546 const B& operator[] (size_type i) const
00547 {
00548 size_type l=0, r=n-1;
00549 while (l<r)
00550 {
00551 size_type q = (l+r)/2;
00552 if (i <= j[q]) r=q;
00553 else l = q+1;
00554 }
00555 if (j[l]!=i) DUNE_THROW(ISTLError,"index not in compressed array");
00556 return p[l];
00557 }
00558
00560 template<class T>
00561 class RealIterator
00562 : public BidirectionalIteratorFacade<RealIterator<T>, T>
00563 {
00564 public:
00566 typedef typename remove_const<T>::type ValueType;
00567
00568 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
00569 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
00570 friend class RealIterator<const ValueType>;
00571 friend class RealIterator<ValueType>;
00572
00574 RealIterator ()
00575 : p(0), j(0), i(0)
00576 {}
00577
00579 RealIterator (B* _p, size_type* _j, size_type _i)
00580 : p(_p), j(_j), i(_i)
00581 { }
00582
00586 RealIterator(const RealIterator<ValueType>& it)
00587 : p(it.p), j(it.j), i(it.i)
00588 {}
00589
00590
00592 bool equals (const RealIterator<ValueType>& it) const
00593 {
00594 assert(p==it.p);
00595 return (i)==(it.i);
00596 }
00597
00599 bool equals (const RealIterator<const ValueType>& it) const
00600 {
00601 assert(p==it.p);
00602 return (i)==(it.i);
00603 }
00604
00605
00607 size_type index () const
00608 {
00609 return j[i];
00610 }
00611
00613 void setindex (size_type k)
00614 {
00615 return j[i] = k;
00616 }
00617
00625 size_type offset () const
00626 {
00627 return i;
00628 }
00629
00630 private:
00632 void increment()
00633 {
00634 ++i;
00635 }
00636
00638 void decrement()
00639 {
00640 --i;
00641 }
00642
00644 B& dereference () const
00645 {
00646 return p[i];
00647 }
00648
00649 B* p;
00650 size_type* j;
00651 size_type i;
00652 };
00653
00655 typedef RealIterator<B> iterator;
00656
00658 iterator begin ()
00659 {
00660 return iterator(p,j,0);
00661 }
00662
00664 iterator end ()
00665 {
00666 return iterator(p,j,n);
00667 }
00668
00670 iterator rbegin ()
00671 {
00672 return iterator(p,j,n-1);
00673 }
00674
00676 iterator rend ()
00677 {
00678 return iterator(p,j,-1);
00679 }
00680
00682 iterator find (size_type i)
00683 {
00684 size_type l=0, r=n-1;
00685 while (l<r)
00686 {
00687 size_type q = (l+r)/2;
00688 if (i <= j[q]) r=q;
00689 else l = q+1;
00690 }
00691
00692 if (n && i==j[l])
00693 return iterator(p,j,l);
00694 else
00695 return iterator(p,j,n);
00696 }
00697
00699 typedef RealIterator<const B> const_iterator;
00700
00702 const_iterator begin () const
00703 {
00704 return const_iterator(p,j,0);
00705 }
00706
00708 const_iterator end () const
00709 {
00710 return const_iterator(p,j,n);
00711 }
00712
00714 const_iterator rbegin () const
00715 {
00716 return const_iterator(p,j,n-1);
00717 }
00718
00720 const_iterator rend () const
00721 {
00722 return const_iterator(p,j,-1);
00723 }
00724
00726 const_iterator find (size_type i) const
00727 {
00728 size_type l=0, r=n-1;
00729 while (l<r)
00730 {
00731 size_type q = (l+r)/2;
00732 if (i <= j[q]) r=q;
00733 else l = q+1;
00734 }
00735
00736 if (n && i==j[l])
00737 return const_iterator(p,j,l);
00738 else
00739 return const_iterator(p,j,n);
00740 }
00741
00742
00743
00745 size_type size () const
00746 {
00747 return n;
00748 }
00749
00750 protected:
00752 compressed_base_array_unmanaged ()
00753 : n(0), p(0), j(0)
00754 {}
00755
00756 size_type n;
00757 B *p;
00758 size_type* j;
00759 };
00760
00761 }
00762
00763 #endif