Generated on Wed Nov 1 15:04:48 2006 for Gecode by doxygen 1.4.5

shared-array.hh

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2003
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:05:34 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3514 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #ifndef __GECODE_SUPPORT_SHARED_ARRAY_HH__
00023 #define __GECODE_SUPPORT_SHARED_ARRAY_HH__
00024 
00025 #include "gecode/kernel.hh"
00026 
00027 #include <algorithm>
00028 
00029 namespace Gecode { namespace Support {
00030 
00044   template <class T, bool fd=false>
00045   class SharedArray {
00046   private:
00048     class Object {
00049     public:
00051       unsigned int use;
00053       int n;
00055       T   a[1];
00056 
00058       static Object* allocate(int n);
00060       Object* copy(void) const;
00061 
00063       void subscribe(void);
00065       void release(void);
00066     };
00068     Object* sao;
00069   public:
00071     SharedArray(void);
00073     SharedArray(int n);
00075     SharedArray(const SharedArray<T,fd>& a);
00077     const SharedArray& operator=(const SharedArray&);
00078 
00080     void update(bool share, SharedArray& a);
00081 
00083     ~SharedArray(void);
00084 
00086     T& operator[](int i);
00088     const T& operator[](int i) const;
00089 
00091     int size(void) const;
00093     void size(int n);
00094 
00096     void shrink(int n);
00098     void ensure(int n);
00099   };
00100 
00101 
00102   template <class T, bool fd>
00103   forceinline typename SharedArray<T,fd>::Object*
00104   SharedArray<T,fd>::Object::allocate(int n) {
00105     assert(n>0);
00106     Object* o = reinterpret_cast<Object*>
00107       (Memory::malloc(sizeof(T)*(n-1) + sizeof(Object)));
00108     o->use = 1;
00109     o->n   = n;
00110     return o;
00111   }
00112 
00113   template <class T, bool fd>
00114   forceinline typename SharedArray<T,fd>::Object*
00115   SharedArray<T,fd>::Object::copy(void) const {
00116     assert(n>0);
00117     Object* o = allocate(n);
00118     for (int i=n; i--;)
00119       new (&(o->a[i])) T(a[i]);
00120     return o;
00121   }
00122 
00123   template <class T, bool fd>
00124   forceinline void
00125   SharedArray<T,fd>::Object::subscribe(void) {
00126     use++;
00127   }
00128 
00129   template <class T, bool fd>
00130   forceinline void
00131   SharedArray<T,fd>::Object::release(void) {
00132     if (--use == 0) {
00133       if (fd)
00134         for (int i=n; i--;)
00135           a[i].~T();
00136       Memory::free(this);
00137     }
00138   }
00139 
00140 
00141   template <class T, bool fd>
00142   forceinline
00143   SharedArray<T,fd>::SharedArray(void) : sao(NULL) {}
00144 
00145   template <class T, bool fd>
00146   forceinline
00147   SharedArray<T,fd>::SharedArray(int n) {
00148     sao = (n>0) ? Object::allocate(n) : NULL;
00149   }
00150   template <class T, bool fd>
00151   forceinline
00152   SharedArray<T,fd>::SharedArray(const SharedArray<T,fd>& a) {
00153     sao = a.sao;
00154     if (sao != NULL)
00155       sao->subscribe();
00156   }
00157 
00158   template <class T, bool fd>
00159   forceinline
00160   SharedArray<T,fd>::~SharedArray(void) {
00161     if (sao != NULL)
00162       sao->release();
00163   }
00164 
00165   template <class T, bool fd>
00166   forceinline const SharedArray<T,fd>&
00167   SharedArray<T,fd>::operator=(const SharedArray<T,fd>& a) {
00168     if (this != &a) {
00169       if (sao != NULL)
00170         sao->release();
00171       sao = a.sao;
00172       if (sao != NULL)
00173         sao->subscribe();
00174     }
00175     return *this;
00176   }
00177 
00178   template <class T, bool fd>
00179   inline void
00180   SharedArray<T,fd>::update(bool share, SharedArray<T,fd>& a) {
00181     if (sao != NULL)
00182       sao->release();
00183     if (share) {
00184       sao = a.sao;
00185       if (sao != NULL)
00186         sao->subscribe();
00187     } else {
00188       sao = (a.sao == NULL) ? NULL : a.sao->copy();
00189     }
00190   }
00191 
00192   template <class T, bool fd>
00193   forceinline T&
00194   SharedArray<T,fd>::operator[](int i) {
00195     return sao->a[i];
00196   }
00197 
00198   template <class T, bool fd>
00199   forceinline const T&
00200   SharedArray<T,fd>::operator[](int i) const {
00201     return sao->a[i];
00202   }
00203 
00204   template <class T, bool fd>
00205   forceinline int
00206   SharedArray<T,fd>::size(void) const {
00207     return (sao == NULL) ? 0 : sao->n;
00208   }
00209 
00210   template <class T, bool fd>
00211   forceinline void
00212   SharedArray<T,fd>::size(int n) {
00213     if (n==0) {
00214       if (sao != NULL)
00215         sao->release();
00216       sao = NULL;
00217     } else {
00218       sao->n = n;
00219     }
00220   }
00221 
00222   template <class T, bool fd>
00223   inline void
00224   SharedArray<T,fd>::shrink(int n) {
00225     assert(n < sao->n);
00226     Object* nsao = Object::allocate(n);
00227     for (int i = n; i--; )
00228       new (&(nsao->a[i])) T(sao->a[i]);
00229     sao->release();
00230     sao = nsao;
00231   }
00232 
00233   template <class T, bool fd>
00234   inline void
00235   SharedArray<T,fd>::ensure(int n) {
00236     if (sao == NULL) {
00237       if (n>0)
00238         sao = Object::allocate(n);
00239       return;
00240     }
00241     if (n >= sao->n) {
00242       int m = std::max(2*sao->n,n);
00243       Object* nsao = Object::allocate(m);
00244       for (int i = sao->n; i--; )
00245         new (&(nsao->a[i])) T(sao->a[i]);
00246       sao->release();
00247       sao = nsao;
00248     }
00249   }
00250 
00251 }}
00252 
00253 #endif
00254 
00255 // STATISTICS: support-any