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 "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