00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016
00017
00031 #ifndef __array_h
00032 #define __array_h
00033
00034 #include <spucconfig.h>
00035
00036 #include <iostream>
00037 namespace SPUC {
00060 template<class T>
00061 class Array {
00062 public:
00064 Array();
00066 Array(int n);
00068 Array(const Array<T> &a);
00070 virtual ~Array();
00071
00073 T &operator()(int i) {
00074
00075 return data[i]; }
00077 T operator()(int i) const {
00078
00079 return data[i]; }
00081 Array<T> operator()(int i1, int i2) const;
00083 Array<T> operator()(const Array<int> &indices) const;
00084
00086 void operator=(T e);
00088 void operator=(const Array<T> &a);
00089
00091
00093
00095
00097
00098
00100 int size() const { return ndata; }
00102 int length() const { return ndata; }
00104 void set_size(int n, bool copy=false);
00106 void set_length(int n, bool copy=false) { set_size(n, copy); }
00107
00109 T shift_right(T e);
00111 Array<T> shift_right(const Array<T> &a);
00113 T shift_left(T e);
00115 Array<T> shift_left(const Array<T> &a);
00117 void swap(int i, int j);
00118
00120 void set_subarray(int i1, int i2, const Array<T> &a);
00122 void set_subarray(int i1, int i2, const T t);
00123
00124
00125 private:
00126 bool in_range(int i) { return ((i<ndata) && (i>=0)); }
00127 int ndata;
00128 T *data;
00129
00130 private:
00131 void alloc(int n);
00132 void free();
00133 };
00134
00135
00136
00137 template<class T>
00138 Array<T>::Array()
00139 {
00140 data = 0;
00141 ndata = 0;
00142 }
00143
00144 template<class T>
00145 Array<T>::Array(int n)
00146 {
00147 alloc(n);
00148 }
00149
00150 template<class T>
00151 Array<T>::Array(const Array<T> &a)
00152 {
00153
00154 data=NULL;
00155 ndata=0;
00156 alloc(a.ndata);
00157 for (int i=0; i<a.ndata; i++)
00158 data[i] = a.data[i];
00159 }
00160
00161 template<class T>
00162 Array<T>::~Array()
00163 {
00164 free();
00165 }
00166
00167 template<class T>
00168 void Array<T>::alloc(int n)
00169 {
00170 if (n == 0) {
00171 data = NULL;
00172 ndata = 0;
00173 }
00174 else {
00175 data = new T[n];
00176
00177 }
00178 ndata = n;
00179 }
00180
00181 template<class T>
00182 void Array<T>::free()
00183 {
00184
00185 delete [] data;
00186
00187 data = 0;
00188 ndata = 0;
00189 }
00190
00191 template<class T>
00192 Array<T> Array<T>::operator()(int i1, int i2) const
00193 {
00194
00195 Array<T> s(i2-i1+1);
00196 int i;
00197
00198 for (i=0; i<s.ndata; i++)
00199 s.data[i] = data[i1+i];
00200
00201 return s;
00202 }
00203
00204 template<class T>
00205 Array<T> Array<T>::operator()(const Array<int> &indices) const
00206 {
00207 Array<T> a(indices.size());
00208
00209 for (int i=0; i<a.size(); i++) {
00210
00211 a(i) = data[indices(i)];
00212 }
00213
00214 return a;
00215 }
00216
00217 template<class T>
00218 void Array<T>::operator=(const Array<T> &a)
00219 {
00220 set_size(a.ndata);
00221 for (int i=0; i<ndata; i++)
00222 data[i] = a.data[i];
00223 }
00224
00225
00226 template<class T>
00227 void Array<T>::operator=(T e)
00228 {
00229 for (int i=0; i<ndata; i++)
00230 data[i] = e;
00231 }
00232
00233
00234 template<class T>
00235 void Array<T>::set_size(int sz, bool copy)
00236 {
00237 int i, min;
00238 T *tmp;
00239
00240 if (ndata == sz)
00241 return;
00242
00243 if (copy) {
00244 tmp = data;
00245 min = ndata < sz ? ndata : sz;
00246 alloc(sz);
00247 for (i=0; i<min; i++)
00248 data[i] = tmp[i];
00249 delete [] tmp;
00250 } else {
00251 free();
00252 alloc(sz);
00253 }
00254 ndata = sz;
00255 }
00256
00257 template<class T>
00258 T Array<T>::shift_right(T x)
00259 {
00260 T ret;
00261
00262
00263 ret = data[ndata-1];
00264 for (int i=ndata-1; i>0; i--)
00265 data[i] = data[i-1];
00266 data[0] = x;
00267
00268 return ret;
00269 }
00270
00271
00272 template<class T>
00273 Array<T> Array<T>::shift_right(const Array<T> &a)
00274 {
00275 int i;
00276 Array<T> out(a.ndata);
00277
00278 it_assert1(a.ndata<=ndata, "Shift Array too large");
00279 for (i=0; i<a.ndata; i++)
00280 out.data[i] = data[ndata-a.ndata+i];
00281 for (i=ndata-1; i>=a.ndata; i--)
00282 data[i] = data[i-a.ndata];
00283 for (i=0; i<a.ndata; i++)
00284 data[i] = a.data[i];
00285
00286 return out;
00287 }
00288
00289 template<class T>
00290 T Array<T>::shift_left(T x)
00291 {
00292 T temp = data[0];
00293
00294 for (int i=0; i<ndata-1; i++)
00295 data[i]=data[i+1];
00296 data[ndata-1] = x;
00297
00298 return temp;
00299 }
00300
00301 template<class T>
00302 Array<T> Array<T>::shift_left(const Array<T> &a)
00303 {
00304 int i;
00305 Array<T> out(a.ndata);
00306
00307 it_assert1(a.ndata<=ndata, "Shift Array too large");
00308 for (i=0; i<a.ndata; i++)
00309 out.data[i] = data[i];
00310 for (i=0; i<ndata-a.ndata; i++) {
00311
00312 data[i] = data[i+a.ndata];
00313 }
00314 for (i=ndata-a.ndata; i<ndata; i++)
00315 data[i] = a.data[i-ndata+a.ndata];
00316
00317 return out;
00318 }
00319
00320 template<class T>
00321 void Array<T>::swap(int i, int j)
00322 {
00323 it_assert1(in_range(i) && in_range(j) , "Shift Array too large");
00324
00325 T temp = data[i];
00326 data[i] = data[j];
00327 data[j] = temp;
00328 }
00329
00330 template<class T>
00331 void Array<T>::set_subarray(int i1, int i2, const Array<T> &a)
00332 {
00333 if (i1 == -1) i1 = ndata-1;
00334 if (i2 == -1) i2 = ndata-1;
00335
00336
00337
00338
00339
00340 memcpy(data+i1, a.data, a.ndata*sizeof(T));
00341 }
00342
00343 template<class T>
00344 void Array<T>::set_subarray(int i1, int i2, const T t)
00345 {
00346 if (i1 == -1) i1 = ndata-1;
00347 if (i2 == -1) i2 = ndata-1;
00348
00349
00350
00351
00352 for (int i=i1;i<=i2;i++)
00353 data[i] = t;
00354 }
00355
00356 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00357
00358
00359 template<class T>
00360 Array<T> concat(const Array<T> &a, const T e)
00361 {
00362 Array<T> temp(a.size()+1);
00363
00364 for (int i=0; i<a.size(); i++)
00365 temp(i) = a(i);
00366 temp(a.size()) = e;
00367
00368 return temp;
00369 }
00370
00371 template<class T>
00372 Array<T> concat(const T e, const Array<T> &a)
00373 {
00374 Array<T> temp(a.size()+1);
00375
00376 temp(0) = e;
00377
00378 for (int i=0; i<a.size(); i++)
00379 temp(i+1) = a(i);
00380
00381 return temp;
00382 }
00383
00384 template<class T>
00385 Array<T> concat(const Array<T> &a1, const Array<T> &a2)
00386 {
00387 int i;
00388 Array<T> temp(a1.size()+a2.size());
00389
00390 for (i=0;i<a1.size();i++) {
00391 temp(i) = a1(i);
00392 }
00393 for (i=0;i<a2.size();i++) {
00394 temp(a1.size()+i) = a2(i);
00395 }
00396 return temp;
00397 }
00398
00399 template<class T>
00400 Array<T> concat(const Array<T> &a1, const Array<T> &a2, const Array<T> &a3)
00401 {
00402
00403 int i;
00404 Array<T> temp(a1.size()+a2.size()+a3.size());
00405
00406 for (i=0;i<a1.size();i++) {
00407 temp(i) = a1(i);
00408 }
00409 for (i=0;i<a2.size();i++) {
00410 temp(a1.size()+i) = a2(i);
00411 }
00412 for (i=0;i<a3.size();i++) {
00413 temp(a1.size()+a2.size()+i) = a3(i);
00414 }
00415 return temp;
00416 }
00417
00418 #endif
00419
00424 #ifdef XXX
00425 template<class T>
00426 inline std::ostream &operator<<(std::ostream &o, const Array<T> &a)
00427 {
00428 o << "{";
00429 for (int i=0; i<a.size()-1; i++)
00430 o << a(i) << " ";
00431 if (a.size() > 0)
00432 o << a(a.size()-1);
00433
00434 o << "}";
00435
00436 return o;
00437 }
00438 #endif
00439 }
00440
00441 #endif // __array_h