Generated on Wed Jan 4 17:49:15 2006 for Gecode by doxygen 1.4.6

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: 2005-12-01 17:56:17 +0100 (Thu, 01 Dec 2005) $ by $Author: tack $
00010  *     $Revision: 2676 $
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 "kernel.hh"
00026 
00027 #include <algorithm>
00028 
00029 namespace Gecode { namespace Support {
00030 
00040   template <class T>
00041   class SharedArray {
00042   private:
00044     class Object {
00045     public:
00047       unsigned int use;
00049       int n;
00051       T   a[1];
00052       
00054       static Object* allocate(int n);
00056       Object* copy(void) const;
00057       
00059       void subscribe(void);
00061       void release(void);
00062     };
00064     Object* sao;
00065   public:
00067     SharedArray(void);
00069     SharedArray(int n);
00071     SharedArray(const SharedArray<T>& a);
00073     const SharedArray& operator=(const SharedArray&);
00074 
00076     void update(bool share, SharedArray& a);
00077 
00079     ~SharedArray(void);
00080 
00082     T& operator[](int i);
00084     const T& operator[](int i) const;
00085 
00087     int size(void) const;
00089     void size(int n);
00090 
00092     void shrink(int n);
00094     void ensure(int n);
00095   };
00096 
00097 
00098   template <class T>
00099   forceinline typename SharedArray<T>::Object*
00100   SharedArray<T>::Object::allocate(int n) {
00101     assert(n>0);
00102     Object* o = reinterpret_cast<Object*>
00103       (Memory::malloc(sizeof(T)*(n-1) + sizeof(Object)));
00104     o->use = 1;
00105     o->n   = n;
00106     return o;
00107   }
00108 
00109   template <class T>
00110   forceinline typename SharedArray<T>::Object*
00111   SharedArray<T>::Object::copy(void) const {
00112     assert(n>0);
00113     Object* o = allocate(n);
00114     for (int i=n; i--;)
00115       o->a[i] = a[i];
00116     return o;
00117   }
00118 
00119   template <class T>
00120   forceinline void
00121   SharedArray<T>::Object::subscribe(void) {
00122     use++;
00123   }
00124 
00125   template <class T>
00126   forceinline void
00127   SharedArray<T>::Object::release(void) {
00128     if (--use == 0) 
00129       Memory::free(this);
00130   }
00131 
00132 
00133   template <class T>
00134   forceinline
00135   SharedArray<T>::SharedArray(void) : sao(NULL) {}
00136 
00137   template <class T>
00138   forceinline
00139   SharedArray<T>::SharedArray(int n) {
00140     sao = (n>0) ? Object::allocate(n) : NULL;
00141   }
00142   template <class T>
00143   forceinline
00144   SharedArray<T>::SharedArray(const SharedArray<T>& a) {
00145     sao = a.sao;
00146     if (sao != NULL)
00147       sao->subscribe();
00148   }
00149 
00150   template <class T>
00151   forceinline
00152   SharedArray<T>::~SharedArray(void) {
00153     if (sao != NULL)
00154       sao->release();
00155   }
00156 
00157   template <class T>
00158   forceinline const SharedArray<T>&
00159   SharedArray<T>::operator=(const SharedArray<T>& a) {
00160     if (this != &a) {
00161       if (sao != NULL)
00162         sao->release();
00163       sao = a.sao;
00164       if (sao != NULL)
00165         sao->subscribe();
00166     }
00167     return *this;
00168   }
00169 
00170   template <class T>
00171   inline void
00172   SharedArray<T>::update(bool share, SharedArray<T>& a) {
00173     if (sao != NULL)
00174       sao->release();
00175     if (share) {
00176       sao = a.sao;
00177       if (sao != NULL)
00178         sao->subscribe();
00179     } else {
00180       sao = (a.sao == NULL) ? NULL : a.sao->copy();
00181     }
00182   }
00183 
00184   template <class T>
00185   forceinline T&
00186   SharedArray<T>::operator[](int i) {
00187     return sao->a[i];
00188   }
00189 
00190   template <class T>
00191   forceinline const T&
00192   SharedArray<T>::operator[](int i) const {
00193     return sao->a[i];
00194   }
00195 
00196   template <class T>
00197   forceinline int
00198   SharedArray<T>::size(void) const {
00199     return (sao == NULL) ? 0 : sao->n;
00200   }
00201 
00202   template <class T>
00203   forceinline void
00204   SharedArray<T>::size(int n) {
00205     if (n==0) {
00206       if (sao != NULL)
00207         sao->release();
00208       sao = NULL;
00209     } else {
00210       sao->n = n;
00211     }
00212   }
00213 
00214   template <class T>
00215   inline void
00216   SharedArray<T>::shrink(int n) {
00217     assert(n < sao->n);
00218     Object* nsao = Object::allocate(n);
00219     for (int i = n; i--; )
00220       nsao->a[i] = sao->a[i];
00221     sao->release();
00222     sao = nsao;
00223   }
00224 
00225   template <class T>
00226   inline void
00227   SharedArray<T>::ensure(int n) {
00228     if (sao == NULL) {
00229       if (n>0)
00230         sao = Object::allocate(n);
00231       return;
00232     }
00233     if (n >= sao->n) {
00234       int m = std::max(2*sao->n,n);
00235       Object* nsao = Object::allocate(m);
00236       for (int i = sao->n; i--; )
00237         nsao->a[i] = sao->a[i];
00238       sao->release();
00239       sao = nsao;
00240     }
00241   }
00242 
00243 }}
00244 
00245 #endif
00246 
00247 // STATISTICS: support-any