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) 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         //===== sizes
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;  // number of elements in array
00757         B *p;   // pointer to dynamically allocated built-in array
00758         size_type* j; // the index set
00759   };
00760 
00761 } // end namespace
00762 
00763 #endif

Generated on Sun Nov 15 22:29:35 2009 for dune-istl by  doxygen 1.5.6