DomainTraits.h File Reference
DomainTraits is a traits class for domain objects.
More...
#include "Pooma/Configuration.h"
#include "Utilities/NoInit.h"
#include "Domain/DomainTraits.int.h"
|
Classes |
struct | SizeTypePromotion< T > |
struct | SizeTypePromotion< int > |
struct | SizeTypePromotion< float > |
struct | Dom1Initialize< I > |
| Template metaprogram for initializing the storage arrays of onedimensional domain objects. More...
|
struct | Dom1Initialize< 0 > |
struct | WrapNoInit< Domain > |
| WrapNoInit is a wrapper class around Domain that changes the default constructor behavior to not init the storage. More...
|
struct | DomainTraitsDomain< DomT, T, Dim > |
| DomainTraitsDomain<DomT, T, Dim> can act as a base class for the partially- specialized versions of DomainTraits for domain-like classes, that is, classes which are derived from Domain. More...
|
struct | DomainTraitsDomain< DomT, T, 1 > |
| 1-dimensional specialized version of DomainTraitsDomain More...
|
struct | DomainTraitsScalar< DomT, T, NewDom1T > |
| DomainTraitsScalar<DomT, T, NewDom1T> can act as a base class for partially specialized versions of DomainTraits for non-domain classes and types, such as the basic scalar types. More...
|
struct | DomainTraits< T > |
| So now, finally, we can define the default version of DomainTraits<T> which just inherits from DomainTraitsScalar<T, T, T>. More...
|
struct | DomainChangeDim< T, Dim > |
| DomainChangeDim is a struct which is templated on a domain of type T, which has some original number of dimensions oldDim, and a new number of dimensions Dim. More...
|
Functions |
template<class Dom , class Storage , class T1 , class T2 > |
void | setDomain (const Dom &, Storage &data, const T1 &beg, const T2 &end) |
| global function templates for invoking DomainTraits::setDomain()
|
Detailed Description
DomainTraits is a traits class for domain objects.
Includes DomainChangeDim.
This traits class is used to specialize the Domain and DomainBase base classes for all domain objects to do the proper action for that domain type, and to store the proper information.
DomainChangeDim is a simple struct used to convert a domain of type T with a certain number of dimensions Dim1, to the same general type of domain but with a different number of dimensions Dim2. It defines two typedefs 'OldType_t' and 'NewType_t' with the type of domain with Dim1 and Dim2, respectively.
DomainTraits<T> is a traits class which provides all the specific information and functionality to specialize how a given domain object such as Loc<N> or Range<1> should store its data and interact with other domain objects. The general DomainTraits class is empty; when a new domain object is added, a new, partially specialized DomainTraits class must be written to provide the information on how that domain class should act. This domain class, along with a new class derived from Domain<DomainTraits<NewDomainType<N>>, N> and the information in NewDomain on how to combine this domain with others, is all that is needed to add a new Domain type into POOMA.
DomainTraits must be able to provide information about how the domain object can be combined with others. There are different ways in which domain objects can be combined (see NewDomain.h for a list).
Each DomainTraits class that is specialized for a specific domain object should do the following:
- DomainTraits should be templated on the main type, e.g., 'Loc<N>'.
- DomainTraits should define the following typedefs and enums:
- typedef Element_t : the type of data for the domain (e.g., int)
- typedef Size_t : the type of data for the domain's size (e.g., long)
- typedef Domain_t : the domain type (what DomainTraits is templated on
- typedef OneDomain_t : type of 1D domain which should be used to combine this domain with others
- typedef PointDomain_t : type of 1D domain that is returned if we try to convert the domain to a single point. Only singleValue'd domains can really be converted to a point; others just return OneDomain_t
- typedef AskDomain_t : the type of domain returned when asking questions about the domain, like "what are the first vals?"
- typedef Storage_t : how the data for a domain should be stored. An instance of type Storage_t is kept in DomainBase.
- typedef NewDomain1_t : the type of NewDomain1<Dom>::SliceType_t; the same as Domain_t, except for Scalar Domains.
- typedef AddResult_t : the type of domain which should result if you add or subtract this domain to a Loc or int.
- typedef MultResult_t : the type of domain which should result if you multiply or divide this domain by a Loc or int.
- enum { domain } : if true, the type derived from Domain, but if false, the type is not really a domain (such as int)
- enum { dimensions = # of dimensions }
- enum { sliceDimensions = # of slice dimensions }
- enum { loopAware } : whether domain stores info about which loop variable it refers to
- enum { singleValued } : whether domain refers to single point
- enum { unitStride } : whether domain is unit-stride sequence
- DomainTraits should include the following static methods, for multidimensional domains (that is, where Dim > 1)
- static OneDomain_t &getDomain(Domain_t& d, int dim)
- static const OneDomain_t &getDomain(const Domain_t& d, int dim) ==> return d[dim], for use in combining elements of this type of domain with others.
- static PointDomain_t &getPointDomain(Domain_t& d, int dim)
- static const PointDomain_t &getPointDomain(const Domain_t& d, int dim) ==> for single-valued domains, return the Nth 1D domain converted to a single point (such as an int or Loc, referring to a point). for a non-single-valued domain, just return the Nth 1D domain. this is used to distinguish between times when you need the domain as a single point, or converted to a larger domain (which can happen with 'getDomain').
- static void initializeStorage(Storage_t &s) ==> initialize the given storage object to an initial, default state.
- DomainTraits for a 1D domain type should include the static methods:
- static OneDomain_t &getDomain(Domain_t& d, int dim)
- static const OneDomain_t &getDomain(const Domain_t& d, int) ==> return d[0], for use in combining elements of this type of domain with others. For the 1D case, this just returns the domain object back again, regardless of dim, so that 1D objects can be combined with all N 1D domains from another multidimensional domain.
- static PointDomain_t &getPointDomain(Domain_t& d, int dim)
- static const PointDomain_t &getPointDomain(const Domain_t& d, int dim) ==> same as for the N-dim case
- static void initializeStorage(Storage_t &s) ==> initialize the given storage object to an initial, default state.
- static Element_t first(const Storage_t &d) ==> return the first endpoint of the domain, using the info in d
- static Element_t last(const Storage_t &d) ==> return the last endpoint of the domain, using the info in d
- static Size_t length(const Storage_t &d) ==> return the length of the domain, using the info in d
- static Element_t stride(const Storage_t &d) ==> return the stride of the domain, using the info in d
- static Element_t min(const Storage_t &d) ==> return the minimum endpoint of the domain, using the info in d
- static Element_t max(const Storage_t &d) ==> return the maximum endpoint of the domain, using the info in d
- static bool empty(const Storage_t &d) ==> return true if the length of the domain is 0
- static int loop(const Storage_t &d) ==> return which loop variable the domain refers to
- static Element_t elem(const Storage_t &d, int n) ==> return the Nth element in the 1D domain; the 0th elem is first(), the length()-1'th elem is last(), etc.
- template<class T> static void setDomain(Storage_t &, const T &newdom)
- static void setDomain(Storage_t &dom, int newdom) { ==> change the domain to the values in newdom, which should be a domain object with the proper interface, or an integer.
- static void setDomain(Storage_t &dom, ** necessary args **) ==> change the domain to the values from a specialized list of information, which is domain-type specific. For example, for Range, this takes three extra args: first, last, stride
- static void setLoop(Storage_t &, int loop) ==> change which loop variable is referred to
- template<class T> static bool isLessThan(const Storage_t &, const T &)
- static bool isLessThan(const Storage_t &dom, int newdom) ==> return if the domain object from the given storage is less than the second argument, either templated or specialized to int.
- template<class T> static bool isEqualTo(const Storage_t &, const T &)
- static bool isEqualTo(const Storage_t &dom, int newdom) ==> return if the domain object from the given storage is equal to the second argument, either templated or specialized to int.
- template<class T> static void addAccum(Storage_t &, const T &);
- static void addAccum(Storage_t &dom, int newdom) ==> add the value from the second argument to this domain.
- template<class T> static void subtractAccum(Storage_t &, const T &);
- static void subtractAccum(Storage_t &dom, int newdom) ==> subtract the value of the second argument from this domain.
- template<class T> static void multiplyAccum(Storage_t &, const T &);
- static void multiplyAccum(Storage_t &dom, int newdom) ==> multiply the value of this domain by the second argument
- template<class T> static void divideAccum(Storage_t &, const T &);
- static void divideAccum(Storage_t &dom, int newdom) ==> divide the value of this domain by the second argument
- DomainTraits for all 1D domains and any other scalars need to also provide the following static methods, which all take as an argument the domain object (or scalar) itself:
- static Element_t getFirst(const Domain_t &)
- static Element_t getLast(const Domain_t &)
- static Element_t getStride(const Domain_t &)
- static Size_t getLength(const Domain_t &)
- static Size_t getSize(const Domain_t &)
- static Element_t getMin(const Domain_t &)
- static Element_t getMax(const Domain_t &)
- static bool getEmpty(const Domain_t &)
- static int getLoop(const Domain_t &)
All of these methods, for domain objects, should just return the value of the relevant function (e.g., getFirst(d) returns d.first()). For non-domain objects such as scalars, they just return the scalar value itself or the relevant value (such as 'false' for getEmpty()) The base classes 'DomainTraitsDomain' and 'DomainTraitsScalar' are provided for users to inherit from which provide implementations of these static methods already, along with a couple other domain trait settings (described next).
There are two general classes of DomainTraits:
- DomainTraits for Domain classes, which provide traits for actual Domain subclasses. When defining traits of of this form, you should have the partially-specialized class derive from DomainTraitsDomain<DomT, T, Dim>, where DomT is the type for Domain_t, T is the type for Element_t, and Dim is the dimension. In this case, the base class DomainTraitsDomain provided part of the DomainTraits interface, including:
- For N-D object: Element_t, Domain_t, domain, and dimensions
- For 1-D objects: Element_t, Domain_t, domain, and dimensions get* methods (see list above), which just call the corresponding method in the provide Domain argument.
- Non-Domain DomainTraits, for things such as scalars. For all types which do not have specific DomainTraits specializations, the default behavior is to treat them as scalars, and so the default version of DomainTraits<T> is derived from DomainTraitsScalar<T, T>. The class DomainTraitsScalar is templated on the type for Domain_t and Element_t. This is a separate class (and not just the default implementation of DomainTraits) because for the special case of integral types, there is a separate DomainTraits used to convert integral scalars to Locs or Intervals when needed. If you need to provide special traits for any other scalars, then have the specialization of DomainTraits inherit from DomainTraitsScalar.
Function Documentation
template<class Dom , class Storage , class T1 , class T2 >
void setDomain |
( |
const Dom & |
, |
|
|
Storage & |
data, |
|
|
const T1 & |
beg, |
|
|
const T2 & |
end | |
|
) |
| | [inline] |