Metrowerks and template member functions
John Hall
johnharveyhall at qwest.net
Fri Apr 20 05:22:31 UTC 2001
Pooma gang:
Apparently, Metrowerks has a problem with template member functions
of partially specialized classes inheriting from a partially
specialized base class being defined external to the class
declaration. As a result, some code checked in last week caused
Interval.h, Range.h and Grid.h to stop compiling. Here are versions
that compile under Metrowerks and should be identical in
functionality.
Could someone look these over and if they are OK check them in?
John Hall
-------------- next part --------------
// -*- C++ -*-
// ACL:license
// ----------------------------------------------------------------------
// This software and ancillary information (herein called "SOFTWARE")
// called POOMA (Parallel Object-Oriented Methods and Applications) is
// made available under the terms described here. The SOFTWARE has been
// approved for release with associated LA-CC Number LA-CC-98-65.
//
// Unless otherwise indicated, this SOFTWARE has been authored by an
// employee or employees of the University of California, operator of the
// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
// the U.S. Department of Energy. The U.S. Government has rights to use,
// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
// prepare derivative works and publicly display this SOFTWARE without
// charge, provided that this Notice and any statement of authorship are
// reproduced on all copies. Neither the Government nor the University
// makes any warranty, express or implied, or assumes any liability or
// responsibility for the use of this SOFTWARE.
//
// If SOFTWARE is modified to produce derivative works, such modified
// SOFTWARE should be clearly marked, so as not to confuse it with the
// version available from LANL.
//
// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
// ----------------------------------------------------------------------
// ACL:license
#ifndef POOMA_DOMAIN_GRID_H
#define POOMA_DOMAIN_GRID_H
//-----------------------------------------------------------------------------
// Class:
// Grid<int Dim>
//-----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Overview:
// Grid is a general type of integer domain, which refers to a set of points
// a0, a1, ... aN for each dimension. The points can be any ascending or
// descending sequence, there is no fixed stride. This is basically a set
// of Dim IndirectionList<int>'s, one for each dimension; the total domain
// is the tensor product of these lists. Grid<Dim> is basically an array
// of Grid<1> objects.
//
// Grid defers most of its implementation to the Domain<DomainTraits<Grid>>
// base class.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Typedefs:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes:
//-----------------------------------------------------------------------------
#include "Domain/Domain.h"
#include "Domain/DomainTraits.Grid.h"
#include "Domain/NewDomain.h"
#include "Domain/Loc.h" // needed for use of operator<<
#include <iosfwd>
//-----------------------------------------------------------------------------
// Forward Declarations:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// Full Description of Grid:
//
// Grid<N> is a domain representing a set of N numeric sequences, one
// for each dimension N. The sequences are lists of ascending or descending
// numbers, but without any fixed stride - the list for each dimension is
// an IndirectionList<int>. It does not have any concept of loop variables,
// however, like Index does, so it cannot be used in any kind of tensor-like
// expression.
//
// You can construct a Grid object using other domain objects.
// The constructors accept up to 7 domain objects of various types.
// Domain types are, for example, Loc, Grid, Interval. int may also be used
// in the constructor for Grid; it acts like a Loc<1> object
// in that context. The domain arguments for the Grid
// constructors are combined together to form a single domain object with
// a dimension equal to the sum of the arguments dimensions; for example,
// if you try to create a Grid<3> from a Loc<2> and an Interval<1>, e.g.
// Grid<3> a(Loc<2>(1,2), Interval<1>(3,5));
// the Loc<2> and Interval arguments are combined into a (2+1=3) dimensional
// domain object, used to initialize the Grid<3>. The number of dimensions
// for the arguments must be <= number of dimensions of the newly constructed
// Grid.
//
// Grid, unlike other domain objects, can also be constructed with
// IndirectionList objects. IndirectionList's look like 1D domain objects
// to the constructor of Grid, so multiple lists can be used. Grid's can
// also be used in this same way to construct other Grid's.
//
// For Grid<1>, the list of constructors includes the following:
// Grid<1> a() - default constructor, which creates an EMPTY Grid
// Grid<1> a(n) - sets the Grid to the sequence [0 ... (n-1)], stride 1
// Grid<1> a(m,n) - sets the Grid to the sequence [m ... n], stride 1 or -1
// Grid<1> a(m,n,s) - sets the Grid to the sequence [m ... n], stride s
//
// The default Grid<1> constructor initializes the Grid to be empty,
// that is, to have a length() of zero. In that case, the endpoints are
// undefined, as is any operation involving the Grid.
//
// In addition to the constructors, Grid has the following public
// interface, similar to all domain objects. There are two classes of
// interface methods, one class which includes methods which any Grid<N>
// object has, regardless of dimensions, the other class which includes extra
// interface methods that are available for just Grid<1> objects.
//
// Grid<N> interface:
// -------------------
// long size() - return the 'volume' of the domain, which is the product
// of the lenghts of the N 1D Grids
// bool empty() - return if any of the Grid<1> objects have length == 0
// Grid<1> operator[](int N) - return the Nth Grid<1> in a
// multidimensional Grid<M>. For Grid<1> objects, this just
// returns the object back.
// comparison operators: <, >, !=, ==, <=, >= : compare a Grid<N> to
// another domain object. The compared domains must have the same
// number of dimensions.
// arithmetic accumulation operators +=, -=, *=, /= : add or substract in a
// given domain. The added domain must have the same number of
// dimensions, or a dimension of 1 (in which case, the same value
// is used for all dimensions), and be known to be single-valued (which
// is true for Loc and int's). Note that for Grid, *= and /= ARE
// allowed, since Grid can have its stride changed at run time. *=
// and /= result in scaling of the endpoints and stride, which leaves
// the length (and size) the same. += and -= shift the beginning
// endpoints by the given values, also leaving the length and size the
// same. Negation of a Grid negates the endpoints and stride.
// binary arithmethic operators +, -, *, / : for + and -, adding a Grid
// to another Loc or int returns a new Grid. For * and /, scaling
// by a Loc or int also returns a Grid object, since the stride may
// change.
// increment/decrement operator ++, -- : only prefix versions of ++ and --
// are provided; they act just like += 1 and -= 1 operations.
//
// Grid<1> interface:
// -------------------
// all of the methods for Grid<N> are also available for Grid<1>. Plus:
// int length() - number of elements (including endpoints) of the domain.
// for a non-unit-stride Grid, the length refers to the number of
// strided points (including the endpoints), NOT the difference between
// the first and last endpoint. That is, length = (end-beg)/stride + 1,
// NOT (end-beg) + 1.
// int first() - the beginning endpoint.
// int last() - the ending endpoint.
// int min(), int max() - min or max of the endpoints.
// Interval<1>::iterator begin() and end() - return iterators for the 1D
// domain. These act like (at least) bidirectional iterators.
//
// For the special case of Grid<1>, there is a specialization given
// after the general case that has different constructors.
//
// Grid inherits much of its activity from Domain<DomainTraits<Grid>>
//
//-----------------------------------------------------------------------------
template<int Dim>
class Grid : public Domain<Dim, DomainTraits<Grid<Dim> > >
{
// convenience typedefs
typedef DomainTraits< Grid<Dim> > DT_t;
typedef Domain<Dim, DT_t> Base_t;
public:
// Typedefs from parent class and DomainTraits
typedef typename Base_t::iterator iterator;
typedef typename Base_t::const_iterator const_iterator;
typedef typename Base_t::blockIterator blockIterator;
typedef typename Base_t::const_blockIterator const_blockIterator;
typedef typename DT_t::Element_t Element_t;
typedef typename DT_t::Domain_t Domain_t;
typedef typename DT_t::OneDomain_t OneDomain_t;
typedef typename DT_t::BlockDomain_t BlockDomain_t;
typedef typename DT_t::AskDomain_t AskDomain_t;
typedef typename DT_t::AddResult_t AddResult_t;
typedef typename DT_t::MultResult_t MultResult_t;
typedef typename DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor : initialize to an empty domain
Grid() { }
// copy constructor
Grid(const Grid<Dim> &a) {
NewDomain1<Grid<Dim> >::fill(*this, a);
}
// templated constructors, taking from 1 to 7 different domain objects
// (or integers).
template<class T1>
explicit Grid(const T1 &a) {
NewDomain1<T1>::fill(*this, a);
}
template<class T1, class T2>
Grid(const T1 &a, const T2 &b) {
NewDomain2<T1,T2>::fill(*this, a, b);
}
template<class T1, class T2, class T3>
Grid(const T1 &a, const T2 &b, const T3 &c) {
NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
}
template<class T1, class T2, class T3, class T4>
Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d) {
NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
}
template<class T1, class T2, class T3, class T4, class T5>
Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e) {
NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6>
Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f) {
NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6, class T7>
Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f, const T7 &g) {
NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
}
//
// Destructor. For this class there is nothing to do.
//
~Grid() {
for (int i=0;i<Dim;++i)
operator[](i).~OneDomain_t();
}
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Grid<Dim> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Grid<Dim> &operator=(const Grid<Dim> &newdom) {
return NewDomain1<Grid<Dim> >::fill(*this, newdom);
}
//
// I/O/
//
// print a Grid<N> to a stream, in the format
// "[" value1,value2,...,valueN "]"
template<class Out>
void print(Out &o) const {
iterator p = begin();
iterator pend = end();
o << "[";
while (p != pend)
{
o << *p;
++p;
if (p != pend)
o << ",";
}
o << "]";
}
protected:
private:
};
//-----------------------------------------------------------------------------
//
// Full Description of Grid<1>:
//
// Grid<1> is a 1D specialization of Grid<N>; for the 1D case,
// there are only a restricted set of constructors available.
// For the special case of Grid<1>, the following constructors
// are defined:
// Grid<1> a() - default constructor, which creates an EMPTY Grid
// Grid<1> a(n) - sets the Grid to the sequence [0 ... (n-1)], stride 1
// Grid<1> a(m,n) - sets the Grid to the sequence [m ... n], stride 1 or -1
// Grid<1> a(m,n,s) - sets the Grid to the sequence [m ... n], stride s
// Grid<1> a(Domain d) : a Grid copied from d, which must be a
// 1D domain object.
//
//-----------------------------------------------------------------------------
template<>
class Grid<1> : public Domain<1, DomainTraits<Grid<1> > >
{
// convenience typedef
typedef DomainTraits< Grid<1> > DT_t;
public:
// typedefs from DomainTraits
typedef DT_t::Element_t Element_t;
typedef DT_t::Domain_t Domain_t;
typedef DT_t::OneDomain_t OneDomain_t;
typedef DT_t::BlockDomain_t BlockDomain_t;
typedef DT_t::AskDomain_t AskDomain_t;
typedef DT_t::AddResult_t AddResult_t;
typedef DT_t::MultResult_t MultResult_t;
typedef DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor
Grid() { }
// copy constructor
Grid(const Grid<1> &a) {
NewDomain1<Grid<1> >::fill(*this, a);
}
// general argument constructor, to copy from a different domain type
template<class T1>
explicit Grid(const T1 &a) {
NewDomain1<T1>::fill(*this, a);
}
// initialize from a single scalar. must specialize to all scalars.
Grid(char a) {
PAssert(a != 0);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
}
Grid(unsigned char a) {
PAssert(a != 0);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
}
Grid(short a) {
PAssert(a != 0);
short s = (a < 0 ? -1 : 1);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
}
Grid(unsigned short a) {
PAssert(a != 0);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
}
Grid(int a) {
PAssert(a != 0);
int s = (a < 0 ? -1 : 1);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
}
Grid(unsigned int a) {
PAssert(a != 0);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
}
Grid(long a) {
PAssert(a != 0);
long s = (a < 0 ? -1 : 1);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
}
Grid(unsigned long a) {
PAssert(a != 0);
DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
}
// initialize from a set of endpoints: sets range to [m ..n].
// domain_m is the domain information storage kept in the base class.
template<class T1, class T2>
Grid(const T1 &m, const T2 &n) {
DomainTraits<Grid<1> >::setDomain(domain_m, m, n);
}
// initialize from a set of endpoints and with a given stride.
// domain_m is the domain information storage kept in the base class.
template<class T1, class T2, class T3>
Grid(const T1 &m, const T2 &n, const T3 &s) {
DomainTraits<Grid<1> >::setDomain(domain_m, m, n, s);
}
//
// Destructor. For this class there is nothing to do.
//
~Grid() { }
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Grid<1> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Grid<1> &operator=(const Grid<1> &newdom) {
return NewDomain1<Grid<1> >::fill(*this, newdom);
}
//
// A special function used to initialize one Grid from another. For
// this, we need non-modifiable access to the storage.
//
const Storage_t &storage() const { return domain_m; }
//
// I/O/
//
// print a Grid<N> to a stream, in the format
// "[" value1,value2,...,valueN "]"
template<class Out>
void print(Out &o) const {
iterator p = begin();
iterator pend = end();
o << "[";
while (p != pend)
{
o << *p;
++p;
if (p != pend)
o << ",";
}
o << "]";
}
};
//////////////////////////////////////////////////////////////////////
//
// print a Grid<N> to a stream, in the format
// "[" value1,value2,...,valueN "]"
//
//////////////////////////////////////////////////////////////////////
template<int Dim>
std::ostream& operator<<(std::ostream &o, const Grid<Dim> &grid)
{
grid.print(o);
return o;
}
//////////////////////////////////////////////////////////////////////
//
// Specialization of the CHEETAH Serialize class for Grid<1>.
//
//////////////////////////////////////////////////////////////////////
#if POOMA_CHEETAH
#include "Cheetah/Cheetah.h"
namespace Cheetah {
template<>
class Serialize<CHEETAH, Grid<1> >
{
public:
typedef Grid<1> Grid_t;
typedef Grid_t::Element_t Element_t;
typedef IndirectionList<Element_t> List_t;
static inline long
size(const Grid_t &a)
{
return sizeof(int) + a.length() * sizeof(Element_t);
}
static inline int
pack(const Grid_t &a, char *buffer)
{
*reinterpret_cast<int *>(buffer) = a.length();
long length = a.length() * sizeof(Element_t);
memcpy(buffer + sizeof(int), &a.storage()(0), length);
return sizeof(int) + length;
}
static inline int
unpack(Grid_t* &a, char *buffer)
{
int length = *reinterpret_cast<int *>(buffer);
List_t list(length);
length *= sizeof(Element_t);
memcpy(&list(0), buffer + sizeof(int), length);
a = new Grid_t(list);
return sizeof(int) + length;
}
static inline void
cleanup(Grid_t* a)
{
delete a;
}
};
} // namespace Cheetah
#endif // POOMA_CHEETAH
#endif // POOMA_DOMAIN_GRID_H
// ACL:rcsinfo
// ----------------------------------------------------------------------
// $RCSfile: Grid.h,v $ $Author: cummings $
// $Revision: 1.11 $ $Date: 2001/04/13 02:12:59 $
// ----------------------------------------------------------------------
// ACL:rcsinfo
-------------- next part --------------
// -*- C++ -*-
// ACL:license
// ----------------------------------------------------------------------
// This software and ancillary information (herein called "SOFTWARE")
// called POOMA (Parallel Object-Oriented Methods and Applications) is
// made available under the terms described here. The SOFTWARE has been
// approved for release with associated LA-CC Number LA-CC-98-65.
//
// Unless otherwise indicated, this SOFTWARE has been authored by an
// employee or employees of the University of California, operator of the
// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
// the U.S. Department of Energy. The U.S. Government has rights to use,
// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
// prepare derivative works and publicly display this SOFTWARE without
// charge, provided that this Notice and any statement of authorship are
// reproduced on all copies. Neither the Government nor the University
// makes any warranty, express or implied, or assumes any liability or
// responsibility for the use of this SOFTWARE.
//
// If SOFTWARE is modified to produce derivative works, such modified
// SOFTWARE should be clearly marked, so as not to confuse it with the
// version available from LANL.
//
// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
// ----------------------------------------------------------------------
// ACL:license
#ifndef POOMA_DOMAIN_INTERVAL_H
#define POOMA_DOMAIN_INTERVAL_H
//-----------------------------------------------------------------------------
// Class:
// Interval<int>
//-----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Overview:
// Interval is a very simple type of domain, which refers to a set of points
// a, a+1, a+2, ..., b. It has a hard-coded stride of 1. Interval<N>
// is basically an array of Interval<1> objects.
//
// Interval defers most of its implementation to the
// Domain<DomainTraits<Interval>> base class.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Typedefs:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes:
//-----------------------------------------------------------------------------
#include "Domain/Domain.h"
#include "Domain/DomainTraits.Interval.h"
#include "Domain/NewDomain.h"
#include "Utilities/NoInit.h"
#include "Utilities/PAssert.h"
//-----------------------------------------------------------------------------
// Forward Declarations:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// Full Description of Interval:
//
// Interval<N> is a domain representing a set of N numeric sequences, one
// for each dimension N. The sequences have endpoints [a,b], and a
// hard-coded stride of +1. It does not have any concept of loop variables,
// however, like Index does, so it cannot be used in any kind of tensor-like
// expression.
//
// You can construct an Interval object using other domain objects.
// The constructors accept up to 7 domain objects of various types.
// Domain types are, for example, Loc, Range, Interval. int may also be used
// in the constructor for Interval; it acts like a Loc<1> object
// in that context. The domain arguments for the Interval
// constructors are combined together to form a single domain object with
// a dimension equal to the sum of the arguments dimensions; for example,
// if you try to create an Interval<3> from a Loc<2> and an Interval<1>, e.g.
// Interval<3> a(Loc<2>(1,2), Interval<1>(3,5));
// the Loc<2> and Interval arguments are combined into a (2+1=3) dimensional
// domain object, used to initialize the Interval<3>. The number of dimensions
// for the arguments must be <= number of dimensions of the newly constructed
// Interval.
//
// For Interval<1>, the list of constructors is limited to just the following:
// Interval<1> a() - default constructor, which creates an EMPTY Interval
// Interval<1> a(n) - sets the Interval to the sequence [0 ... (n-1)]
// Interval<1> a(m,n) - sets the Interval to the sequence [m ... n]
//
// The default Interval<1> constructor initializes the Interval to be empty,
// that is, to have a length() of zero. In that case, the endpoints are
// undefined, as is any operation involving the Interval.
//
// In addition to the constructors, Interval has the following public
// interface, similar to all domain objects. There are two classes of
// interface methods, one class which includes methods which any Interval<N>
// object has, regardless of dimensions, the other class which includes extra
// interface methods that are available for just Interval<1> objects.
//
// Interval<N> interface:
// ----------------------
// long size() - return the 'volume' of the domain, which is the product
// of the lenghts of the N 1D Intervals
// bool empty() - return if any of the Interval<1> objects have length == 0
// Interval<1> operator[](int N) - return the Nth Interval<1> in a
// multidimensional Interval<M>. For Interval<1> objects, this just
// returns the object back.
// comparison operators: <, >, !=, ==, <=, >= : compare an Interval <N> to
// another domain object. The compared domains must have the same
// number of dimensions.
// arithmetic accumulation operators +=, -= : add or substract in a
// given domain. The added domain must have the same number of
// dimensions, or a dimension of 1 (in which case, the same value
// is used for all dimensions), and be known to be single-valued (which
// is true for Loc and int's). Note that for Interval, *= and /= are NOT
// allowed, since these operators would change the stride and that is
// not allowed for Interval (it has a hard-coded stride of 1).
// The negation operator (operator-) is also NOT allowed for Interval.
// binary arithmethic operators +, -, *, / : for + and -, adding an Interval
// to another Loc or int returns a new Interval. For * and /, scaling
// by a Loc or int returns a Range object, since the stride may
// change.
// increment/decrement operator ++, -- : only prefix versions of ++ and --
// are provided; they act just like += 1 and -= 1 operations.
//
// Interval<1> interface:
// ----------------------
// all of the methods for Interval<N> are also available for Interval<1>.
// int length() - number of elements (including endpoints) of the domain.
// int first() - the beginning endpoint.
// int last() - the ending endpoint.
// int min(), int max() - min or max of the endpoints.
// Interval<1>::iterator begin() and end() - return iterators for the 1D
// domain. These act like (at least) bidirectional iterators.
//
// Interval inherits much of its activity from Domain<DomainTraits<Interval>>.
//
// For the special case of Interval<1>, there is a specialization given
// after the general case that has different constructors (listed above).
//
//-----------------------------------------------------------------------------
template<int Dim>
class Interval : public Domain<Dim, DomainTraits<Interval<Dim> > >
{
// convenience typedefs
typedef DomainTraits< Interval<Dim> > DT_t;
typedef Domain<Dim, DT_t> Base_t;
public:
// Typedefs from parent class and DoaminTraits
typedef typename Base_t::iterator iterator;
typedef typename Base_t::const_iterator const_iterator;
typedef typename Base_t::blockIterator blockIterator;
typedef typename Base_t::const_blockIterator const_blockIterator;
typedef typename DT_t::Element_t Element_t;
typedef typename DT_t::Domain_t Domain_t;
typedef typename DT_t::OneDomain_t OneDomain_t;
typedef typename DT_t::BlockDomain_t BlockDomain_t;
typedef typename DT_t::AskDomain_t AskDomain_t;
typedef typename DT_t::AddResult_t AddResult_t;
typedef typename DT_t::MultResult_t MultResult_t;
typedef typename DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor : initialize to an empty domain
Interval() { }
// copy constructor
Interval(const Interval<Dim> &a)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain1<Interval<Dim> >::fill(*this, a);
}
// Uninitialized constructor
Interval(const Pooma::NoInit &a)
: Domain<Dim, DomainTraits<Interval<Dim> > >(a)
{ }
// templated constructors, taking from 1 to 7 different domain objects
// (or integers).
template<class T1>
explicit Interval(const T1 &a)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain1<T1>::fill(*this, a);
}
template<class T1, class T2>
Interval(const T1 &a, const T2 &b)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain2<T1,T2>::fill(*this, a, b);
}
template<class T1, class T2, class T3>
Interval(const T1 &a, const T2 &b, const T3 &c)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
}
template<class T1, class T2, class T3, class T4>
Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
}
template<class T1, class T2, class T3, class T4, class T5>
Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6>
Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6, class T7>
Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f, const T7 &g)
: Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
}
//
// Destructor. For this class there is nothing to do.
//
~Interval() { }
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Interval<Dim> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Interval<Dim> &operator=(const Interval<Dim> &newdom) {
return NewDomain1<Interval<Dim> >::fill(*this, newdom);
}
protected:
private:
};
//-----------------------------------------------------------------------------
//
// Full Description of Interval<1>:
//
// Interval<1> is a 1D specialization of Interval<N>; for the 1D case,
// there are only a restricted set of constructors available.
// For the special case of Interval<1>, the following constructors
// are defined:
// Interval<1> a() - default constructor, which creates an EMPTY Interval
// Interval<1> a(n) - sets the Interval to the sequence [0 ... (n-1)]
// Interval<1> a(m,n) - sets the Interval to the sequence [m ... n]
// Interval<1> a(Domain d) - an Interval copied from d, which must be a
// 1D domain object.
//
//-----------------------------------------------------------------------------
template<>
class Interval<1> : public Domain<1, DomainTraits<Interval<1> > >
{
// convenience typedef
typedef DomainTraits< Interval<1> > DT_t;
public:
// typedefs from DomainTraits
typedef DT_t::Element_t Element_t;
typedef DT_t::Domain_t Domain_t;
typedef DT_t::OneDomain_t OneDomain_t;
typedef DT_t::BlockDomain_t BlockDomain_t;
typedef DT_t::AskDomain_t AskDomain_t;
typedef DT_t::AddResult_t AddResult_t;
typedef DT_t::MultResult_t MultResult_t;
typedef DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor
Interval() { }
// copy constructor
Interval(const Interval<1> &a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
NewDomain1<Interval<1> >::fill(*this, a);
}
// Uninitialized constructor
Interval(const Pooma::NoInit &a)
: Domain<1, DomainTraits<Interval<1> > >(a)
{ }
// general argument constructor, to copy from a different domain type
template<class T1>
explicit Interval(const T1 &a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
NewDomain1<T1>::fill(*this, a);
}
// initialize from a single scalar. must specialize to all scalars.
Interval(char a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(unsigned char a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(short a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(unsigned short a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(int a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(unsigned int a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(long a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
Interval(unsigned long a)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
}
// initialize from a set of endpoints: sets interval to [m ..n]. Must
// have m <= n.
template<class T1, class T2>
Interval(const T1 &m, const T2 &n)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit() ) {
DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
}
// initialize from three integers: if the stride is not 1,
// it is an error.
template<class T1, class T2, class T3>
Interval(const T1 &m, const T2 &n, const T3 &s)
: Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
PAssert(s == 1);
DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
}
//
// Destructor. For this class there is nothing to do.
//
~Interval() { }
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Interval<1> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Interval<1> &operator=(const Interval<1> &newdom) {
return NewDomain1<Interval<1> >::fill(*this, newdom);
}
};
//////////////////////////////////////////////////////////////////////
#endif // POOMA_DOMAIN_INTERVAL_H
// ACL:rcsinfo
// ----------------------------------------------------------------------
// $RCSfile: Interval.h,v $ $Author: cummings $
// $Revision: 1.17 $ $Date: 2001/04/13 02:12:59 $
// ----------------------------------------------------------------------
// ACL:rcsinfo
-------------- next part --------------
// -*- C++ -*-
// ACL:license
// ----------------------------------------------------------------------
// This software and ancillary information (herein called "SOFTWARE")
// called POOMA (Parallel Object-Oriented Methods and Applications) is
// made available under the terms described here. The SOFTWARE has been
// approved for release with associated LA-CC Number LA-CC-98-65.
//
// Unless otherwise indicated, this SOFTWARE has been authored by an
// employee or employees of the University of California, operator of the
// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
// the U.S. Department of Energy. The U.S. Government has rights to use,
// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
// prepare derivative works and publicly display this SOFTWARE without
// charge, provided that this Notice and any statement of authorship are
// reproduced on all copies. Neither the Government nor the University
// makes any warranty, express or implied, or assumes any liability or
// responsibility for the use of this SOFTWARE.
//
// If SOFTWARE is modified to produce derivative works, such modified
// SOFTWARE should be clearly marked, so as not to confuse it with the
// version available from LANL.
//
// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
// ----------------------------------------------------------------------
// ACL:license
#ifndef POOMA_DOMAIN_RANGE_H
#define POOMA_DOMAIN_RANGE_H
//-----------------------------------------------------------------------------
// Class:
// Range<int>
//-----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Overview:
// Range is a general type of integer domain, which refers to a set of points
// a, a+s, a+2s, ..., b. It has a run-time specified stride value s. It
// is basically an array of Range<1> objects.
//
// Range defers most of its implementation to the Domain<DomainTraits<Range>>
// base class.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Typedefs:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes:
//-----------------------------------------------------------------------------
#include "Domain/Domain.h"
#include "Domain/DomainTraits.Range.h"
#include "Domain/NewDomain.h"
#include "Utilities/NoInit.h"
#include "Utilities/PAssert.h"
//-----------------------------------------------------------------------------
// Forward Declarations:
//-----------------------------------------------------------------------------
template <int Dim> class Range;
template<int Dim>
inline
void fillRangeScalar(Range<Dim> &r, const int &a);
//-----------------------------------------------------------------------------
//
// Full Description of Range:
//
// Range<N> is a domain representing a set of N numeric sequences, one
// for each dimension N. The sequences have endpoints [a,b], with a stride
// s. It does not have any concept of loop variables,
// however, like Index does, so it cannot be used in any kind of tensor-like
// expression.
//
// You can construct a Range object using other domain objects.
// The constructors accept up to 7 domain objects of various types.
// Domain types are, for example, Loc, Range, Interval. int may also be used
// in the constructor for Range; it acts like a Loc<1> object
// in that context. The domain arguments for the Range
// constructors are combined together to form a single domain object with
// a dimension equal to the sum of the arguments dimensions; for example,
// if you try to create a Range<3> from a Loc<2> and an Interval<1>, e.g.
// Range<3> a(Loc<2>(1,2), Interval<1>(3,5));
// the Loc<2> and Interval arguments are combined into a (2+1=3) dimensional
// domain object, used to initialize the Range<3>. The number of dimensions
// for the arguments must be <= number of dimensions of the newly constructed
// Range.
//
// For Range<1>, the list of constructors is limited to just the following:
// Range<1> a() - default constructor, which creates an EMPTY Range
// Range<1> a(n) - sets the Range to the sequence [0 ... (n-1)], stride 1
// Range<1> a(m,n) - sets the Range to the sequence [m ... n], stride 1 or -1
// Range<1> a(m,n,s) - sets the Range to the sequence [m ... n], stride s
//
// The default Range<1> constructor initializes the Range to be empty,
// that is, to have a length() of zero. In that case, the endpoints are
// undefined, as is any operation involving the Range.
//
// In addition to the constructors, Range has the following public
// interface, similar to all domain objects. There are two classes of
// interface methods, one class which includes methods which any Range<N>
// object has, regardless of dimensions, the other class which includes extra
// interface methods that are available for just Range<1> objects.
//
// Range<N> interface:
// -------------------
// long size() - return the 'volume' of the domain, which is the product
// of the lenghts of the N 1D Ranges
// bool empty() - return if any of the Range<1> objects have length == 0
// Range<1> operator[](int N) - return the Nth Range<1> in a
// multidimensional Range<M>. For Range<1> objects, this just
// returns the object back.
// comparison operators: <, >, !=, ==, <=, >= : compare a Range<N> to
// another domain object. The compared domains must have the same
// number of dimensions.
// arithmetic accumulation operators +=, -=, *=, /= : add or substract in a
// given domain. The added domain must have the same number of
// dimensions, or a dimension of 1 (in which case, the same value
// is used for all dimensions), and be known to be single-valued (which
// is true for Loc and int's). Note that for Range, *= and /= ARE
// allowed, since Range can have its stride changed at run time. *=
// and /= result in scaling of the endpoints and stride, which leaves
// the length (and size) the same. += and -= shift the beginning
// endpoints by the given values, also leaving the length and size the
// same. Negation of a Range negates the endpoints and stride.
// binary arithmethic operators +, -, *, / : for + and -, adding a Range
// to another Loc or int returns a new Range. For * and /, scaling
// by a Loc or int also returns a Range object, since the stride may
// change.
// increment/decrement operator ++, -- : only prefix versions of ++ and --
// are provided; they act just like += 1 and -= 1 operations.
//
// Range<1> interface:
// -------------------
// all of the methods for Range<N> are also available for Range<1>. Plus:
// long length() - number of elements (including endpoints) of the domain.
// for a non-unit-stride Range, the length refers to the number of
// strided points (including the endpoints), NOT the difference between
// the first and last endpoint. That is, length = (end-beg)/stride + 1,
// NOT (end-beg) + 1.
// int first() - the beginning endpoint.
// int last() - the ending endpoint.
// int min(), int max() - min or max of the endpoints.
// Interval<1>::iterator begin() and end() - return iterators for the 1D
// domain. These act like (at least) bidirectional iterators.
//
// For the special case of Range<1>, there is a specialization given
// after the general case that has different constructors.
//
// Range inherits much of its activity from Domain<DomainTraits<Range>>
//
//-----------------------------------------------------------------------------
template<int Dim>
class Range : public Domain<Dim, DomainTraits<Range<Dim> > >
{
// convenience typedefs
typedef DomainTraits< Range<Dim> > DT_t;
typedef Domain<Dim, DT_t> Base_t;
public:
// Typedefs from parent class and DomainTraits
typedef typename Base_t::iterator iterator;
typedef typename Base_t::const_iterator const_iterator;
typedef typename Base_t::blockIterator blockIterator;
typedef typename Base_t::const_blockIterator const_blockIterator;
typedef typename DT_t::Element_t Element_t;
typedef typename DT_t::Domain_t Domain_t;
typedef typename DT_t::OneDomain_t OneDomain_t;
typedef typename DT_t::BlockDomain_t BlockDomain_t;
typedef typename DT_t::AskDomain_t AskDomain_t;
typedef typename DT_t::AddResult_t AddResult_t;
typedef typename DT_t::MultResult_t MultResult_t;
typedef typename DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor : initialize to an empty domain
Range() { }
// copy constructor
Range(const Range<Dim> &a)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain1<Range<Dim> >::fill(*this, a);
}
// Uninitialized constructor
Range(const Pooma::NoInit &a)
: Domain<Dim, DomainTraits<Range<Dim> > >(a)
{ }
// templated constructors, taking from 1 to 7 different domain objects
// (or integers).
template<class T1>
explicit Range(const T1 &a)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain1<T1>::fill(*this, a);
}
template<class T1, class T2>
Range(const T1 &a, const T2 &b)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain2<T1,T2>::fill(*this, a, b);
}
template<class T1, class T2, class T3>
Range(const T1 &a, const T2 &b, const T3 &c)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
}
template<class T1, class T2, class T3, class T4>
Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
}
template<class T1, class T2, class T3, class T4, class T5>
Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6>
Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
}
template<class T1, class T2, class T3, class T4, class T5,
class T6, class T7>
Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
const T6 &f, const T7 &g)
: Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
}
//
// Destructor. For this class there is nothing to do.
//
~Range() { }
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Range<Dim> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Range<Dim> &operator=(const Range<Dim> &newdom) {
return NewDomain1<Range<Dim> >::fill(*this, newdom);
}
Range<Dim> &operator=(const int a) {
fillRangeScalar(*this,a);
return *this;
}
protected:
private:
};
//-----------------------------------------------------------------------------
//
// Full Description of Range<1>:
//
// Range<1> is a 1D specialization of Range<N>; for the 1D case,
// there are only a restricted set of constructors available.
// For the special case of Range<1>, the following constructors
// are defined:
// Range<1> a() - default constructor, which creates an EMPTY Range
// Range<1> a(n) - sets the Range to the sequence [0 ... (n-1)], stride 1
// Range<1> a(m,n) - sets the Range to the sequence [m ... n], stride 1 or -1
// Range<1> a(m,n,s) - sets the Range to the sequence [m ... n], stride s
// Range<1> a(Domain d) : a Range copied from d, which must be a
// 1D domain object.
//
//-----------------------------------------------------------------------------
template<>
class Range<1> : public Domain<1, DomainTraits<Range<1> > >
{
// convenience typedef
typedef DomainTraits< Range<1> > DT_t;
public:
// typedefs from DomainTraits
typedef DT_t::Element_t Element_t;
typedef DT_t::Domain_t Domain_t;
typedef DT_t::OneDomain_t OneDomain_t;
typedef DT_t::BlockDomain_t BlockDomain_t;
typedef DT_t::AskDomain_t AskDomain_t;
typedef DT_t::AddResult_t AddResult_t;
typedef DT_t::MultResult_t MultResult_t;
typedef DT_t::Storage_t Storage_t;
// duplicate static data from traits class
static const bool domain = DT_t::domain;
static const int dimensions = DT_t::dimensions;
static const int sliceDimensions = DT_t::sliceDimensions;
static const bool loopAware = DT_t::loopAware;
static const bool singleValued = DT_t::singleValued;
static const bool unitStride = DT_t::unitStride;
static const bool wildcard = DT_t::wildcard;
//
// Constructors.
//
// default constructor
Range() { }
// copy constructor
Range(const Range<1> &a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
NewDomain1<Range<1> >::fill(*this, a);
}
// Uninitialized constructor
Range(const Pooma::NoInit &a)
: Domain<1, DomainTraits<Range<1> > >(a)
{ }
// general argument constructor, to copy from a different domain type
template<class T1>
explicit Range(const T1 &a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
NewDomain1<T1>::fill(*this, a);
}
// initialize from a single scalar. must specialize to all scalars.
Range(char a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
}
Range(unsigned char a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
}
Range(short a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
short s = (a < 0 ? -1 : 1);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
}
Range(unsigned short a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
}
Range(int a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
int s = (a < 0 ? -1 : 1);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
}
Range(unsigned int a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
}
Range(long a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
long s = (a < 0 ? -1 : 1);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
}
Range(unsigned long a)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
PAssert(a != 0);
DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
}
// initialize from a set of endpoints: sets range to [m ..n].
// domain_m is the domain information storage kept in the base class.
template<class T1, class T2>
Range(const T1 &m, const T2 &n)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
DomainTraits<Range<1> >::setDomain(domain_m, m, n);
}
// initialize from a set of endpoints and with a given stride.
// domain_m is the domain information storage kept in the base class.
template<class T1, class T2, class T3>
Range(const T1 &m, const T2 &n, const T3 &s)
: Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
DomainTraits<Range<1> >::setDomain(domain_m, m, n, s);
}
//
// Destructor. For this class there is nothing to do.
//
~Range() { }
//
// operator=, templated to allow assignment from other domain objects
// this uses the same mechanism as the constructors to fill in to this
// object the data from the given object. If the new object has too
// few dimensions, this will only change the first M dimensions of this
// object, where M is the number of dimensions for newdom
//
template<class T>
Range<1> &operator=(const T &newdom) {
return NewDomain1<T>::fill(*this, newdom);
}
Range<1> &operator=(const Range<1> &newdom) {
return NewDomain1<Range<1> >::fill(*this, newdom);
}
};
template<int Dim>
inline
void fillRangeScalar(Range<Dim> &r, const int &a)
{
for (int i=0; i < Dim; ++i)
r[i]=Range<1>(a);
}
//////////////////////////////////////////////////////////////////////
#endif // POOMA_DOMAIN_RANGE_H
// ACL:rcsinfo
// ----------------------------------------------------------------------
// $RCSfile: Range.h,v $ $Author: cummings $
// $Revision: 1.18 $ $Date: 2001/04/13 02:12:59 $
// ----------------------------------------------------------------------
// ACL:rcsinfo
More information about the pooma-dev
mailing list