00001
00002
00003
00004 #ifndef multiarray_hh
00005 #define multiarray_hh
00006
00007 #include <map>
00008 #include "basics/outputOperator.hh"
00009 #include "basics/exceptions.hh"
00010 #include "basics/typedefs.hh"
00011 #include "basics/vectorsMatrices.hh"
00012 #include "toolbox/stiffArray.hh"
00013 #include "toolbox/scannerConnectors.hh"
00014 #include "basics/debug.hh"
00015
00016
00017 #define MultiIndexDestr_D 0
00018 #define MultiArrayCommute_D 0
00019 #define MultiArrayErase_D 0
00020 #define MultiArrayScanner_D 0
00021 #define MultiArrayIndex_D 0
00022 #define MultiArrayIndexShort_D 0
00023
00024 #define MultiArrayInfo 1
00025
00026 namespace concepts {
00027
00028
00029 template <uint dim, typename T>
00030 class MultiArray;
00031
00032
00033
00034
00035
00036
00037
00038
00039 template<uint dim>
00040 class MultiIndex : public StiffArray<dim, uint> {
00041 public:
00043 MultiIndex() : StiffArray<dim, uint>() {}
00049 MultiIndex(const uint& dft) : StiffArray<dim, uint>(dft) {}
00056 MultiIndex(const uint dft[]);
00057
00059 MultiIndex(const MultiIndex<dim>& a) : StiffArray<dim, uint>(a) {}
00060 virtual ~MultiIndex() {
00061 DEBUGL(MultiIndexDestr_D, "done.");
00062 }
00063
00065
00067 bool operator==(const MultiIndex<dim>& a) const;
00069 bool operator!=(const MultiIndex<dim>& a) const;
00070 protected:
00071 virtual std::ostream& info(std::ostream& os) const;
00072 };
00073
00074 template<uint dim>
00075 MultiIndex<dim>::MultiIndex(const uint dft[]) :
00076 StiffArray<dim, uint>() {
00077 memorycpy((uint*)(*this), dft, dim);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087 template<uint dim>
00088 bool MultiIndex<dim>::operator==(const MultiIndex<dim>& a) const {
00089 uint i = 0;
00090 while(i < dim && (*this)[i] == a[i]) ++i;
00091 return (i == dim);
00092 }
00093
00094 template<uint dim>
00095 bool MultiIndex<dim>::operator!=(const MultiIndex<dim>& a) const {
00096 return !(*this == a);
00097 }
00098
00099 template<uint dim>
00100 std::ostream& MultiIndex<dim>::info(std::ostream& os) const {
00101 os << "MultiIndex<" << dim << ">([";
00102 for (uint i = 0; i < dim; ++i)
00103 os << (*this)[i] << ((i == dim-1) ? "" : ", ");
00104 return os << "])";
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114 template <uint dim, typename T>
00115 class MultiEntrance : public OutputOperator {
00116 public:
00117 MultiEntrance(const uint i, const MultiEntrance<dim-1,T> ent) :
00118 i_(i), ent_(ent) {}
00119 inline uint operator()(const uint j) const {
00120 conceptsAssert(j < dim, Assertion());
00121 if (j==0) return i_;
00122 return ent_(j-1);
00123 }
00124 inline const T& value() const { return ent_.value(); }
00125 protected:
00126 virtual std::ostream& info(std::ostream& os) const {
00127 os << "(" << i_;
00128 for(uint j=0;j < dim-1;++j)
00129 os << ", " << ent_(j);
00130 return os << ", " << ent_.value() << ")";
00131 }
00132 private:
00133 const uint i_;
00134 MultiEntrance<dim-1,T> ent_;
00135 };
00136
00137
00138
00139 template <typename T>
00140 class MultiEntrance<1,T> : public OutputOperator {
00141 public:
00142 MultiEntrance(const uint i, const T& value) : i_(i), value_(value) {}
00143 inline uint operator()(const uint j = 0) const {
00144 conceptsAssert(j < 1, Assertion());
00145 return i_;
00146 }
00147 inline const T& value() const { return value_; }
00148 protected:
00149 virtual std::ostream& info(std::ostream& os) const {
00150 return os << "(" << i_ << ", " << value_ << ")";
00151 }
00152 private:
00153 const uint i_;
00154 const T value_;
00155 };
00156
00157
00158
00165 template <uint dim, typename T>
00166 class MultiArray : public OutputOperator {
00167 public:
00170 class Scanner {
00171 public:
00172 Scanner(const MultiArray<dim,T> array) :
00173 i_(array.data_.begin()), end_(array.data_.end()), j_(0) {
00174 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00175 if (!eos())
00176
00177 j_ = i_->second.scan();
00178 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00179 }
00180 Scanner(const Scanner& scan)
00181 : i_(scan.i_), end_(scan.end_), j_(scan.j_) {}
00183 virtual ~Scanner() { if (j_!=0) delete j_; }
00185 bool eos() const {
00186 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00187 return i_ == end_;
00188 }
00189 const MultiEntrance<dim,T> operator()() const {
00190 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00191 return MultiEntrance<dim,T>(i_->first, (*j_)());
00192 }
00193 const MultiEntrance<dim,T> operator++(int) {
00194 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00195
00196 conceptsAssert(!eos(), Assertion());
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 const MultiEntrance<dim,T> tmp(i_++->first, (*j_)());
00212 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second << ", " << j_ << ", " << j_->eos());
00213 return tmp;
00214 }
00215 Scanner* clone() const { return new Scanner(*this); }
00216 private:
00220 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator i_;
00222 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator end_;
00224 typename MultiArray<dim-1, T>::Scanner* j_;
00225
00226 };
00231 MultiArray(bool commutable = false) : commutable_(commutable) {}
00232 ~MultiArray() { clear(); }
00240 T& operator [](const uint i[dim]);
00241 T& operator [](uint i[dim]);
00242
00247 const T& operator [](const uint i[dim]) const;
00248 const T& operator [](uint i[dim]) const;
00249 Scanner* scan() const { return new Scanner(*this); }
00252 bool isElm(const uint i[dim]) const;
00253 bool isElm(uint i[dim]) const;
00255 void commute(uint i[dim]) const;
00258 void erase(const uint i[dim]);
00259 void erase(uint i[dim]);
00261 uint size() const;
00263 void clear();
00264 protected:
00265 virtual std::ostream& info(std::ostream& os) const;
00266 private:
00268 std::map<uint, MultiArray<dim-1, T> > data_;
00270 const bool commutable_;
00271 };
00272
00273 template <uint dim, typename T>
00274 T& MultiArray<dim, T>::operator[](const uint i[dim]) {
00275 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00276 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00277 "i = " << MultiIndex<dim>(i));
00278 uint I[dim];
00279 memorycpy(I, i, dim);
00280 return (*this)[I];
00281 }
00282
00283 template <uint dim, typename T>
00284 T& MultiArray<dim, T>::operator[](uint i[dim]) {
00285 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00286 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00287 "i = " << MultiIndex<dim>(i));
00288 commute(i);
00289 typename std::map<uint, MultiArray<dim-1, T> >::iterator j =
00290 data_.find(i[0]);
00291 if (j == data_.end()) {
00292
00293 std::pair
00294 <typename std::map<uint, MultiArray<dim-1, T> >::iterator, bool> k =
00295 data_.insert(std::pair<uint, MultiArray<dim-1, T> >
00296 (i[0], MultiArray<dim-1, T>(commutable_)));
00297 j = k.first;
00298 }
00299 DEBUGL(MultiArrayIndex_D, *this);
00300
00301 return j->second[i+1];
00302 }
00303
00304 template <uint dim, typename T>
00305 const T& MultiArray<dim, T>::operator[](const uint i[dim]) const {
00306 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00307 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00308 "i = " << MultiIndex<dim>(i));
00309 uint I[dim];
00310 memorycpy(I, i, dim);
00311 return (*this)[I];
00312 }
00313
00314 template <uint dim, typename T>
00315 const T& MultiArray<dim, T>::operator[](uint i[dim]) const {
00316 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00317 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00318 "i = " << MultiIndex<dim>(i));
00319 commute(i);
00320 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
00321 data_.find(i[0]);
00322 if (j == data_.end()) {
00323 DEBUGL(MultiArrayIndex_D || MultiArrayIndexShort_D,
00324 "i = " << MultiIndex<dim>(i));
00325 throw conceptsException(IndexNotExisting());
00326 }
00327 return j->second[i+1];
00328 }
00329
00330 template <uint dim, typename T>
00331 bool MultiArray<dim, T>::isElm(const uint i[dim]) const {
00332 uint I[dim];
00333 memorycpy(I, i, dim);
00334 return isElm(I);
00335 }
00336
00337 template <uint dim, typename T>
00338 bool MultiArray<dim, T>::isElm(uint i[dim]) const {
00339 commute(i);
00340 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
00341 data_.find(i[0]);
00342 if (j == data_.end())
00343 return false;
00344 else return j->second.isElm(i+1);
00345 }
00346
00347 template <uint dim, typename T>
00348 void MultiArray<dim, T>::commute(uint i[dim]) const {
00349 if (commutable_) {
00350 for(uint j=1; j < dim; ++j) {
00351 if (i[j] < i[0]) std::swap(i[0],i[j]);
00352 }
00353 DEBUGL(MultiArrayCommute_D, MultiIndex<dim>(i));
00354 }
00355 }
00356
00357 template <uint dim, typename T>
00358 void MultiArray<dim, T>::erase(const uint i[dim]) {
00359 uint I[dim];
00360 memorycpy(I, i, dim);
00361 erase(I);
00362 }
00363
00364 template <uint dim, typename T>
00365 void MultiArray<dim, T>::erase(uint i[dim]) {
00366 commute(i);
00367 DEBUGL(MultiArrayErase_D, "Erase (" << Array<uint>(i,dim) << ")");
00368 typename std::map<uint, MultiArray<dim-1, T> >::iterator j =
00369 data_.find(i[0]);
00370 if (j == data_.end())
00371 throw conceptsException(IndexNotExisting());
00372 DEBUGL(MultiArrayErase_D, j->second);
00373 j->second.erase(i+1);
00374 DEBUGL(MultiArrayErase_D, j->second);
00375 if (j->second.size()==0)
00376 data_.erase(i[0]);
00377 }
00378
00379 template <uint dim, typename T>
00380 uint MultiArray<dim, T>::size() const {
00381 uint size = 0;
00382 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
00383 data_.begin();
00384 for(;j != data_.end();++j)
00385 size += j->second.size();
00386 return size;
00387 }
00388
00389 template <uint dim, typename T>
00390 void MultiArray<dim, T>::clear() {
00391 typename std::map<uint, MultiArray<dim-1, T> >::iterator j = data_.begin();
00392 for(;j != data_.end();++j)
00393 j->second.clear();
00394 data_.clear();
00395 }
00396
00397 template <uint dim, typename T>
00398 std::ostream& MultiArray<dim, T>::info(std::ostream& os) const {
00399 uint size = this->size();
00400 os << "MultiArray<" << dim << ",T>(" << size << ", ";
00401 if (commutable_) os << "yes";
00402 else os << "no";
00403 if (size > 0) {
00404 os << ",[";
00405 typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j0 = data_.begin();
00406 for(;j0 != data_.end();) {
00407 #if MultiArrayInfo
00408 DEBUGL(MultiArrayScanner_D,j0->first << ", " << j0->second);
00409 os << "(" << j0->first << ", " << j0->second << ")";
00410 #else
00411
00412 std::auto_ptr<Scanner> sc(scan());
00413 while (!sc->eos()) {
00414 os << (*sc)++;
00415 if (!sc->eos()) os << ", ";
00416 }
00417 #endif
00418 if (++j0 != data_.end()) os << ", ";
00419 }
00420 os << "]";
00421 }
00422 return os << ")";
00423 }
00424
00425
00426
00431 template <typename T>
00432 class MultiArray<1,T> : public OutputOperator {
00433 public:
00436 class Scanner {
00437 public:
00438 Scanner(const MultiArray<1,T> array) : i_(array.data_.begin()),
00439 end_(array.data_.end()) {}
00440 Scanner(const Scanner& scan) : i_(scan.i_), end_(scan.end_) {}
00441 bool eos() const { return i_ == end_; }
00442 const MultiEntrance<1,T> operator()() const {
00443 return MultiEntrance<1,T>(i_->first, i_->second);
00444 }
00445 const MultiEntrance<1,T> operator++(int) {
00446
00447 conceptsAssert(!eos(), Assertion());
00448
00449 const MultiEntrance<1,T> tmp(i_->first, i_->second);
00450 i_++;
00451 return tmp;
00452 }
00453 Scanner* clone() const { return new Scanner(*this); }
00454 private:
00458 typename std::map<uint, T>::const_iterator i_;
00459 typename std::map<uint, T>::const_iterator end_;
00460 };
00461
00467 MultiArray(bool commutable = false) {}
00468 ~MultiArray() { clear(); }
00476 T& operator [](const uint i[1]) { return data_[i[0]]; }
00481 const T& operator [](const uint i[1]) const { return (*this)[i[0]];}
00489 T& operator [](const uint i) { return data_[i]; }
00494 const T& operator [](const uint i) const;
00496 Scanner* scan() const { return new Scanner(*this); }
00499 bool isElm(const uint i[1]) const { return isElm(i[0]); }
00500 bool isElm(const uint i) const;
00503 inline void erase(const uint i[1]) { erase(i[0]); }
00504 inline void erase(uint i) {
00505 DEBUGL(MultiArrayErase_D, "Erase (" << i << ")");
00506 data_.erase(i);
00507 }
00509 uint size() const { return data_.size(); }
00510
00512 inline void clear() { data_.clear(); }
00513 protected:
00514 virtual std::ostream& info(std::ostream& os) const;
00515 private:
00517 std::map<uint, T> data_;
00518 };
00519
00520 template <typename T>
00521 const T& MultiArray<1, T>::operator[](const uint i) const {
00522 typename std::map<uint, T>::const_iterator j = data_.find(i);
00523 if (j == data_.end())
00524 throw conceptsException(IndexNotExisting());
00525 return j->second;
00526 }
00527
00528 template <typename T>
00529 bool MultiArray<1, T>::isElm(const uint i) const {
00530 typename std::map<uint, T>::const_iterator j = data_.find(i);
00531 return (j != data_.end());
00532 }
00533
00534 template <typename T>
00535 std::ostream& MultiArray<1,T>::info(std::ostream& os) const {
00536 uint size = this->size();
00537 os << "MultiArray<1,T>(" << size;
00538 if (size > 0) {
00539 os << ",[";
00540 std::auto_ptr<Scanner> sc(scan());
00541 while (!sc->eos()) {
00542 os << (*sc)++;
00543 if (!sc->eos()) os << ", ";
00544 }
00545 os << "]";
00546 }
00547 return os << ")";
00548 }
00549
00550 }
00551
00552 #endif // multiarray_hh