00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef SOFFSET_H
00012 #define SOFFSET_H
00013
00014
00015 #include "Index/NDIndex.h"
00016 #include "Utility/PAssert.h"
00017 #include "Message/Message.h"
00018
00019 #ifdef IPPL_USE_STANDARD_HEADERS
00020 #include <iostream>
00021 using namespace std;
00022 #else
00023 #include <iostream.h>
00024 #endif
00025
00026
00027 template <unsigned Dim> class SOffset;
00028
00029 template <unsigned Dim>
00030 SOffset<Dim> operator+(const SOffset<Dim>&, const SOffset<Dim>&);
00031 template <unsigned Dim>
00032 SOffset<Dim> operator+(const SOffset<Dim>&, const int *);
00033 template <unsigned Dim>
00034 SOffset<Dim> operator+(const int *, const SOffset<Dim>&);
00035 template <unsigned Dim>
00036 NDIndex<Dim> operator+(const NDIndex<Dim>&, const SOffset<Dim>&);
00037 template <unsigned Dim>
00038 NDIndex<Dim> operator+(const SOffset<Dim>&, const NDIndex<Dim>&);
00039
00040 template <unsigned Dim>
00041 SOffset<Dim> operator-(const SOffset<Dim>&, const SOffset<Dim>&);
00042 template <unsigned Dim>
00043 SOffset<Dim> operator-(const SOffset<Dim>&, const int *);
00044 template <unsigned Dim>
00045 SOffset<Dim> operator-(const int *, const SOffset<Dim>&);
00046 template <unsigned Dim>
00047 NDIndex<Dim> operator-(const NDIndex<Dim>&, const SOffset<Dim>&);
00048 template <unsigned Dim>
00049 NDIndex<Dim> operator-(const SOffset<Dim>&, const NDIndex<Dim>&);
00050
00051 template <unsigned Dim>
00052 SOffset<Dim> operator*(const SOffset<Dim>&, const SOffset<Dim>&);
00053 template <unsigned Dim>
00054 SOffset<Dim> operator*(const SOffset<Dim>&, const int *);
00055 template <unsigned Dim>
00056 SOffset<Dim> operator*(const int *, const SOffset<Dim>&);
00057 template <unsigned Dim>
00058 NDIndex<Dim> operator*(const NDIndex<Dim>&, const SOffset<Dim>&);
00059 template <unsigned Dim>
00060 NDIndex<Dim> operator*(const SOffset<Dim>&, const NDIndex<Dim>&);
00061
00062 template <unsigned Dim>
00063 SOffset<Dim> operator/(const SOffset<Dim>&, const SOffset<Dim>&);
00064 template <unsigned Dim>
00065 SOffset<Dim> operator/(const SOffset<Dim>&, const int *);
00066 template <unsigned Dim>
00067 SOffset<Dim> operator/(const int *, const SOffset<Dim>&);
00068 template <unsigned Dim>
00069 NDIndex<Dim> operator/(const NDIndex<Dim>&, const SOffset<Dim>&);
00070
00071 template <unsigned Dim>
00072 SOffset<Dim>& operator-(const SOffset<Dim>&);
00073
00074 template <unsigned Dim>
00075 ostream& operator<<(ostream&, const SOffset<Dim>&);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 template <unsigned Dim>
00088 class SOffset {
00089
00090 public:
00091 typedef int * iterator;
00092 typedef const int * const_iterator;
00093
00094 public:
00095
00096 SOffset() { for (unsigned int d=0; d < Dim; v[d++] = 0); }
00097 SOffset(int v0) { for (unsigned int d=0; d < Dim; v[d++] = v0); }
00098 SOffset(int v0, int v1);
00099 SOffset(int v0, int v1, int v2);
00100 SOffset(int v0, int v1, int v2, int v3);
00101 SOffset(int v0, int v1, int v2, int v3, int v4);
00102 SOffset(int v0, int v1, int v2, int v3, int v4, int v5);
00103 SOffset(const int *vv);
00104 SOffset(const SOffset<Dim>&);
00105
00106
00107 SOffset<Dim>& operator=(const SOffset<Dim>&);
00108 SOffset<Dim>& operator=(const int *);
00109 int& operator[](unsigned int d) { return v[d]; }
00110 const int& operator[](unsigned int d) const { return v[d]; }
00111
00112
00113 bool operator==(const SOffset<Dim>&) const;
00114 bool operator<(const SOffset<Dim>&) const;
00115 bool operator!=(const SOffset<Dim>& a) const { return !(*this == a); }
00116 bool operator<=(const SOffset<Dim>& a) const { return !(*this > a); }
00117 bool operator>=(const SOffset<Dim>& a) const { return !(*this < a); }
00118 bool operator>(const SOffset<Dim>& a) const {
00119 return !(*this < a || *this == a);
00120 }
00121
00122
00123 SOffset<Dim>& operator+=(const SOffset<Dim>&);
00124 SOffset<Dim>& operator+=(const int *);
00125 SOffset<Dim>& operator-=(const SOffset<Dim>&);
00126 SOffset<Dim>& operator-=(const int *);
00127 SOffset<Dim>& operator*=(const SOffset<Dim>&);
00128 SOffset<Dim>& operator*=(const int *);
00129 SOffset<Dim>& operator/=(const SOffset<Dim>&);
00130 SOffset<Dim>& operator/=(const int *);
00131
00132
00133 Message& putMessage(Message &);
00134 Message& getMessage(Message &);
00135
00136
00137 iterator begin() { return v; }
00138 iterator end() { return (v + Dim); }
00139 const_iterator begin() const { return v; }
00140 const_iterator end() const { return (v + Dim); }
00141 unsigned int size() const { return Dim; }
00142
00143
00144 bool inside(const NDIndex<Dim>&) const;
00145
00146 private:
00147 int v[Dim];
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157 template<unsigned int Dim>
00158 inline
00159 SOffset<Dim>::SOffset(int v0, int v1) {
00160 CTAssert(Dim==2);
00161 v[0] = v0;
00162 v[1] = v1;
00163 }
00164
00165 template<unsigned int Dim>
00166 inline
00167 SOffset<Dim>::SOffset(int v0, int v1, int v2) {
00168 CTAssert(Dim==3);
00169 v[0] = v0;
00170 v[1] = v1;
00171 v[2] = v2;
00172 }
00173
00174 template<unsigned int Dim>
00175 inline
00176 SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3) {
00177 CTAssert(Dim==4);
00178 v[0] = v0;
00179 v[1] = v1;
00180 v[2] = v2;
00181 v[3] = v3;
00182 }
00183
00184 template<unsigned int Dim>
00185 inline
00186 SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3, int v4) {
00187 CTAssert(Dim==5);
00188 v[0] = v0;
00189 v[1] = v1;
00190 v[2] = v2;
00191 v[3] = v3;
00192 v[4] = v4;
00193 }
00194
00195 template<unsigned int Dim>
00196 inline
00197 SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3, int v4, int v5) {
00198 CTAssert(Dim==6);
00199 v[0] = v0;
00200 v[1] = v1;
00201 v[2] = v2;
00202 v[3] = v3;
00203 v[4] = v4;
00204 v[5] = v5;
00205 }
00206
00207 template<unsigned int Dim>
00208 inline bool
00209 SOffset<Dim>::operator==(const SOffset<Dim>& a) const {
00210 for (unsigned int i=0; i < Dim; ++i)
00211 if (v[i] != a.v[i])
00212 return false;
00213 return true;
00214 }
00215
00216 template<unsigned int Dim>
00217 inline bool
00218 SOffset<Dim>::operator<(const SOffset<Dim>& a) const {
00219 for (unsigned int i=0; i < Dim; ++i) {
00220 if (v[i] < a.v[i])
00221 return true;
00222 else if (v[i] > a.v[i])
00223 return false;
00224 }
00225
00226
00227 return false;
00228 }
00229
00230 template<unsigned int Dim>
00231 inline Message&
00232 SOffset<Dim>::putMessage(Message &m) {
00233 ::putMessage(m, v, v + Dim);
00234 return m;
00235 }
00236
00237 template<unsigned int Dim>
00238 inline Message&
00239 SOffset<Dim>::getMessage(Message &m) {
00240 ::getMessage_iter(m, v);
00241 return m;
00242 }
00243
00244 template<unsigned int Dim>
00245 inline ostream&
00246 operator<<(ostream& o, const SOffset<Dim>& a) {
00247 o << "[";
00248 for (unsigned int i=0; i < Dim; ++i)
00249 o << a[i] << (i < (Dim-1) ? "," : "");
00250 o << "]";
00251 return o;
00252 }
00253
00254
00255
00256
00257 template<unsigned int Dim>
00258 inline bool
00259 SOffset<Dim>::inside(const NDIndex<Dim>& ndi) const {
00260 for (unsigned int d=0; d < Dim; ++d) {
00261 if (v[d] < ndi[d].first() || v[d] > ndi[d].last())
00262 return false;
00263 }
00264 return true;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 template<unsigned int Dim, int Flag>
00278 class DivideSOffsetCopyTag {
00279 #ifdef IPPL_PURIFY
00280
00281 public:
00282 DivideSOffsetCopyTag() {}
00283 DivideSOffsetCopyTag(const DivideSOffsetCopyTag<Dim,Flag> &) {}
00284 DivideSOffsetCopyTag<Dim,Flag>&
00285 operator=(const DivideSOffsetCopyTag<Dim,Flag> &) { return *this; }
00286 #endif
00287 };
00288
00289
00290 struct SOffsetAssignOp {
00291 #ifdef IPPL_PURIFY
00292
00293 SOffsetAssignOp() {}
00294 SOffsetAssignOp(const SOffsetAssignOp &) {}
00295 SOffsetAssignOp& operator=(const SOffsetAssignOp &) { return *this; }
00296 #endif
00297 void operator()(int& a, int b) { a = b; }
00298 };
00299
00300 struct SOffsetAddAssignOp {
00301 #ifdef IPPL_PURIFY
00302
00303 SOffsetAddAssignOp() {}
00304 SOffsetAddAssignOp(const SOffsetAddAssignOp &) {}
00305 SOffsetAddAssignOp& operator=(const SOffsetAddAssignOp &) { return *this; }
00306 #endif
00307 void operator()(int& a, int b) { a += b; }
00308 };
00309
00310 struct SOffsetSubAssignOp {
00311 #ifdef IPPL_PURIFY
00312
00313 SOffsetSubAssignOp() {}
00314 SOffsetSubAssignOp(const SOffsetSubAssignOp &) {}
00315 SOffsetSubAssignOp& operator=(const SOffsetSubAssignOp &) { return *this; }
00316 #endif
00317 void operator()(int& a, int b) { a -= b; }
00318 };
00319
00320 struct SOffsetMultAssignOp {
00321 #ifdef IPPL_PURIFY
00322
00323 SOffsetMultAssignOp() {}
00324 SOffsetMultAssignOp(const SOffsetMultAssignOp &) {}
00325 SOffsetMultAssignOp& operator=(const SOffsetMultAssignOp &) { return *this; }
00326 #endif
00327 void operator()(int& a, int b) { a *= b; }
00328 };
00329
00330 struct SOffsetDivAssignOp {
00331 #ifdef IPPL_PURIFY
00332
00333 SOffsetDivAssignOp() {}
00334 SOffsetDivAssignOp(const SOffsetDivAssignOp &) {}
00335 SOffsetDivAssignOp& operator=(const SOffsetDivAssignOp &) { return *this; }
00336 #endif
00337 void operator()(int& a, int b) { a /= b; }
00338 };
00339
00340
00341
00342
00343 template<class T1, class T2, class Op, unsigned int L>
00344 inline void
00345 divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag<L,4> ) {
00346 divide_soffset_op(p1, p2, op, DivideSOffsetCopyTag<L/2, (L>=8 ? 4 : L/2)>());
00347 divide_soffset_op(p1+(L/2), p2+(L/2), op,
00348 DivideSOffsetCopyTag<L-L/2, (L>=8?4:L-L/2)>());
00349 }
00350
00351
00352
00353 template<class T1, class T2, class Op>
00354 inline void
00355 divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag<3,3>) {
00356 op(p1[0], p2[0]);
00357 op(p1[1], p2[1]);
00358 op(p1[2], p2[2]);
00359 }
00360
00361 template<class T1, class T2, class Op>
00362 inline void
00363 divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag<2,2>) {
00364 op(p1[0], p2[0]);
00365 op(p1[1], p2[1]);
00366 }
00367
00368 template<class T1, class T2, class Op>
00369 inline void
00370 divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag<1,1>) {
00371 op(*p1, *p2);
00372 }
00373
00374 template<class T1, class T2, class Op>
00375 inline void
00376 divide_soffset_op(T1 *,T2 *, Op, DivideSOffsetCopyTag<0,0>) {
00377 }
00378
00379
00380
00381
00382
00383 template<unsigned int L>
00384 inline
00385 SOffset<L>::SOffset(const SOffset<L>& SO)
00386 {
00387 divide_soffset_op(v, SO.v, SOffsetAssignOp(),
00388 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00389 }
00390
00391 template<unsigned int L>
00392 inline
00393 SOffset<L>::SOffset(const int *SO)
00394 {
00395 divide_soffset_op(v, SO, SOffsetAssignOp(),
00396 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00397 }
00398
00399 template<unsigned int L>
00400 inline SOffset<L>&
00401 SOffset<L>::operator=(const SOffset<L>& SO)
00402 {
00403 if ( this != &SO )
00404 divide_soffset_op(v, SO.v, SOffsetAssignOp(),
00405 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00406 return *this;
00407 }
00408
00409 template<unsigned int L>
00410 inline SOffset<L>&
00411 SOffset<L>::operator=(const int *SO)
00412 {
00413 divide_soffset_op(v, SO, SOffsetAssignOp(),
00414 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00415 return *this;
00416 }
00417
00418 template<unsigned int L>
00419 inline SOffset<L>&
00420 SOffset<L>::operator+=(const SOffset<L>& SO)
00421 {
00422 divide_soffset_op(v, SO.v, SOffsetAddAssignOp(),
00423 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00424 return *this;
00425 }
00426
00427 template<unsigned int L>
00428 inline SOffset<L>&
00429 SOffset<L>::operator+=(const int *SO)
00430 {
00431 divide_soffset_op(v, SO, SOffsetAddAssignOp(),
00432 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00433 return *this;
00434 }
00435
00436 template<unsigned int L>
00437 inline SOffset<L>&
00438 SOffset<L>::operator-=(const SOffset<L>& SO)
00439 {
00440 divide_soffset_op(v, SO.v, SOffsetSubAssignOp(),
00441 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00442 return *this;
00443 }
00444
00445 template<unsigned int L>
00446 inline SOffset<L>&
00447 SOffset<L>::operator-=(const int *SO)
00448 {
00449 divide_soffset_op(v, SO, SOffsetSubAssignOp(),
00450 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00451 return *this;
00452 }
00453
00454 template<unsigned int L>
00455 inline SOffset<L>&
00456 SOffset<L>::operator*=(const SOffset<L>& SO)
00457 {
00458 divide_soffset_op(v, SO.v, SOffsetMultAssignOp(),
00459 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00460 return *this;
00461 }
00462
00463 template<unsigned int L>
00464 inline SOffset<L>&
00465 SOffset<L>::operator*=(const int *SO)
00466 {
00467 divide_soffset_op(v, SO, SOffsetMultAssignOp(),
00468 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00469 return *this;
00470 }
00471
00472 template<unsigned int L>
00473 inline SOffset<L>&
00474 SOffset<L>::operator/=(const SOffset<L>& SO)
00475 {
00476 divide_soffset_op(v, SO.v, SOffsetDivAssignOp(),
00477 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00478 return *this;
00479 }
00480
00481 template<unsigned int L>
00482 inline SOffset<L>&
00483 SOffset<L>::operator/=(const int *SO)
00484 {
00485 divide_soffset_op(v, SO, SOffsetDivAssignOp(),
00486 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
00487 return *this;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 template<unsigned int L>
00499 inline SOffset<L>
00500 operator+(const SOffset<L>& a, const SOffset<L>& b)
00501 {
00502 SOffset<L> retval(a);
00503 return (retval += b);
00504 }
00505
00506 template<unsigned int L>
00507 inline SOffset<L>
00508 operator+(const SOffset<L>& a, const int *b)
00509 {
00510 SOffset<L> retval(a);
00511 return (retval += b);
00512 }
00513
00514 template<unsigned int L>
00515 inline SOffset<L>
00516 operator+(const int *b, const SOffset<L>& a)
00517 {
00518 SOffset<L> retval(a);
00519 return (retval += b);
00520 }
00521
00522 template<unsigned int L>
00523 inline NDIndex<L>
00524 operator+(const SOffset<L>& a, const NDIndex<L>& b)
00525 {
00526 NDIndex<L> retval;
00527 for (int d=0; d < L; ++d)
00528 retval[d] = b[d] + a[d];
00529 return retval;
00530 }
00531
00532 template<unsigned int L>
00533 inline NDIndex<L>
00534 operator+(const NDIndex<L>& b, const SOffset<L>& a)
00535 {
00536 NDIndex<L> retval;
00537 for (int d=0; d < L; ++d)
00538 retval[d] = b[d] + a[d];
00539 return retval;
00540 }
00541
00542 template<unsigned int L>
00543 inline SOffset<L>
00544 operator-(const SOffset<L>& a, const SOffset<L>& b)
00545 {
00546 SOffset<L> retval(a);
00547 return (retval -= b);
00548 }
00549
00550 template<unsigned int L>
00551 inline SOffset<L>
00552 operator-(const SOffset<L>& a, const int *b)
00553 {
00554 SOffset<L> retval(a);
00555 return (retval -= b);
00556 }
00557
00558 template<unsigned int L>
00559 inline SOffset<L>
00560 operator-(const int *b, const SOffset<L>& a)
00561 {
00562 SOffset<L> retval(a);
00563 return (retval -= b);
00564 }
00565
00566 template<unsigned int L>
00567 inline NDIndex<L>
00568 operator-(const SOffset<L>& a, const NDIndex<L>& b)
00569 {
00570 NDIndex<L> retval;
00571 for (int d=0; d < L; ++d)
00572 retval[d] = b[d] - a[d];
00573 return retval;
00574 }
00575
00576 template<unsigned int L>
00577 inline NDIndex<L>
00578 operator-(const NDIndex<L>& b, const SOffset<L>& a)
00579 {
00580 NDIndex<L> retval;
00581 for (int d=0; d < L; ++d)
00582 retval[d] = b[d] - a[d];
00583 return retval;
00584 }
00585
00586 template<unsigned int L>
00587 inline SOffset<L>
00588 operator*(const SOffset<L>& a, const SOffset<L>& b)
00589 {
00590 SOffset<L> retval(a);
00591 return (retval *= b);
00592 }
00593
00594 template<unsigned int L>
00595 inline SOffset<L>
00596 operator*(const SOffset<L>& a, const int *b)
00597 {
00598 SOffset<L> retval(a);
00599 return (retval *= b);
00600 }
00601
00602 template<unsigned int L>
00603 inline SOffset<L>
00604 operator*(const int *b, const SOffset<L>& a)
00605 {
00606 SOffset<L> retval(a);
00607 return (retval *= b);
00608 }
00609
00610 template<unsigned int L>
00611 inline NDIndex<L>
00612 operator*(const SOffset<L>& a, const NDIndex<L>& b)
00613 {
00614 NDIndex<L> retval;
00615 for (int d=0; d < L; ++d)
00616 retval[d] = b[d] * a[d];
00617 return retval;
00618 }
00619
00620 template<unsigned int L>
00621 inline NDIndex<L>
00622 operator*(const NDIndex<L>& b, const SOffset<L>& a)
00623 {
00624 NDIndex<L> retval;
00625 for (int d=0; d < L; ++d)
00626 retval[d] = b[d] * a[d];
00627 return retval;
00628 }
00629
00630 template<unsigned int L>
00631 inline SOffset<L>
00632 operator/(const SOffset<L>& a, const SOffset<L>& b)
00633 {
00634 SOffset<L> retval(a);
00635 return (retval /= b);
00636 }
00637
00638 template<unsigned int L>
00639 inline SOffset<L>
00640 operator/(const SOffset<L>& a, const int *b)
00641 {
00642 SOffset<L> retval(a);
00643 return (retval /= b);
00644 }
00645
00646 template<unsigned int L>
00647 inline SOffset<L>
00648 operator/(const int *b, const SOffset<L>& a)
00649 {
00650 SOffset<L> retval(a);
00651 return (retval /= b);
00652 }
00653
00654 template<unsigned int L>
00655 inline NDIndex<L>
00656 operator/(const NDIndex<L>& b, const SOffset<L>& a)
00657 {
00658 NDIndex<L> retval;
00659 for (int d=0; d < L; ++d)
00660 retval[d] = b[d] / a[d];
00661 return retval;
00662 }
00663
00664
00665
00666
00667
00668
00669 template<unsigned int L>
00670 inline SOffset<L>&
00671 operator-(const SOffset<L>& a)
00672 {
00673 SOffset<L> retval;
00674 return (retval -= a);
00675 }
00676
00677 #endif // SOFFSET_H
00678
00679
00680
00681
00682
00683