OptppArray.h
00001 #ifndef OPTPPARRAY_H
00002 #define OPTPPARRAY_H
00003
00004 #include <iostream>
00005
00006 #include "OptppFatalError.h"
00007
00008 using std::ostream;
00009
00010 namespace OPTPP {
00011
00028 template<class T>
00029 class OptppArray {
00030 public:
00037 OptppArray();
00041 OptppArray(int n);
00042
00047 OptppArray(int n, const T* cOptppArray);
00048
00053 OptppArray(int n, const T& t);
00054
00056 ~OptppArray();
00058 OptppArray(const OptppArray<T>& other);
00060 const OptppArray<T>& operator=(const OptppArray<T>& other);
00061
00063 void resize(int newN);
00065 void reserve(int n);
00067 int reserve() const ;
00068
00070 OptppArray<T>& append(const T& rhs);
00071
00078 T& operator[](int i);
00079 const T& operator[](int i) const;
00080
00087 bool get(int i, T& value) const ;
00088 bool put(int i, const T& value) ;
00089
00093 int length() const;
00100 bool bcast(int sender);
00101 bool send(int tag, int dest);
00102 bool recv(int tag, int src);
00103 private:
00104 T* data_;
00105 int len_;
00106 int reserve_;
00107
00108 void indexCheckCrash(int i) const;
00109 bool indexCheckNoCrash(int i) const;
00110 };
00111
00112
00113
00114 template<class T> ostream& operator<<(ostream& os, const OptppArray<T>& item)
00115 {
00116 const OptppArray<T>& myItem = item;
00117 T myElem;
00118
00119
00120 os << "(";
00121 int ultimate = myItem.length()-1;
00122
00123 for (int i = 0; i < ultimate; ++i) {
00124 myElem = myItem[i];
00125 os << myElem;
00126 os << ", ";
00127 }
00128 if (ultimate >= 0)
00129 os << myItem[ultimate];
00130 os << ")";
00131 return os;
00132 }
00133
00134 inline int bump(int start, int to) {
00135 if (start == 0)
00136 start = 1;
00137 while (start < to)
00138 start *= 2;
00139 return start;
00140 }
00141
00142 template<class T>
00143 OptppArray<T> sliceOptppArray(const OptppArray<OptppArray<T> >& array, int index)
00144 {
00145 OptppArray<T> rtn(array.length());
00146
00147 for (int i=0; i<array.length(); i++)
00148 {
00149 rtn[i] = array[i][index];
00150 }
00151 return rtn;
00152 }
00153
00154
00155
00156
00157 template<class T>
00158 OptppArray<T> tuple(const T& a)
00159 {
00160 OptppArray<T> rtn(1, a);
00161 return rtn;
00162 }
00163
00164 template<class T>
00165 OptppArray<T> tuple(const T& a, const T& b)
00166 {
00167 OptppArray<T> rtn(2);
00168 rtn[0] = a;
00169 rtn[1] = b;
00170 return rtn;
00171 }
00172
00173 template<class T>
00174 OptppArray<T> tuple(const T& a, const T& b, const T& c)
00175 {
00176 OptppArray<T> rtn(3);
00177 rtn[0] = a;
00178 rtn[1] = b;
00179 rtn[2] = c;
00180 return rtn;
00181 }
00182
00183 template<class T>
00184 OptppArray<T> tuple(const T& a, const T& b, const T& c, const T& d)
00185 {
00186 OptppArray<T> rtn(4);
00187 rtn[0] = a;
00188 rtn[1] = b;
00189 rtn[2] = c;
00190 rtn[3] = d;
00191 return rtn;
00192 }
00193
00194 template<class T>
00195 OptppArray<T> tuple(const T& a, const T& b, const T& c, const T& d, const T& e)
00196 {
00197 OptppArray<T> rtn(5);
00198 rtn[0] = a;
00199 rtn[1] = b;
00200 rtn[2] = c;
00201 rtn[3] = d;
00202 rtn[4] = e;
00203 return rtn;
00204 }
00205
00206 template<class T>
00207 OptppArray<T> tuple(const T& a, const T& b, const T& c, const T& d, const T& e,
00208 const T& f)
00209 {
00210 OptppArray<T> rtn(6);
00211 rtn[0] = a;
00212 rtn[1] = b;
00213 rtn[2] = c;
00214 rtn[3] = d;
00215 rtn[4] = e;
00216 rtn[5] = f;
00217 return rtn;
00218 }
00219
00220 template<class T> inline OptppArray<T>::OptppArray()
00221 : data_(0),
00222 len_(0),
00223 reserve_(0)
00224 {
00225 }
00226
00227 template<class T> inline OptppArray<T>::OptppArray(int n)
00228 : data_(0),
00229 len_(n),
00230 reserve_(n)
00231 {
00232 if (len_ < 0)
00233 OptppfatalError("Negative length passed to OptppArray<T>::OptppArray(int n)");
00234 if (len_ > 0)
00235 {
00236 data_ = new T [len_];
00237 if (!data_)
00238 OptppmemoryError("OptppArray constructor out of memory");
00239 }
00240 }
00241
00242 template<class T> inline OptppArray<T>::OptppArray(int n, const T* cOptppArray)
00243 : data_(0),
00244 len_(n),
00245 reserve_(n)
00246 {
00247 if (len_ < 0)
00248 OptppfatalError("Negative lenght passed to OptppArray::OptppArray(n, cOptppArray)");
00249 if (len_ > 0)
00250 {
00251 data_ = new T [len_];
00252 if (!data_)
00253 OptppmemoryError("OptppArray constructor out of memory");
00254 }
00255 for (int i = 0; i < len_; i++) data_[i] = cOptppArray[i];
00256 }
00257
00258 template<class T> inline OptppArray<T>::OptppArray(int n, const T& t)
00259 : data_(0),
00260 len_(n),
00261 reserve_(n)
00262 {
00263 if (len_ < 0)
00264 OptppfatalError("Negative length passed to OptppArray<T>::OptppArray(int n)");
00265 if (len_ > 0)
00266 {
00267 data_ = new T [len_];
00268 if (!data_)
00269 OptppmemoryError("OptppArray constructor out of memory");
00270 }
00271 for (int i = 0; i < len_; ++ i)
00272 data_[i] = t;
00273 }
00274
00275
00276 template<class T> inline OptppArray<T>::OptppArray(const OptppArray<T>& arr)
00277 : data_(0),
00278 len_(arr.len_),
00279 reserve_(arr.len_)
00280 {
00281 if (len_ > 0)
00282 {
00283 data_ = new T [reserve_];
00284 if (!data_)
00285 OptppmemoryError("OptppArray constructor out of memory");
00286 for (int i = 0; i < len_; ++i)
00287 data_[i] = arr.data_[i];
00288 }
00289 }
00290
00291 template<class T> inline OptppArray<T>::~OptppArray()
00292 {
00293 delete [] data_;
00294 }
00295
00296 template<class T>
00297 inline OptppArray<T>& OptppArray<T>::append(const T& rhs)
00298 {
00299 resize(len_+1);
00300 data_[len_-1] = rhs;
00301 return *this;
00302 }
00303
00304 template<class T>
00305 inline const OptppArray<T>& OptppArray<T>::operator=(const OptppArray<T>& arr)
00306 {
00307 if (this != &arr)
00308 {
00309 if (reserve_ < arr.len_)
00310 {
00311 delete [] data_;
00312 data_ = 0;
00313 reserve_ = arr.len_;
00314 if (reserve_ > 0) {
00315 data_ = new T[reserve_];
00316 if (!data_)
00317 OptppmemoryError("OptppArray constructor out of memory");
00318 }
00319 }
00320 len_ = arr.len_;
00321 for (int i = 0; i < len_; ++i)
00322 data_[i] = arr[i];
00323 }
00324 return *this;
00325 }
00326
00327 template<class T>
00328 inline void OptppArray<T>::resize(int newN) {
00329 if (len_ != newN) {
00330 if (newN < 0)
00331 OptppfatalError("Negative length passed to OptppArray<T>::resize(int newN)");
00332 if(newN > reserve_)
00333 reserve(bump(reserve_, newN));
00334 len_ = newN;
00335 }
00336 }
00337
00338 template<class T>
00339 inline int OptppArray<T>::length() const {
00340 return len_;
00341 }
00342
00343 template<class T>
00344 inline void OptppArray<T>::reserve(int N){
00345 if(reserve_ != N){
00346 if(N < 0){
00347 OptppfatalError("Negative length passed to OptppArray<T>::reserve(int N)");
00348 }
00349 if(N < len_){ len_ = N;}
00350 reserve_ = N;
00351 T* oldData = data_;
00352 data_ = 0;
00353 data_ = new T [reserve_];
00354 if (!data_)
00355 OptppmemoryError("OptppArray<T>::reserve(int N) out of memory");
00356 for (int i = 0; i < len_; i++)
00357 data_[i] = oldData[i];
00358 delete [] oldData;
00359 }
00360 }
00361
00362 template<class T>
00363 inline int OptppArray<T>::reserve() const{
00364 return reserve_;
00365 }
00366
00367 template<class T>
00368 inline T& OptppArray<T>::operator[](int i) {
00369 #ifndef NOBOUNDSCHECK
00370 indexCheckCrash(i);
00371 #endif
00372 return data_[i];
00373 }
00374
00375 template<class T>
00376 inline const T& OptppArray<T>::operator[](int i) const {
00377 #ifndef NOBOUNDSCHECK
00378 indexCheckCrash(i);
00379 #endif
00380 return data_[i];
00381 }
00382
00383 template<class T>
00384 inline void OptppArray<T>::indexCheckCrash(int i) const
00385 {
00386 if (i<0 || i>=len_)
00387 OptpprangeError("OptppArray<T>", i, 0, len_-1);
00388 }
00389
00390 template<class T>
00391 inline bool OptppArray<T>::indexCheckNoCrash(int i) const
00392 {
00393 if (i<0 || i>=len_) return false;
00394 return true;
00395 }
00396
00397 template<class T>
00398 inline bool OptppArray<T>::get(int i, T& value) const
00399 {
00400 #ifndef NOBOUNDSCHECK
00401 if (!indexCheckNoCrash(i)) return false;
00402 #endif
00403 value = data_[i];
00404 return true;
00405 }
00406
00407 template<class T>
00408 inline bool OptppArray<T>::put(int i, const T& value)
00409 {
00410 #ifndef NOBOUNDSCHECK
00411 if (!indexCheckNoCrash(i)) return false;
00412 #endif
00413 data_[i]= value;
00414 return true;
00415 }
00416
00417 }
00418
00419 #endif