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 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         //===== sizes
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; // number of elements in array
00245         B *p;  // pointer to dynamically allocated built-in array
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         //===== type definitions and constants
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         //===== constructors and such
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         //===== window manipulation methods
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         //===== type definitions and constants
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         //===== constructors and such
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           // allocate memory with same size as a
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           // and copy elements
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           // allocate memory with same size as a
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           // and copy elements
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) // check if this and a are different objects
00463                 {
00464                   // adjust size of array
00465                   if (this->n!=a.n) // check if size is different
00466                         {
00467                           if (this->n>0) A::template free<B>(this->p); // delete old memory
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                   // copy data
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         //===== type definitions and constants
00519 
00521         typedef B member_type;
00522 
00524         typedef A allocator_type;
00525 
00527     typedef typename A::size_type size_type;
00528 
00529         //===== access to components
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         //===== sizes
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;  // number of elements in array
00761         B *p;   // pointer to dynamically allocated built-in array
00762         size_type* j; // the index set
00763   };
00764 
00765 } // end namespace
00766 
00767 #endif
Generated on Sat Apr 24 11:13:45 2010 for dune-istl by  doxygen 1.6.3