00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __loaded__array_meta_h__
00021 #define __loaded__array_meta_h__
00022 using namespace std;
00023 #line 1 "array-meta.h++"
00024 #include <cstdio>
00025 #include "array-storage.h"
00026 #include "coordinates.h"
00027
00028
00029
00030
00031 template <int D, class T> class ArrayMeta
00032 {
00033 int refcount;
00034 long setSize(const Size<D> & s);
00035 public:
00036 ArrayStorage<T> * storage;
00037 T * offset;
00038 Size<D> size;
00039 Delta<D> delta;
00040
00041 ArrayMeta(Size<D> size);
00042 ArrayMeta(ArrayMeta<D,T> *other, const From<D> &from);
00043
00049 ArrayMeta(ArrayStorage<T> * store, const Size<D> &size_to)
00050 {
00051 refcount=1;
00052 assert(store);
00053 storage = store;
00054 offset = storage->data;
00055 setSize(size_to);
00056 }
00057
00062 ArrayMeta(ArrayMeta<D,T> *other, const Size<D> &sized_to);
00063 ArrayMeta(ArrayMeta<D,T> *other, const To<D> &to);
00064 ArrayMeta(ArrayMeta<D,T> *other, const From<D> & from,
00065 const Size<D> &sized_to);
00066 ArrayMeta(ArrayMeta<D,T> *other, const From<D> & from, const To<D> &to);
00067 ArrayMeta(const ArrayMeta&)
00068 {
00069 assert(0);
00070 };
00075 template <int O> ArrayMeta(const ArrayMeta<O,T>& o);
00080 template <int O> ArrayMeta(const ArrayMeta<O,T>& o,
00081 const Select<D> & selected);
00082 ArrayMeta &operator = (const ArrayMeta&)
00083 {
00084 assert(0);
00085 return *this;
00086 };
00087 ~ArrayMeta()
00088 {
00089 deref();
00090 };
00091 void deref()
00092 {
00093 if (--storage->refcount==0)
00094 delete storage;
00095 };
00096 void incref()
00097 {
00098 refcount++;
00099 }
00100 bool decref()
00101 {
00102 return --refcount==0;
00103 }
00104 void replaceAccess(ArrayMeta<D,T> *other);
00105 void setAddress(T * start)
00106 {
00107 offset = start;
00108 };
00109 T * address(const Position<D> & c);
00110 T * address(const From<D> & c);
00111 void printMetaInfo();
00112 };
00113
00114 template <int D, class T>
00115 void ArrayMeta<D,T>::replaceAccess(ArrayMeta<D,T> *other)
00116 {
00117 other->storage->refcount++;
00118 deref();
00119 storage=other->storage;
00120 offset = other->offset;
00121 size = other->size;
00122 delta = other->delta;
00123 }
00124
00125 template <int D, class T>
00126 void ArrayMeta<D,T>::printMetaInfo()
00127 {
00128 printf( " Size: "); size.print();
00129 printf("\n Delta: "); delta.print();
00130 printf("\n Refcount: %d", storage->refcount);
00131 printf("\n Offset: %d\n",offset-storage->data);
00132 }
00133
00134 template <int D, class T>
00135 T * ArrayMeta<D,T>::address(const Position<D> & c)
00136 {
00137 T* result = offset;
00138 iterate_dimensions(d,D,result+=c[d]*delta[d]);
00139 return result;
00140 }
00141
00142 template <int D, class T>
00143 T * ArrayMeta<D,T>::address(const From<D> & c)
00144 {
00145 T* result = offset;
00146 iterate_dimensions(d,D,result+=c[d]*delta[d]);
00147 return result;
00148 }
00149
00150 template <int D, class T>
00151 ArrayMeta<D,T>::ArrayMeta(Size<D> size)
00152 {
00153 refcount = 1;
00154 long totsiz = setSize(size);
00155 NormalArrayStorage<T> * nas = new NormalArrayStorage<T>(totsiz);
00156 storage = nas;
00157 offset = storage->data;
00158 }
00159
00160 template <int D, class T> ArrayMeta<D,T>::ArrayMeta(ArrayMeta<D,T> * other,
00161 const From<D> &from)
00162 {
00163 refcount = 1;
00164 other->storage->refcount++;
00165 storage=other->storage;
00166 offset = other->offset;
00167 size = other->size;
00168 delta = other->delta;
00169 offset=address(from);
00170 size-=from;
00171 }
00172
00173 template <int D, class T>
00174 ArrayMeta<D,T>::ArrayMeta(ArrayMeta<D,T> * other, const Size<D> &to)
00175 {
00176 refcount = 1;
00177 other->storage->refcount++;
00178 storage = other->storage;
00179 offset = other->offset;
00180 delta = other->delta;
00181 size.set(to);
00182 }
00183
00184 template <int D, class T>
00185 ArrayMeta<D,T>::ArrayMeta(ArrayMeta<D,T> * other, const To<D> &to)
00186 {
00187 refcount = 1;
00188 other->storage->refcount++;
00189 storage = other->storage;
00190 offset = other->offset;
00191 delta = other->delta;
00192 size.set(to);
00193 size += 1;
00194 }
00195
00196 template <int D, class T>
00197 ArrayMeta<D,T>::ArrayMeta(ArrayMeta<D,T> * other, const From<D> &from,
00198 const Size<D> &sized)
00199 {
00200 refcount = 1;
00201 other->storage->refcount++;
00202 storage = other->storage;
00203 offset = other->offset;
00204 size = sized;
00205 delta = other->delta;
00206 offset = address(from);
00207 }
00208
00209 template <int D, class T>
00210 ArrayMeta<D,T>::ArrayMeta(ArrayMeta<D,T> * other, const From<D> &from,
00211 const To<D> &to)
00212 {
00213 refcount = 1;
00214 other->storage->refcount++;
00215 storage = other->storage;
00216 offset = other->offset;
00217 size.set(to);
00218 size -= from;
00219 size += 1;
00220 delta = other->delta;
00221 offset = address(from);
00222 }
00223
00224 template <int D, class T>
00225 template <int O>
00226 ArrayMeta<D,T>::ArrayMeta(const ArrayMeta<O,T>& o, const Select<D> & selected)
00227 {
00228 refcount = 1;
00229 o.storage->refcount++;
00230 storage = o.storage;
00231 offset = o.offset;
00232 assert(D<=O);
00233 for(int i = 0 ; i < D ; i ++)
00234 {
00235 int d = selected[i];
00236 assert(d<O);
00237 delta[i] = o.delta[d];
00238 size[i] = o.size[d];
00239 }
00240 }
00241
00242 template <int D, class T>
00243 template <int O>
00244 ArrayMeta<D,T>::ArrayMeta(const ArrayMeta<O,T>& o)
00245 {
00246 assert(O<D);
00247 refcount = 1;
00248 o.storage->refcount++;
00249 storage = o.storage;
00250 offset = o.offset;
00251 int stride=1;
00252 for(int i = 0 ; i < O ; i ++)
00253 {
00254 delta[i+D-O] = o.delta[i];
00255 size[i+D-O] = o.size[i];
00256 stride*=o.delta[i];
00257 }
00258 for(int i = 0 ; i < D-O ; i++)
00259 {
00260 size[i]=1;
00261 delta[i]=stride;
00262 }
00263 }
00264
00265 template <int D, class T> long ArrayMeta<D,T>::setSize(const Size<D> & s)
00266 {
00267 long int totsize = 1;
00268 size = s;
00269 for(int i = D-1 ; i >=0 ; i --)
00270 {
00271 delta[i]=totsize;
00272 totsize*=s[i];
00273 };
00274 return totsize;
00275 }
00276 #endif // __loaded__array_meta_h__