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 INDEXED_SINDEX_H 00012 #define INDEXED_SINDEX_H 00013 00014 // include files 00015 #include "Index/SIndex.h" 00016 #include "Index/NDIndex.h" 00017 #include "Index/SIndexAssign.h" 00018 #include "Utility/PAssert.h" 00019 00020 00021 /*********************************************************************** 00022 * 00023 * IndexedSIndex represents an SIndex object + an NDIndex object which 00024 * selects just a subset of the original field domain of the SIndex 00025 * object. When the user uses the [] operator on an SIndex object, it 00026 * returns an IndexedSIndex object which knows it should refer to points 00027 * only in the index space of the Index objects provided in the [] operator. 00028 * This is used to modify the original SIndex to let it know that it refers 00029 * only to a subset, and so when it is used in an SIndex assignment or 00030 * expression, only that subset should be looped over. 00031 * 00032 * The first template parameter is the dimension of the SIndex object; the 00033 * second is the number of dimensions worth of bracket operators which have 00034 * been applied so far. This is the sum of the dimensions which have been 00035 * specified by Index or NDIndex objects inside the bracket operators of 00036 * SIndex or IndexedSIndex. By the time the SIndex object is needed, this 00037 * should have Dim == Brackets. If not, it is an error. 00038 * 00039 ***********************************************************************/ 00040 00041 00042 template <unsigned Dim, unsigned Brackets> 00043 class IndexedSIndex { 00044 00045 public: 00046 // Initialize this object with the SIndex it refers to, and the NDIndex 00047 // it should use. 00048 IndexedSIndex(SIndex<Dim> &s, const NDIndex<Dim> &i) 00049 : sIndex(s), domain(i) { } 00050 00051 IndexedSIndex(const IndexedSIndex<Dim,Brackets> &isi) 00052 : sIndex(const_cast<SIndex<Dim> &>(isi.sIndex)), domain(isi.domain) { } 00053 00054 // destructor: nothing to do 00055 ~IndexedSIndex() { } 00056 00057 // get the SIndex we are using 00058 const SIndex<Dim> &getSIndex() const { return sIndex; } 00059 00060 // get the domain we're Indexing 00061 const NDIndex<Dim> &getDomain() const { return domain; } 00062 00063 // assignment operators. First make sure we have fully specified 00064 // what domain to use by checking that Dim == Brackets, then call 00065 // assign but with the smaller domain. 00066 template<class T> 00067 IndexedSIndex<Dim,Brackets>& operator=(const PETE_Expr<T>& rhs) { 00068 CTAssert(Brackets == Dim); 00069 assign(sIndex, rhs, domain); 00070 return *this; 00071 } 00072 00073 // operator[], which is used with Index or NDIndex objects to further 00074 // subset the data. This will only work if the dimension of the Index 00075 // arguments + Brackets is <= Dim. Otherwise, too many dimensions worth 00076 // of Index objects are being applied 00077 IndexedSIndex<Dim,Brackets + 1> 00078 operator[](const Index &i) { 00079 CTAssert((Brackets + 1) <= Dim); 00080 NDIndex<Dim> dom = domain; 00081 dom[Brackets] = i; 00082 return IndexedSIndex<Dim,Brackets + 1>(sIndex, dom); 00083 } 00084 00085 template<unsigned Dim2> 00086 IndexedSIndex<Dim,Brackets + Dim2> 00087 operator[](const NDIndex<Dim2> &ndi) { 00088 CTAssert((Brackets + Dim2) <= Dim); 00089 NDIndex<Dim> dom = domain; 00090 for (int i=0; i < Dim2; ++i) 00091 dom[Brackets + i] = ndi[i]; 00092 return IndexedSIndex<Dim,Brackets + Dim2>(sIndex, dom); 00093 } 00094 00095 private: 00096 // the SIndex we refer to 00097 SIndex<Dim> &sIndex; 00098 00099 // the NDIndex we are subsetting to 00100 NDIndex<Dim> domain; 00101 00102 // copy constructor and operator=, made private since we do not want them 00103 IndexedSIndex<Dim,Brackets>& operator=(const IndexedSIndex<Dim,Brackets> &); 00104 }; 00105 00106 #endif // INDEXED_SINDEX_H 00107 00108 /*************************************************************************** 00109 * $RCSfile: IndexedSIndex.h,v $ $Author: adelmann $ 00110 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $ 00111 * IPPL_VERSION_ID: $Id: IndexedSIndex.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $ 00112 ***************************************************************************/