src/SubField/SubBareField.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 SUB_BARE_FIELD_H
00012 #define SUB_BARE_FIELD_H
00013 
00014 /***************************************************************************
00015   SubBareField - represent a view on a given BareField, referring to a
00016   subset of the original field data.  This is meant as an eventual
00017   replacement for IndexedBareField.
00018 
00019   SubBareField is templated on the T and Dim of the Field, and also on the
00020   type of subset object used to refer to the field subsection.  This can
00021   range from NDIndex for a rectangular block, to SIndex for an arbitrary
00022   list of points, to SOffset to store a single point.  The behavior of this
00023   class, and in particular the iterator for this class, is specialized to
00024   each subset object using a traits class 'SFTraits' and a couple of global
00025   functions.
00026 
00027   From a BareField, you create a SubBareField by using the bracket
00028   operators [], giving a particular type of data to further index the object.
00029   Indexing with and Index or NDIndex object results in a SubBareField object
00030   templated on NDIndex, etc.  A SubBareField keeps track of the number of
00031   'Brackets' its been given; an expression can only involve a SubBareField
00032   if Brackets == Dim.  Using [] on a SubBareField will generally increase the
00033   number of brackets, and result in a new SubBareField incorporating the
00034   info about how to select the subset as specified by the object in brackets.
00035   For example, Field<T,Dim>[Index] results in a SubBareField<T,Dim,NDIndex<Dim>>
00036   object with Brackets==1; further application of [Index] operators increases
00037   the number of Brackets and stores each Index in the internal NDIndex at the
00038   proper location.  SFTraits provides the information on what types of objects
00039   can be used to subset, and what type of subset object they produce.
00040 
00041   For the future, it might be useful to make this 'SubBareField' be the actual
00042   class employed by the user, with the current 'BareField' some form of
00043   internal class used only to store the data in whatever representation is
00044   most efficient.
00045  ***************************************************************************/
00046 
00047 // include files
00048 #include "SubField/SubFieldIter.h"
00049 #include "SubField/SubFieldTraits.h"
00050 #include "PETE/IpplExpressions.h"
00051 
00052 #ifdef IPPL_USE_STANDARD_HEADERS
00053 #include <iostream>
00054 using namespace std;
00055 #else
00056 #include <iostream.h>
00057 #endif
00058 
00059 // forward declarations
00060 template <class T, unsigned Dim, class S> class SubBareField;
00061 template <class T, unsigned Dim, class S> class SubFieldIter;
00062 template <class T, unsigned Dim, class S>
00063 ostream& operator<<(ostream&,const SubBareField<T,Dim,S>&);
00064 
00065 
00066 template <class T, unsigned Dim, class S>
00067 class SubBareField : public PETE_Expr< SubBareField<T,Dim,S> > {
00068 
00069   friend class BareField<T,Dim>;
00070 
00071 public:
00072   //# public typedefs
00073   typedef T T_t;
00074   typedef S Index_t;
00075   typedef SubFieldIter<T,Dim,S> iterator;
00076 
00077   //# public enumerations
00078   enum { Dim_u = Dim };
00079 
00080   // Return the beginning and end iterators for this class.
00081   iterator begin() const;
00082   iterator end() const;
00083 
00084   //
00085   // accessor functions
00086   //
00087 
00088   // return the 'domain', that is, the information which subsets the field
00089   const S& getDomain() const { return MyDomain; }
00090 
00091   // fill in the second argument with the data for the 'bounding box' of
00092   // the domain.  This could be the whole field domain, a single point, or
00093   // perhaps just a subset of the whole domain.
00094   void makeNDIndex(NDIndex<Dim> &i) { iterator::makeNDIndex(MyDomain, i); }
00095 
00096   // return a reference to the field we are subsetting
00097   BareField<T,Dim>& getBareField() const { return A; }
00098 
00099   // Return a single value.
00100   T    get() { T r; get(r); return r; }
00101   void get(T& r);
00102 
00103   // Return a typecode for the subset object
00104   static int getSubsetType() { return iterator::getSubsetType(); }
00105 
00106   // check to make sure Dim == Brackets.
00107   bool checkBrackets() const { return Brackets == Dim; }
00108 
00109   //
00110   // bracket operators
00111   //
00112 
00113   // bracket operator, which select subsets of the BareField.
00114   //mwerks template<class S2>
00115   //mwerks SubBareField<T,Dim,typename SubFieldTraits<T,Dim,S,S2>::Return_t>
00116   //mwerks operator[](const S2&);
00118   // bracket operators, which select subsets of the BareField.  This
00119   // further subsets from the current SubBareField based on the type of
00120   // input subset object.
00121   template<class S2>
00122   SubBareField<T,Dim,typename SubFieldTraits<T,Dim,S,S2>::Return_t>
00123   operator[](const S2& s) {
00124     // create a new instance of the resulting subset object
00125     typename SubFieldTraits<T,Dim,S,S2>::Return_t newdomain;
00126     TAU_TYPE_STRING(taustr, CT(newdomain) + " (" + CT(s) + " )" );
00127     TAU_PROFILE("SubBareField::operator[]()", taustr, TAU_SUBFIELD);
00128 
00129     // make sure we can subset by the number of dimensions requested, then
00130     // combine the current subset value with the new one
00131     int B = SubFieldTraits<T,Dim,S,S2>::Brackets_u;
00132     if (checkAddBrackets(B)) {
00133       SubFieldTraits<T,Dim,S,S2>::combine(MyDomain, s, newdomain, Brackets, A);
00134       Brackets += B;
00135     }
00136  
00137     // return a new SubBareField
00138     return SubBareField<T,Dim,
00139       typename SubFieldTraits<T,Dim,S,S2>::Return_t>(A,newdomain);
00140   }
00141 
00142 
00143   //
00144   // assignment operators
00145   //
00146 
00147   // assignment of another SubBareField
00148   SubBareField<T,Dim,S>& operator=(const SubBareField<T,Dim,S> &);
00149 
00150   // assignment of a scalar
00151   SubBareField<T,Dim,S>& operator=(T);
00152 
00153   // assignment of an arbitrary expression
00154   //mwerks template<class B>
00155   //mwerks SubBareField<T,Dim,S>& operator=(const PETE_Expr<B> &);
00157   // assignment of an arbitrary expression
00158   template<class B>
00159   SubBareField<T,Dim,S>&
00160   operator=(const PETE_Expr<B> &b) {
00161     TAU_TYPE_STRING(taustr, CT(*this) + " (" + CT(b) + " )" );
00162     TAU_PROFILE("SubBareField::operator=()",taustr, TAU_SUBFIELD | TAU_ASSIGN);
00163     assign(*this, b);
00164     return *this;
00165   }
00166 
00167 
00168   //
00169   // I/O
00170   //
00171 
00172   void write(ostream&);
00173 
00174   //
00175   // PETE interface
00176   //
00177 
00178   enum { IsExpr = 1 };
00179   typedef iterator PETE_Expr_t;
00180   iterator MakeExpression() const { return begin(); }
00181 
00182   // Pass operator() down to each element of type T.
00183   // Could also build versions with 2 or more arguments...
00184   // Without member templates we are restricted to passing an integer down.
00185   PETE_TUTree<OpParens<int>, iterator> operator()(int arg) {
00186     checkBrackets();
00187     typedef PETE_TUTree<OpParens<int>, iterator> Elem_t;
00188     return Elem_t(arg, begin());
00189   }
00190   PETE_TUTree< OpParens< pair<int,int> >, iterator> operator()(int a1,int a2){
00191     checkBrackets();
00192     typedef PETE_TUTree<OpParens< pair<int,int> >, iterator> Elem_t;
00193     return Elem_t(pair<int,int>(a1,a2), begin());
00194   }
00195 
00196 protected:
00197   // the field we are subsetting
00198   BareField<T,Dim>& A;
00199 
00200   // the 'domain', that is, the information which subsets the field
00201   S MyDomain;
00202 
00203   // the current number of dimensions we have indexed via bracket operators.
00204   // An expression can only be carried out if the number of brackets == Dim.
00205   unsigned int Brackets;
00206 
00207   // check to see if it is ok to add the given number of brackets to our
00208   // current number
00209   bool checkAddBrackets(unsigned int);
00210 
00211 public:
00212   // the class constructor, used by BareField or SubBareField to make a new one
00213   //mwerks template<class S2>
00214   //mwerks SubBareField(BareField<T,Dim>&, const S2&);
00216   // Make the constructor private so that only this class and it's friends
00217   // can construct them.
00218   template<class S2>
00219   SubBareField(BareField<T,Dim>& f, const S2& s) : A(f) {
00220     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(s) + " )" );
00221     TAU_PROFILE("SubBareField::SubBareField()", taustr, TAU_SUBFIELD);
00222     
00223     // initialize the subset object, to a state where it can be combined
00224     // with the given input data.  Then, put in data from given subset object.
00225     Brackets = SubFieldTraits<T,Dim,S,S2>::construct(MyDomain, s, A);
00226   }
00227 
00228 };
00229 
00230 // I/O
00231 
00232 // write a subfield to the given ostream
00233 template<class T, unsigned int Dim, class S>
00234 inline
00235 ostream& operator<<(ostream& o, const SubBareField<T,Dim,S>& s) {
00236   TAU_TYPE_STRING(taustr, "ostream (ostream, " + CT(s) + " )" );
00237   TAU_PROFILE("SubBareField::operator<<()", taustr, TAU_SUBFIELD | TAU_IO );
00238   SubBareField<T,Dim,S>& ncs = const_cast<SubBareField<T,Dim,S>&>(s);
00239   ncs.write(o);
00240   return o;
00241 }
00242 
00243 
00244 #include "SubField/SubBareField.cpp"
00245 
00246 #endif // SUB_BARE_FIELD_H
00247 
00248 /***************************************************************************
00249  * $RCSfile: SubBareField.h,v $   $Author: adelmann $
00250  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00251  * IPPL_VERSION_ID: $Id: SubBareField.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00252  ***************************************************************************/

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