FreePOOMA  2.4.1
NewDomain
Domain Objects and Modifiers

NewDomain2 ... More...

Collaboration diagram for NewDomain:

NewDomain2 ...

TemporaryNewDomain1 is a fix for a deficiency in NewDomain1, which synthesizes SliceType_t from a single parameter, which is incorrect.

NewDomain1 ...

NewDomainNBase: a base class for all NewDomainN classes for N >= 3.

The general version of NewDomain2.

A simple base class for all specialized NewDomain2 objects, defining the functions which all have in common.

NewDomain7 are simple helper structs which are used to combine Domain objects of different types together (when possible). They are basically traits classes used to tell what the type is when you combine several domains together, and what the combined object looks like.

If you have N Domain objects to combine (where N is from 1 to 7), the type of the Domain object which results when you combine the Domain objects together is (for, say, combining 4 Domains of types T1, T2, T3, and T4 together) NewDomain4<T1,T2,T3,T4>::Type_t

The new Domain will be one of the Domain types listed in the include and forward ref sections above. Generally, combining a more specific type of domain with a more general type of domain (say, a Loc with a Range) results in return domain type of the more general category. E.g., in the case of combining a Loc with Range, the result would be a Range.

The dimension of the new Domain will be the sum of the dimensions of the input objects. The dimensions will be filled in from left to right from the arguments, going from 1 ... Dim for the dimensions. For example, if you combine three domains, the first of Dim 2, the next of Dim 1, the third of Dim 2, the result will be of Dim=5, and will have Dim 1&2 taken from the first argument, Dim 3 from the second, and Dim 4&5 from the third.

To combine domains together, there are two possibilities:

  1. combine them into a separate object, returned by the 'combine' method This takes N domain objects, and puts them into a new domain object of type NewDomainN<T1,T2,...,TN>::Type_t. The method Type_t NewDomainN<...>::combine(a,b,c,d,...) will combine the elements a, b, c, ... and return a new domain object
  2. fill them into a provided domain object, using the 'fill' method This does a similar thing as 'combine', but is more efficient since the user provides (in the first argument to 'fill') the domain object into which the elements should be combined. The syntax is void NewDomainN<...>::fill(retval,a,b,c,d,...) where a,b,c,d,... are the domain object to combine together, and retval is the domain object which should hold the result. Note that retval is a templated item, it does not have to be the same type as NewDomainN<...>::Type_t. fill returns a reference to the retval item.

Both of these methods will perform 1D assigments of pieces of the domains to the resulting domain object, using the setDomain method of a 1D domain object.

Determining the type of the combined domain is done pair-wise, starting with the first two types, then combining the result of that with the third type, etc. So, most of the work here is in NewDomain2, which must be specialized for the different possible pairwise combinations. The other NewDomainN's then use NewDomain2 and NewDomain(N-1)'s.

There is actually more than one way to combine Domain objects together. Each method has an associated set of typedef and combine/fill methods. The above discussion was just for one of these methods; the different combining methods are:

  1. "Domain/Array constructor" rules: this combining method is applicable to the situation that exists when combining domain objects together in the constructors/operator='s of domain objects. In this case, the total dimension of the resulting object is the sum of the dimensions of the arguments. Loc<1> objects are treated like single points, but int's are treated like Interval<1> objects of size 0 ... int value - 1. For this case, the typedefs and combine/fill methods are:
    • NewDomainN::Type_t; // typedef
    • NewDomainN::Type_t NewDomainN::combine(a,b,...); // combine
    • void NewDomainN::fill(retval, a, b, ...); // fill
  2. "Slice" rules: this combining method is applicable to the situation that exists when combining domain objects together in the operator()'s of Array objects. In this case, the resulting domain may represent a "slice" of the full domain which would have been created if "domain constructor" rules had been applied. The slice is actually a lower-dimensional subdomain of the complete domain. Specifying a Loc or int for one or more of the dimensions in the operator() will result in that dimension being "sliced out", so that the total dim of the slice = sum of dimensions of Interval, Range objects
    • sum dimensions of Loc and int objects. If slice rules are used, and any Loc or int objects are being combined in, the resulting domain object will be a SliceDomain subclass (e.g., SliceInterval, SliceRange, whatever is the most general based on the other combined domain types). This SliceDomain subclass is templated on the total dimension, and the slice dimension, where slicedim < totaldim. If slice rules are used, but no singleValue'd domains are used, then regular "domain constructor" rules apply. The pairwise combination mechanism only allows you to combine a SliceDomain subclass with a non-SliceDomain, which means that you cannot combine, say, a SliceInterval with a SliceRange. Since slice domain objects are only meant for internal use when constructing a subdimensional Array from a larger dimensional Array, this is all that is needed. For this case, the typedefs and methods are:
      • NewDomainN::SliceType_t; // typedef
      • NewDomainN::SliceType_t NewDomainN::combineSlice(a,b,..); // combine
      • void NewDomainN::fillSlice(retval, a, b, ...); // fill

So, to use NewDomainN objects, first determine what kind of combining rules you need in your particular context, and then use the relevant set of typedef and combine/fill methods from the list above.

This is most easily done through a base class, since we need to define several different specializations of NewDomain2.

The allowed versions of NewDomain2 are given as partial specializations of this general case. The general case assumes T1 and T2 are single-valued domains for which DomainTraits exist, that combine together to form Interval's (or Loc's for slice combine rules).

This just simplifies the work of specifying all the typedefs for the combination results. The implementations of the combine and fill routines are left to the NewDomainN classes which are derived from NewDomainNBase. T = final type in list of types for NewDomainN. Each NewDomainN is templated on N types T1 ... TN. T should be the same as TN. ND = type of lower-dimensional NewDomainN class which the subclass will build on. For example, NewDomain4<T1,..T4> should be derived from NewDomainNBase<NewDomain3<T1,T2,T3>, T4>. Thus, in this case, we have ND ==> NewDomain3<T1,T2,T3>, and T ==> T4.

NewDomain7: these build on each other pairwise, eventually returning back to NewDomain2 for the final determination. NewDomain1 does no actual combining, just a conversion; and NewDomain2 is defined already above.

We need the array's domain type in order to get the right answer when the user specifies a single AllDomain<Dim>.