basearray.hh

Go to the documentation of this file.
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         //===== type definitions and constants
00043 
00045         typedef B member_type;
00046 
00048         typedef A allocator_type;
00049 
00051     typedef typename A::size_type size_type;
00052     
00053 
00054         //===== access to components
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         //===== sizes
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; // number of elements in array
00235         B *p;  // pointer to dynamically allocated built-in array
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         //===== type definitions and constants
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         //===== constructors and such
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         //===== window manipulation methods
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         //===== type definitions and constants
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         //===== constructors and such
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           // allocate memory with same size as a
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           // and copy elements
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           // allocate memory with same size as a
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           // and copy elements
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) // check if this and a are different objects
00453                 {
00454                   // adjust size of array
00455                   if (this->n!=a.n) // check if size is different
00456                         {
00457                           if (this->n>0) A::template free<B>(this->p); // delete old memory
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                   // copy data
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         //===== type definitions and constants
00509 
00511         typedef B member_type;
00512 
00514         typedef A allocator_type;
00515 
00517     typedef typename A::size_type size_type;
00518 
00519         //===== access to components
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         //===== sizes
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;  // number of elements in array
00747         B *p;   // pointer to dynamically allocated built-in array
00748         size_type* j; // the index set
00749   };
00750 
00751 } // end namespace
00752 
00753 #endif

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].