shared-array.hh
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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