00001
00002
00003
00004
00005
00006
00007 #ifndef Array_hh
00008 #define Array_hh
00009
00010 #include <cstring>
00011 #include <memory>
00012 #include <iostream>
00013
00014 #include "basics/typedefs.hh"
00015 #include "basics/vectorsMatrices.hh"
00016 #include "basics/exceptions.hh"
00017 #include "basics/pointerOutput.hh"
00018
00019
00020 #define ArrayConstr_D 0
00021 #define ArrayDestr_D 0
00022
00023 namespace concepts {
00024
00025
00026
00029 template<class F>
00030 std::ostream& operator<<(std::ostream& os, std::auto_ptr<F>& a) {
00031 return os << "std::auto_ptr output";
00032 }
00033
00034
00035
00043 template<class F>
00044 class Array {
00045 public:
00047 Array(const uint sz = 0) : data_(sz ? new F[sz] : 0),
00048 size_(sz), n_(sz) {
00049 DEBUGL(ArrayConstr_D, "start: size = " << sz << ", data = " << data_);
00050 }
00057 Array(const uint sz, const F& dft) : data_(sz ? new F[sz] : 0),
00058 size_(sz), n_(sz) {
00059 F* d = data_; for(uint i = size_; i--;) *d++ = dft;
00060 }
00068 Array(const F* dft, const uint sz) : data_(sz ? new F[sz] : 0),
00069 size_(sz), n_(sz) {
00070 memorycpy(data_, dft, sz);
00071 }
00081 Array(const uint sz, const F& first, const F& diff) :
00082 data_(sz ? new F[sz] : 0), size_(sz), n_(sz) {
00083 if (sz > 0) {
00084 F* d = data_, *e = data_;
00085 *d++ = first;
00086 for(uint i = sz - 1; i--;) *d++ = *e++ + diff;
00087 }
00088 }
00094 template<class H>
00095 Array(const Array<H>& a, F fnc(const H&)) : data_(0), size_(0), n_(0) {
00096 apply(a, fnc);
00097 }
00099 Array(const Array<F>& a) : data_(a.n_ ? new F[a.n_] : 0),
00100 size_(a.n_), n_(a.n_) {
00101 std::memcpy(data_, a.data_, n_*sizeof(F));
00102 }
00104 template<class H>
00105 Array(const Array<H>& a) : data_(0), size_(0), n_(0) { *this = a; }
00106
00107 ~Array() {
00108 DEBUGL(ArrayDestr_D, "start: size = " << size_ << ", n = " << n_
00109 << ", data = " << data_);
00110 delete[] data_;
00111 DEBUGL(ArrayDestr_D, "done.");
00112 }
00113
00118 void resize(const uint sz);
00122 void resizePreserve(const uint sz);
00124 void zeros() { std::memset(data_, 0, n_*sizeof(F)); }
00125
00127 operator F*() { return data_; }
00129 operator const F*() const { return data_; }
00130
00132 const F& operator[] (const int i) const {
00133 conceptsAssert3(i < (int)size_, Assertion(),
00134 "i = " << i << ", size = " << size_);
00135 return data_[i];
00136 }
00138 F& operator[] (const int i) {
00139 conceptsAssert3(i < (int)size_, Assertion(),
00140 "i = " << i << ", size = " << size_);
00141 return data_[i];
00142 }
00143
00145 template<class G>
00146 Array<F>& operator*=(const G n) {
00147 F* d = data_;
00148 for(uint i = size_; i--;) *d++ *= n;
00149 return *this;
00150 }
00151
00153 template<class H>
00154 Array<F>& operator*=(const Array<H>& a) {
00155 conceptsAssert(n_ <= a.size(), Assertion());
00156 F* d = data_; const H* e = (const H*)a;
00157 for(uint i = n_; i--;) *d++ *= *e++;
00158 return *this;
00159 }
00160
00162 Array<F>& operator=(const F n) {
00163 F* d = data_; for(uint i = size_; i--;) *d++ = n;
00164 return *this;
00165 }
00167 Array<F>& operator=(const Array<F>& a) {
00168 resize(a.size());
00169 std::memcpy(data_, a.data_, n_*sizeof(F));
00170 return *this;
00171 }
00173 template<class H>
00174 Array<F>& operator=(const Array<H>& a) {
00175 resize(a.size());
00176 F* d = data_; const H* e = (const H*)a;
00177 for(uint i = size_; i--;) *d++ = *e++;
00178 return *this;
00179 }
00181 Array<F>& operator+=(const F n) {
00182 F* d = data_; for(uint i = size_; i--;) *d++ += n;
00183 return *this;
00184 }
00186 template<class H>
00187 Array<F>& operator+=(const Array<H>& a) {
00188 if (size_ == 0 && a.size() > 0) *this = Array<F>(a.size(), F(0));
00189 F* d = data_; const H* e = (const H*)a;
00190 for(uint i = size_; i--;) *d++ += *e++;
00191 return *this;
00192 }
00194 Array<F>& operator-=(const F n) {
00195 F* d = data_; for(uint i = size_; i--;) *d++ -= n;
00196 return *this;
00197 }
00199 template<class H>
00200 Array<F>& operator-=(const Array<H>& a) {
00201 if (size_ == 0 && a.size() > 0) *this = Array<F>(a.size(), F(0));
00202 F* d = data_; const H* e = (const H*)a;
00203 for(uint i = size_; i--;) *d++ -= *e++;
00204 return *this;
00205 }
00207 Array<F> operator-() const {
00208 Array<F> a(size_);
00209 F* d = (F*)a; const F* e = data_;
00210 for(uint i = size_; i--;) *d++ = -*e++;
00211 return a;
00212 }
00215 Array<F>& apply(F& fnc(F&)) {
00216 F* d = data_;
00217 for(uint i = size_; i--;++d) *d = fnc(*d);
00218 return *this;
00219 }
00228 template<class H>
00229 Array<F>& apply(const Array<H>& a, F fnc(const H&)) {
00230 resize(a.size());
00231 F* d = data_; const H* e = (const H*)a;
00232 for(uint i = size_; i--; ++d)
00233 *d = fnc(*e++);
00234 return *this;
00235 }
00244 template<class H>
00245 Array<F>& apply(const Array<H>& a, F fnc(const H&, const F&)) {
00246 resize(a.size());
00247 F* d = data_; const H* e = (const H*)a;
00248 for(uint i = n_; i--;++d) {
00249 *d = fnc(*e++, *d);
00250 }
00251 return *this;
00252 }
00253
00255 uint size() const { return n_; }
00256
00258 uint cursize() const { return size_;}
00259
00261 int memory() const { return size_*sizeof(F); }
00262
00264 Array<F>& reverse();
00265
00266 std::ostream& info(std::ostream& os) const;
00267 protected:
00269 F* data_;
00271 uint size_;
00273 uint n_;
00274 };
00275
00276 template<class F>
00277 void Array<F>::resize(const uint sz) {
00278 if (sz > size_) {
00279 if (size_ > 0) delete[] data_;
00280 data_ = new F[size_ = sz];
00281 }
00282 n_ = sz;
00283 }
00284
00285 template<class F>
00286 void Array<F>::resizePreserve(const uint sz) {
00287 if (sz > size_) {
00288 F* data = new F[sz];
00289 std::memcpy(data, data_, n_*sizeof(F));
00290 delete[] data_;
00291 data_ = data;
00292 size_ = sz;
00293 }
00294 n_ = sz;
00295 }
00296
00297 template<class F>
00298 std::ostream& Array<F>::info(std::ostream& os) const {
00299 os << "Array<F>(" << n_ << ", [";
00300 F* d = data_;
00301 for (uint i = n_; i--;)
00302 os << *d++ << ((i == 0) ? "" : ", ");
00303 return os << "])";
00304 }
00305
00306 template<class F>
00307 Array<F>& Array<F>::reverse() {
00308 F *d = data_, *e = data_ + (n_-1);
00309 for(uint i = std::floor(double(n_)/2.0); i--; )
00310 std::swap(*d++, *e--);
00311 return *this;
00312 }
00313
00314 template<class F>
00315 std::ostream& operator<<(std::ostream& os, const Array<F>& o) {
00316 #ifdef DEBUG
00317 os << std::flush;
00318 #endif
00319 return o.info(os);
00320 }
00321
00322 template <class F>
00323 inline bool operator==(const Array<F>& x, const Array<F>& y)
00324 {
00325 uint n = x.size();
00326 if (n != y.size()) return false;
00327 const F* d = (const F*)x; const F* e = (const F*)y;
00328 for (uint i = n; i--;)
00329 if (*d++ != *e++) return false;
00330 return true;
00331 }
00332
00333 template <class F>
00334 inline bool operator==(const Array<F>& x, F& y)
00335 {
00336 uint n = x.size();
00337 const F* d = (const F*)x;
00338 for (uint i = n; i--;)
00339 if (*d++ != y) return false;
00340 return true;
00341 }
00342
00343 template <class F>
00344 inline bool operator==(F& y, const Array<F>& x)
00345 {
00346 return x == y;
00347 }
00348
00354 template<class F, class G>
00355 concepts::Array<typename Combtype<F,G>::type>
00356 operator*(const concepts::Array<F>& array, const G& val) {
00357 concepts::Array<typename Combtype<F,G>::type> result(array.size());
00358 typename Combtype<F,G>::type* r = (typename Combtype<F,G>::type*)result;
00359 const F* a = (const F*)array;
00360 for(uint i = array.size(); i--;) *r++ = *a++ * val;
00361 return result;
00362 }
00363
00369 template<class F, class G>
00370 Array<typename Combtype<F,G>::type>
00371 operator*(const G& val, const Array<F>& array) {
00372 return array * val;
00373 }
00374
00375
00376
00377 template<typename F>
00378 struct Realtype<Array<F> > {
00379 typedef typename Realtype<F>::type type;
00380 };
00381
00382 template<class F>
00383 void pointerOutput(std::ostream& os, const Array<F>& array) {
00384 os << "Array<F>(" << array.size() << ", [";
00385 const F* d = (const F*)array;
00386 for (uint i = array.size(); i--;) {
00387 pointerOutput(os, *d++);
00388 os << ((i == 0) ? "" : ", ");
00389 }
00390 os << "])";
00391 }
00392
00393 }
00394
00395 #endif // Array_hh