src/Index/SOffset.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef SOFFSET_H
00012 #define SOFFSET_H
00013 
00014 // include files
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 // forward declarations
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  * SOffset is a simple class which stores an array of N integers
00080  * for use by the SIndex class.  It represents an integer offset
00081  * for the numbers in the SIndex set of indices.  Otherwise, it acts
00082  * just like a set of N integers.  The class is templated on the number
00083  * of elements N.
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   // constructors: note the default constructor initializes data to 0
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);                 // only works for a 2D SOffset
00099   SOffset(int v0, int v1, int v2);         // only works for a 3D SOffset
00100   SOffset(int v0, int v1, int v2, int v3); // only works for a 4D SOffset
00101   SOffset(int v0, int v1, int v2, int v3, int v4); // only for 5D SOffset
00102   SOffset(int v0, int v1, int v2, int v3, int v4, int v5); // only for 6D
00103   SOffset(const int *vv);     // Takes array of offsets, for any dimensionality
00104   SOffset(const SOffset<Dim>&);
00105 
00106   // copy and index operators
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   // comparison operators
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   // arithmetic operators
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   // put or get to/from a Message
00133   Message& putMessage(Message &);
00134   Message& getMessage(Message &);
00135 
00136   // iterators for the offset, and information about the data
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   // is this point within an NDIndex object (includes the edges) ?
00144   bool inside(const NDIndex<Dim>&) const;
00145   
00146 private:
00147   int v[Dim];
00148 };
00149 
00150 
00151 /***********************************************************************
00152  * 
00153  * Inlined constructors and SOffset functions.
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   // if we're here, they're exactly equal
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 // is this point within an NDIndex object (includes the edges) ?
00255 // NOTE: this intersects with the whole region of the NDIndex, basically
00256 // assuming unit stride.
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  * Template classes and functions to unroll the loops into subloops of
00271  * a maximum of 3 elements.
00272  * This is taken from the Utility/Vec.h class with modifications.
00273  *
00274  ***********************************************************************/
00275 
00276 // a tag class used to indicate how many elements and when to split a loop
00277 template<unsigned int Dim, int Flag>
00278 class DivideSOffsetCopyTag {
00279 #ifdef IPPL_PURIFY
00280   // Add explicit default/copy constructors and op= to avoid UMR's.
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 // simple functors for performing operations on SOffset elements
00290 struct SOffsetAssignOp {
00291 #ifdef IPPL_PURIFY
00292   // Add explicit default/copy constructors and op= to avoid UMR's.
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   // Add explicit default/copy constructors and op= to avoid UMR's.
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   // Add explicit default/copy constructors and op= to avoid UMR's.
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   // Add explicit default/copy constructors and op= to avoid UMR's.
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   // Add explicit default/copy constructors and op= to avoid UMR's.
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 // Operate on a vector of dim 4 or greater.  Split it in half and do each half.
00342 // Do it this way so that the depth of inlining is O(log(Dim)).
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 // Modify a vector of length 0, 1, 2 or 3.
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 // The SOffset operators just call divide_soffset_op to do the operation
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 // binary operators
00493 // SOffset +-*/ SOffset  -->  SOffset
00494 // SOffset +-*/ int *    -->  SOffset
00495 // SOffset +-*/ NDIndex  -->  NDIndex
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 // unary operators
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  * $RCSfile: SOffset.h,v $   $Author: adelmann $
00681  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:27 $
00682  * IPPL_VERSION_ID: $Id: SOffset.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $ 
00683  ***************************************************************************/

Generated on Mon Jan 16 13:23:49 2006 for IPPL by  doxygen 1.4.6