#include <sys/time.h>
#include <cstddef>
#include <time.h>
#include <fenv.h>
#include <cstdarg>
#include <complex>
#include <algorithm>
#include <limits>
#include <math.h>
#include <cstring>

namespace Smarts {
template<class T>
class IterateScheduler;
template<class T>
class Iterate;
template<class T>
class DataObject;
}
namespace Smarts {
class Runnable
{
public:
  Runnable()
  {
    priority_m = 0;
  }
  Runnable(int)
  {
    priority_m = 0;
  }
  virtual ~Runnable() {}
  inline int
  priority() { return priority_m; }
  inline void
  priority(int _priority) { priority_m = _priority; }
  virtual void execute()
  {
    run();
  }
protected:
  virtual void run() {}
private:
  int priority_m;
};
typedef Runnable *RunnablePtr_t;
inline void add(RunnablePtr_t);
}
namespace Smarts {
class Stub
{
public:
  enum Action { Read, Write };
};
template<> class Iterate<Stub>;
template<> class IterateScheduler<Stub>;
template<> class DataObject<Stub>;
template<>
class Iterate<Stub> : public Runnable
{
public:
  inline Iterate(IterateScheduler<Stub> & scheduler, int affinity=-1);
  virtual ~Iterate() {}
  virtual void run() = 0;
  int affinity() { return 0; }
  int hintAffinity() { return 0; }
  void affinity(int) {}
  void hintAffinity(int) {}
  void generation(int gen) { generation_m=gen; }
  int generation() { return generation_m; }
protected:
  IterateScheduler<Stub> &scheduler_m;
private:
  int generation_m;
};
template<>
class IterateScheduler<Stub>
{
public:
  inline
  void beginGeneration() { generation_m++; }
  inline
  void endGeneration() {}
  inline
  void blockingEvaluate() {}
  inline
  void releaseIterates() { }
  inline
  IterateScheduler()
    : generation_m(0)
  { }
  inline
  ~IterateScheduler() {}
  inline int generation() const { return generation_m; }
  inline
  void handOff(Iterate<Stub>* it)
  {
    it->run();
    delete it;
  }
protected:
private:
  int generation_m;
};
inline Iterate<Stub>::Iterate(IterateScheduler<Stub> & scheduler, int)
  : scheduler_m(scheduler)
{
  generation(scheduler.generation());
}
template<>
class DataObject<Stub>
{
public:
    inline DataObject(int=-1) {}
    inline int affinity() const { return 0; };
    inline void affinity(int) {}
    inline void request(Iterate<Stub>&, Stub::Action) {}
    inline void release(Stub::Action) {}
protected:
private:
};
inline void concurrency(int)
{
}
inline int concurrency()
{
  return 1;
}
inline void wait()
{
}
inline void add(Runnable *runnable)
{
  runnable->execute();
  delete runnable;
}
}
namespace Pooma {
  typedef Smarts::Stub SmartsTag_t;
}
namespace Pooma {
static const char schedulerVersion[] = "stub scheduler";
typedef Smarts::IterateScheduler<SmartsTag_t> Scheduler_t;
typedef Smarts::DataObject<SmartsTag_t> DataObject_t;
typedef Smarts::Iterate<SmartsTag_t> Iterate_t;
typedef Smarts::Runnable Runnable_t;
inline void addRunnable(Runnable_t *runnable)
{
  Smarts::add(runnable);
}
}
namespace Pooma {
class Assertion
{
  char *msg_m;
  char *file_m;
  int line_m;
public:
  Assertion(const char *msg, const char *file, int line);
  Assertion(const Assertion &a);
  ~Assertion() { delete[] msg_m; delete [] file_m; }
  Assertion &operator=(const Assertion &a);
  const char *what() const { return msg_m; }
  const char *file() const { return file_m; }
  int line() const { return line_m; }
  template<class OS>
  void print(OS &os) const
  {
    os << "### POOMA Assertion Failure ###\n";
    os << "### " << what() << "\n";
    os << "### File " << file() << "; Line " << line();
  }
};
void toss_cookies(const char *msg, const char *file, int line ...) __attribute__((noreturn));
}
template<bool B> struct PoomaCTAssert {};
template<> struct PoomaCTAssert<true> { static inline void test() {} };
template<class T1, class T2>
struct SameType
{
  enum { same = false };
};
template<class T1>
struct SameType<T1, T1>
{
  enum { same = true };
};
namespace Pooma {
  class DummyMutex
  {
  public:
    inline DummyMutex() { }
    inline DummyMutex(const DummyMutex &) { }
    inline DummyMutex &operator=(const DummyMutex &) { return *this; }
    inline void lock() { }
    inline void unlock() { }
  };
  typedef DummyMutex Mutex_t;
}
#include <iostream>
#include <map>
class InformStream;
class Inform
{
public:
  typedef int ID_t;
  typedef int Level_t;
  typedef int Context_t;
  enum { out, app };
  enum { allContexts = (-1) };
  enum { off = (-1), on = 0 };
  Inform(const char *prefix = 0, Context_t outputContext = 0);
  Inform(const char *prefix, const char *fname, int writemode,
  Context_t outputContext = 0);
  Inform(const char *prefix, std::ostream &outstream,
  Context_t outputContext = 0);
  ~Inform();
  const std::string &prefix() const { return prefix_m; }
  void setPrefix(const char *prefix = 0);
  ID_t open(Context_t context = 0);
  ID_t open(const char *fname, int writemode, Context_t context = 0);
  ID_t open(std::ostream &outstream, Context_t context = 0);
  void close(ID_t);
  void close();
  Level_t messageLevel() const { return level_m; }
  Inform &setMessageLevel(Level_t newval) { level_m = newval; return *this; }
  Level_t outputLevel(ID_t id = 0) const;
  void setOutputLevel(Level_t newval, ID_t id);
  void setOutputLevel(Level_t newval);
  Context_t outputContext(ID_t id = 0) const;
  void setOutputContext(Context_t outputContext, ID_t id);
  void setOutputContext(Context_t outputContext);
  inline static Context_t context() { return context_s; }
  inline static Context_t numContexts() { return nContexts_s; }
  static inline void setContext(Context_t c) { context_s = c; }
  static inline void setNumContexts(Context_t n) { nContexts_s = n; }
  void flush();
  void print() { flush(); }
  void output() { flush(); }
  typedef std::ios_base::fmtflags FmtFlags_t;
  std::ostream& stream() { return *message_m; }
  FmtFlags_t
    setf(FmtFlags_t setbits,FmtFlags_t field)
    { return message_m->setf(setbits,field);}
  FmtFlags_t
    setf(FmtFlags_t f) { return message_m->setf(f); }
  void unsetf(FmtFlags_t f) { message_m->unsetf(f); }
  long flags() const { return message_m->flags(); }
  long flags(FmtFlags_t f) { return message_m->flags(f); }
  int width() const { return message_m->width(); }
  int width(int w) { return message_m->width(w); }
  char fill() const { return message_m->fill(); }
  char fill(char c) { return message_m->fill(c); }
  int precision() const { return message_m->precision(); }
  int precision(int p) { return message_m->precision(p); }
  void lock() const { mutex_m.lock(); }
  void unlock() const { mutex_m.unlock(); }
private:
  typedef std::map<ID_t, InformStream *> StreamList_t;
  typedef StreamList_t::size_type Size_t;
  typedef StreamList_t::value_type Value_t;
  typedef StreamList_t::iterator iterator;
  typedef StreamList_t::const_iterator const_iterator;
  std::string prefix_m;
  Context_t outputContext_m;
  Level_t level_m;
  StreamList_t streams_m;
  std::ostringstream *message_m;
  char *buffer_m;
  static const unsigned int bufSize;
  ID_t nextID_m;
  mutable Pooma::Mutex_t mutex_m;
  static Pooma::Mutex_t outputMutex_s;
  static Context_t context_s;
  static Context_t nContexts_s;
  InformStream *findStream(ID_t) const;
  void setup(const char *prefix);
};
namespace std {
  extern Inform &endl(Inform &);
  extern Inform &flush(Inform &);
  extern Inform &lock(Inform &);
  extern Inform &unlock(Inform &);
}
inline Inform &operator<<(Inform &o, Inform &(*d)(Inform &))
{
  return d(o);
}
inline Inform &operator<<(Inform &o, std::ios_base &(*d)(std::ios_base &))
{
  d(o.stream());
  return o;
}
template<class T>
inline Inform &operator<<(Inform &o, const T &val)
{
  o.stream() << val;
  return o;
}
inline Inform &operator<<(Inform &o, const void *val)
{
  Inform::FmtFlags_t oldformat =
    o.setf(std::ios::hex, std::ios::basefield);
  o.stream() << "0x" << reinterpret_cast<long>(val);
  o.setf(oldformat, std::ios::basefield);
  return o;
}
inline Inform &operator<<(Inform &o, const char *s)
{
  o.stream() << s;
  return o;
}
inline Inform &operator<<(Inform &o, const std::string &s)
{
  o.stream() << s.c_str();
  return o;
}
#include <iterator>
template <class T>
class InformIterator
{
public:
  typedef std::output_iterator_tag iterator_category;
  typedef void value_type;
  typedef void difference_type;
  typedef void pointer;
  typedef void reference;
  InformIterator(Inform &s) : out_m(&s), delim_m(0) { }
  InformIterator(Inform &s, const char *d) : out_m(&s), delim_m(d) { }
  InformIterator &operator=(const T &value)
  {
    *out_m << value;
    if (delim_m != 0)
      *out_m << delim_m;
    return *this;
  }
  InformIterator &operator*() { return *this; }
  InformIterator &operator++() { return *this; }
  InformIterator &operator++(int) { return *this; }
private:
  Inform *out_m;
  const char *delim_m;
};
namespace Pooma {
class Options
{
public:
  Options();
  Options(int &argc, char ** argv);
  Options(const Options &opts);
  Options &operator=(const Options &opts);
  ~Options();
  int concurrency() const { return concurrency_m; }
  void concurrency(int c)
    {
      ;
      concurrency_m = c;
    }
  bool printInfo() const { return info_m; }
  void printInfo(bool p) { info_m = p; }
  bool printWarnings() const { return warn_m; }
  void printWarnings(bool p) { warn_m = p; }
  bool printErrors() const { return err_m; }
  void printErrors(bool p) { err_m = p; }
  const std::string &logfile() const { return logfile_m; }
  void logfile(const std::string &s) { logfile_m = s; }
  bool printStats() const { return stats_m; }
  void printStats(bool p) { stats_m = p; }
  int debug() const { return debug_m; }
  void debug(int p) { debug_m = p; }
  bool neverCompress() const { return neverCompress_m; }
  void neverCompress(bool p) { neverCompress_m = p; }
  bool deferredGuardFills() const { return deferredFills_m; }
  void deferredGuardFills(bool p) { deferredFills_m = p; }
  bool hardInit() const { return hardinit_m; }
  void hardInit(bool p) { hardinit_m = p; }
  bool hardRun() const { return hardrun_m; }
  void hardRun(bool p) { hardrun_m = p; }
  bool lockThreads() const { return lockthreads_m; }
  void lockThreads(bool p) { lockthreads_m = p; }
  bool blockingExpressions() const { return blockingExpressions_m; }
  void blockingExpressions(bool p) { blockingExpressions_m = p; }
  void usage();
  void reset();
  void parse(int &argc, char ** &argv);
private:
  int concurrency_m;
  bool info_m;
  bool warn_m;
  bool err_m;
  std::string logfile_m;
  bool stats_m;
  int debug_m;
  bool neverCompress_m;
  bool deferredFills_m;
  bool hardinit_m;
  bool hardrun_m;
  bool lockthreads_m;
  bool blockingExpressions_m;
};
bool intArgument(int argc, char **argv, int pos, int &val);
bool stringArgument(int argc, char **argv, int pos, std::string &val);
bool doubleArgument(int argc, char **argv, int pos, double &val);
}
namespace Pooma {
  typedef void (*AbortHandler_t)();
  typedef int Context_t;
  typedef int PatchID_t;
  namespace Arch {
    inline void dawdle() { }
    inline void getCommandLineArguments(int &, char** &) { }
    inline void initialize() { }
    inline void finalize() { }
  }
  void incrementNumExpressions(long val = 1);
  void incrementNumMultiPatchExpressions(long val = 1);
  void incrementNumZBExpressions(long val = 1);
  void incrementNumCompressedAssigns(long val = 1);
  void incrementNumAssignsRequiringUnCompression(long val = 1);
  void incrementNumInlineEvaluations(long val = 1);
  void incrementNumLocalPatchesEvaluated(long val = 1);
  void incrementNumReductions(long val = 1);
  void incrementNumUnCompresses(long val = 1);
  void incrementNumUnsuccessfulTryCompresses(long val = 1);
  void incrementNumSuccessfulTryCompresses(long val = 1);
  void incrementNumPolls(long val = 1);
  extern Inform pinfo;
  extern Inform pwarn;
  extern Inform perr;
  extern Inform pdebug;
  bool initialize(int &argc, char ** &argv,
    bool initRTS = true, bool getCLArgsArch = true, bool initArch = true);
  bool initialize(Pooma::Options &opts, bool initRTS = true,
    bool initArch = true);
  bool finalize();
  bool finalize(bool quitRTS, bool quitArch);
  void pAbort(int errorcode = 0) __attribute__((noreturn));
  void pAbort(const char *msg, int errorcode = 0) __attribute__((noreturn));
  void stopHere();
  AbortHandler_t abortHandler();
  AbortHandler_t abortHandler(AbortHandler_t);
  AbortHandler_t resetAbortHandler();
  const char *version();
  int majorVersion();
  int minorVersion();
  const char *buildDate();
  bool printStats();
  void printStats(bool on);
  bool infoMessages();
  void infoMessages(bool on);
  bool warnMessages();
  void warnMessages(bool on);
  bool errorMessages();
  void errorMessages(bool on);
  void logMessages(const char *filename);
  int debugLevel();
  void debugLevel(int val);
  bool neverCompress();
  void neverCompress(bool p);
  bool deferredGuardFills();
  void deferredGuardFills(bool p);
  extern Context_t myContext_g;
  extern int numContexts_g;
  extern int expression_g;
  inline Context_t context() { return myContext_g; }
  inline int contexts() { return numContexts_g; }
  Scheduler_t &scheduler();
  void blockAndEvaluate();
  bool hardInit();
  void hardInit(bool on);
  bool hardRun();
  void hardRun(bool on);
  bool lockThreads();
  void lockThreads(bool on);
  bool blockingExpressions();
  void blockingExpressions(bool on);
  inline void beginExpression()
  {
    scheduler().beginGeneration();
  }
  inline void endExpression()
  {
    scheduler().endGeneration();
    expression_g++;
    if (blockingExpressions())
      blockAndEvaluate();
  }
  inline int expression()
  {
    return expression_g;
  }
inline void poll()
{
    ;
}
}
template<int Dim, class T, class EngineTag> class Array;
template<int Dim, class T, class EngineTag> class Engine;
template<class Subject, class Sub1, bool SV>
struct View1Implementation;
template <class LayoutTag, class PatchTag>
struct MultiPatch;
template <class LayoutTag, class PatchTag, int Dim2>
struct MultiPatchView;
template<class Expr>
struct ExpressionTag;
template <int Dim, class T, class EngineTag>
class Engine;
template <class Engine, class SubDomain>
struct NewEngine
{
};
template <class Engine, class SubDomain>
struct NewEngineEngine
{
  typedef Engine Type_t;
  static inline
  const Engine &apply(const Engine &e, const SubDomain &)
  {
    return e;
  }
} ;
template <class Engine, class SubDomain>
struct NewEngineDomain
{
  typedef SubDomain Type_t;
  typedef const SubDomain &Return_t;
  static inline
  Return_t apply(const Engine &, const SubDomain &i)
  {
    return i;
  }
} ;
template<class Eng, class Dom>
inline typename NewEngineEngine<Eng, Dom>::Type_t
newEngineEngine(const Eng &e, const Dom &dom)
{
  return NewEngineEngine<Eng, Dom>::apply(e, dom);
}
template<class Eng, class Dom>
inline typename NewEngineDomain<Eng, Dom>::Type_t
newEngineDomain(const Eng &e, const Dom &dom)
{
  return NewEngineDomain<Eng, Dom>::apply(e, dom);
}
struct EngineConstructTag
{
  EngineConstructTag() { };
  ~EngineConstructTag() { };
  EngineConstructTag(const EngineConstructTag &) { };
  EngineConstructTag &operator=(const EngineConstructTag &) { return *this; }
};
template<class T>
class Scalar
{
public:
  inline
  Scalar() { }
  inline
  Scalar(const T &t) : scalar_m(t) { }
  template<class T1>
  inline
  explicit Scalar(const T1 &t) : scalar_m(t) { }
  template<class Arg>
  inline
  Scalar(const Scalar<T> &s, const Arg &)
    : scalar_m(s.scalar_m) { }
  template<class Arg1, class Arg2>
  inline
  Scalar(const Scalar<T> &s, const Arg1 &, const Arg2 &)
    : scalar_m(s.scalar_m) { }
  inline
  Scalar(const Scalar<T> &s) : scalar_m(s.scalar_m) { }
  inline
  const T &value() const { return scalar_m; }
  inline
  Scalar<T> &operator=(const Scalar<T> &rhs)
  {
    scalar_m = rhs.scalar_m;
    return *this;
  }
  inline
  Scalar<T> &operator=(const T &rhs)
  {
    scalar_m = rhs;
    return *this;
  }
private:
  T scalar_m;
};
template<class T, class Op>
struct UnaryReturn {
  typedef T Type_t;
};
template<class T1, class T2>
struct Promote { typedef T1 Type_t; };
template<>
struct Promote<bool, bool> {
  typedef bool Type_t;
};
template<>
struct Promote<bool, char> {
  typedef char Type_t;
};
template<>
struct Promote<bool, short> {
  typedef short Type_t;
};
template<>
struct Promote<bool, int> {
  typedef int Type_t;
};
template<>
struct Promote<bool, long> {
  typedef long Type_t;
};
template<>
struct Promote<bool, float> {
  typedef float Type_t;
};
template<>
struct Promote<bool, double> {
  typedef double Type_t;
};
template<>
struct Promote<char, bool> {
  typedef char Type_t;
};
template<>
struct Promote<char, char> {
  typedef char Type_t;
};
template<>
struct Promote<char, short> {
  typedef short Type_t;
};
template<>
struct Promote<char, int> {
  typedef int Type_t;
};
template<>
struct Promote<char, long> {
  typedef long Type_t;
};
template<>
struct Promote<char, float> {
  typedef float Type_t;
};
template<>
struct Promote<char, double> {
  typedef double Type_t;
};
template<>
struct Promote<short, bool> {
  typedef short Type_t;
};
template<>
struct Promote<short, char> {
  typedef short Type_t;
};
template<>
struct Promote<short, short> {
  typedef short Type_t;
};
template<>
struct Promote<short, int> {
  typedef int Type_t;
};
template<>
struct Promote<short, long> {
  typedef long Type_t;
};
template<>
struct Promote<short, float> {
  typedef float Type_t;
};
template<>
struct Promote<short, double> {
  typedef double Type_t;
};
template<>
struct Promote<int, bool> {
  typedef int Type_t;
};
template<>
struct Promote<int, char> {
  typedef int Type_t;
};
template<>
struct Promote<int, short> {
  typedef int Type_t;
};
template<>
struct Promote<int, int> {
  typedef int Type_t;
};
template<>
struct Promote<int, long> {
  typedef long Type_t;
};
template<>
struct Promote<int, float> {
  typedef float Type_t;
};
template<>
struct Promote<int, double> {
  typedef double Type_t;
};
template<>
struct Promote<long, bool> {
  typedef long Type_t;
};
template<>
struct Promote<long, char> {
  typedef long Type_t;
};
template<>
struct Promote<long, short> {
  typedef long Type_t;
};
template<>
struct Promote<long, int> {
  typedef long Type_t;
};
template<>
struct Promote<long, long> {
  typedef long Type_t;
};
template<>
struct Promote<long, float> {
  typedef float Type_t;
};
template<>
struct Promote<long, double> {
  typedef double Type_t;
};
template<>
struct Promote<float, bool> {
  typedef float Type_t;
};
template<>
struct Promote<float, char> {
  typedef float Type_t;
};
template<>
struct Promote<float, short> {
  typedef float Type_t;
};
template<>
struct Promote<float, int> {
  typedef float Type_t;
};
template<>
struct Promote<float, long> {
  typedef float Type_t;
};
template<>
struct Promote<float, float> {
  typedef float Type_t;
};
template<>
struct Promote<float, double> {
  typedef double Type_t;
};
template<>
struct Promote<double, bool> {
  typedef double Type_t;
};
template<>
struct Promote<double, char> {
  typedef double Type_t;
};
template<>
struct Promote<double, short> {
  typedef double Type_t;
};
template<>
struct Promote<double, int> {
  typedef double Type_t;
};
template<>
struct Promote<double, long> {
  typedef double Type_t;
};
template<>
struct Promote<double, float> {
  typedef double Type_t;
};
template<>
struct Promote<double, double> {
  typedef double Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn {
  typedef typename Promote<T1, T2>::Type_t Type_t;
};
template<class T1, class T2, class T3, class Op>
struct TrinaryReturn {
  typedef typename BinaryReturn<T2, T3, Op>::Type_t Type_t;
};
template<class T>
struct Reference
{
  typedef T Type_t;
  inline
  Reference(const T &reference)
    : reference_m(reference)
  { }
  inline
  Reference(const Reference<T> &model)
    : reference_m(model.reference())
  { }
  inline
  const T &reference() const
  {
    return reference_m;
  }
  operator const T& () const { return reference_m; }
  operator T& () const { return const_cast<T&>(reference_m); }
  const T &reference_m;
};
template<class T>
struct DeReference
{
  typedef const T &Return_t;
  typedef T Type_t;
  static inline Return_t apply(const T &a) { return a; }
};
template<class T>
struct DeReference<Reference<T> >
{
  typedef const T &Return_t;
  typedef T Type_t;
  static inline Return_t apply(const Reference<T> &a) { return a.reference(); }
};
template<class Op, class Child>
class UnaryNode
{
public:
  inline
  typename DeReference<Child>::Return_t
  child() const { return DeReference<Child>::apply(child_m); }
  inline
  UnaryNode(const Child &c)
    : child_m(c) { }
  inline
  UnaryNode(const UnaryNode<Op, Child> &t)
    : child_m(t.child()) { }
  template<class OtherChild>
  inline
  UnaryNode(const UnaryNode<Op, OtherChild> &t)
    : child_m(t.child()) { }
  template<class OtherChild, class Arg>
  inline
  UnaryNode(const UnaryNode<Op, OtherChild> &t, const Arg &a)
    : child_m(t.child(), a) { }
  template<class OtherChild, class Arg1, class Arg2>
  inline
  UnaryNode(const UnaryNode<Op, OtherChild> &t,
     const Arg1 &a1, const Arg2 &a2)
    : child_m(t.child(), a1, a2)
    { }
private:
  Child child_m;
};
template<class Op, class Left, class Right>
class BinaryNode
{
public:
  inline
  typename DeReference<Left>::Return_t
  left() const { return DeReference<Left>::apply(left_m); }
  inline
  typename DeReference<Right>::Return_t
  right() const { return DeReference<Right>::apply(right_m); }
  inline
  BinaryNode(const Left &l, const Right &r)
    : left_m(l), right_m(r)
  { }
  inline
  BinaryNode(const BinaryNode<Op, Left, Right> &t)
    : left_m(t.left()), right_m(t.right())
  { }
  template<class OtherLeft, class OtherRight>
  inline
  BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t)
    : left_m(t.left()), right_m(t.right())
  { }
  template<class OtherLeft, class OtherRight, class Arg>
  inline
  BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t,
      const Arg &a)
    : left_m(t.left(), a), right_m(t.right(), a)
  { }
  template<class OtherLeft, class OtherRight, class Arg1, class Arg2>
  inline
  BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t,
      const Arg1 &a1, const Arg2 &a2)
    : left_m(t.left(), a1, a2), right_m(t.right(), a1, a2)
  { }
private:
  Left left_m;
  Right right_m;
};
template< class Op, class Left, class Middle, class Right>
class TrinaryNode
{
public:
  inline
  typename DeReference<Left>::Return_t
  left() const { return DeReference<Left>::apply(left_m); }
  inline
  typename DeReference<Right>::Return_t
  right() const { return DeReference<Right>::apply(right_m); }
  inline
  typename DeReference<Middle>::Return_t
  middle() const { return DeReference<Middle>::apply(middle_m); }
  inline
  TrinaryNode(const Left &l, const Middle &m, const Right &r)
    : left_m(l), middle_m(m), right_m(r)
  { }
  inline
  TrinaryNode(const TrinaryNode<Op, Left, Middle, Right> &t)
    : left_m(t.left()), middle_m(t.middle()), right_m(t.right())
  { }
  template<class OtherLeft, class OtherMiddle, class OtherRight>
  inline
  TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> & t)
    : left_m(t.left()), middle_m(t.middle()), right_m(t.right())
  { }
  template<class OtherLeft, class OtherMiddle, class OtherRight, class Arg>
  inline
  TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> &t,
       const Arg &a)
    : left_m(t.left(), a), middle_m(t.middle(), a), right_m(t.right(), a)
  { }
  template<class OtherLeft, class OtherMiddle, class OtherRight,
    class Arg1, class Arg2>
  inline
  TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> &t,
       const Arg1 &a1, const Arg2 &a2)
    : left_m(t.left(), a1, a2),
      middle_m(t.middle(), a1, a2) , right_m(t.right(), a1, a2)
  { }
private:
  Left left_m;
  Middle middle_m;
  Right right_m;
};
struct FnArcCos
{
 
  template<class T>
  inline typename UnaryReturn<T, FnArcCos >::Type_t
  operator()(const T &a) const
  {
    return (acos(a));
  }
};
struct FnArcSin
{
 
  template<class T>
  inline typename UnaryReturn<T, FnArcSin >::Type_t
  operator()(const T &a) const
  {
    return (asin(a));
  }
};
struct FnArcTan
{
 
  template<class T>
  inline typename UnaryReturn<T, FnArcTan >::Type_t
  operator()(const T &a) const
  {
    return (atan(a));
  }
};
struct FnCeil
{
 
  template<class T>
  inline typename UnaryReturn<T, FnCeil >::Type_t
  operator()(const T &a) const
  {
    return (ceil(a));
  }
};
struct FnCos
{
 
  template<class T>
  inline typename UnaryReturn<T, FnCos >::Type_t
  operator()(const T &a) const
  {
    return (cos(a));
  }
};
struct FnHypCos
{
 
  template<class T>
  inline typename UnaryReturn<T, FnHypCos >::Type_t
  operator()(const T &a) const
  {
    return (cosh(a));
  }
};
struct FnExp
{
 
  template<class T>
  inline typename UnaryReturn<T, FnExp >::Type_t
  operator()(const T &a) const
  {
    return (exp(a));
  }
};
struct FnFabs
{
 
  template<class T>
  inline typename UnaryReturn<T, FnFabs >::Type_t
  operator()(const T &a) const
  {
    return (fabs(a));
  }
};
struct FnFloor
{
 
  template<class T>
  inline typename UnaryReturn<T, FnFloor >::Type_t
  operator()(const T &a) const
  {
    return (floor(a));
  }
};
struct FnLog
{
 
  template<class T>
  inline typename UnaryReturn<T, FnLog >::Type_t
  operator()(const T &a) const
  {
    return (log(a));
  }
};
struct FnLog10
{
 
  template<class T>
  inline typename UnaryReturn<T, FnLog10 >::Type_t
  operator()(const T &a) const
  {
    return (log10(a));
  }
};
struct FnSin
{
 
  template<class T>
  inline typename UnaryReturn<T, FnSin >::Type_t
  operator()(const T &a) const
  {
    return (sin(a));
  }
};
struct FnHypSin
{
 
  template<class T>
  inline typename UnaryReturn<T, FnHypSin >::Type_t
  operator()(const T &a) const
  {
    return (sinh(a));
  }
};
struct FnSqrt
{
 
  template<class T>
  inline typename UnaryReturn<T, FnSqrt >::Type_t
  operator()(const T &a) const
  {
    return (sqrt(a));
  }
};
struct FnTan
{
 
  template<class T>
  inline typename UnaryReturn<T, FnTan >::Type_t
  operator()(const T &a) const
  {
    return (tan(a));
  }
};
struct FnHypTan
{
 
  template<class T>
  inline typename UnaryReturn<T, FnHypTan >::Type_t
  operator()(const T &a) const
  {
    return (tanh(a));
  }
};
struct OpUnaryMinus
{
 
  template<class T>
  inline typename UnaryReturn<T, OpUnaryMinus >::Type_t
  operator()(const T &a) const
  {
    return (-a);
  }
};
struct OpUnaryPlus
{
 
  template<class T>
  inline typename UnaryReturn<T, OpUnaryPlus >::Type_t
  operator()(const T &a) const
  {
    return (+a);
  }
};
struct OpBitwiseNot
{
 
  template<class T>
  inline typename UnaryReturn<T, OpBitwiseNot >::Type_t
  operator()(const T &a) const
  {
    return (~a);
  }
};
struct OpIdentity
{
 
  template<class T>
  inline typename UnaryReturn<T, OpIdentity >::Type_t
  operator()(const T &a) const
  {
    return (a);
  }
};
struct OpNot
{
 
  template<class T>
  inline typename UnaryReturn<T, OpNot >::Type_t
  operator()(const T &a) const
  {
    return (!a);
  }
};
template<class T >
struct UnaryReturn<T, OpNot > {
  typedef bool Type_t;
};
template <class T1>
struct OpCast
{
 
  template<class T2>
  inline UnaryReturn<T2, OpCast<T1> >
  operator()(const T2 &a) const
  {
    return T1(a);
  }
};
template<class T1, class T2>
struct UnaryReturn<T2, OpCast<T1> > {
  typedef T1 Type_t;
};
struct OpAdd
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpAdd >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a + b);
  }
};
struct OpSubtract
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpSubtract >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a - b);
  }
};
struct OpMultiply
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpMultiply >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a * b);
  }
};
struct OpDivide
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpDivide >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a / b);
  }
};
struct OpMod
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpMod >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a % b);
  }
};
struct OpBitwiseAnd
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseAnd >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a & b);
  }
};
struct OpBitwiseOr
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseOr >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a | b);
  }
};
struct OpBitwiseXor
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseXor >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a ^ b);
  }
};
struct FnLdexp
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnLdexp >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (ldexp(a,b));
  }
};
struct FnPow
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnPow >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (pow(a,b));
  }
};
struct FnFmod
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnFmod >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (fmod(a,b));
  }
};
struct FnArcTan2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnArcTan2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (atan2(a,b));
  }
};
struct OpLT
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLT >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a < b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLT > {
  typedef bool Type_t;
};
struct OpLE
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLE >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a <= b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLE > {
  typedef bool Type_t;
};
struct OpGT
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpGT >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a > b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpGT > {
  typedef bool Type_t;
};
struct OpGE
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpGE >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a >= b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpGE > {
  typedef bool Type_t;
};
struct OpEQ
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpEQ >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a == b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpEQ > {
  typedef bool Type_t;
};
struct OpNE
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpNE >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a != b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpNE > {
  typedef bool Type_t;
};
struct OpAnd
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpAnd >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a && b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpAnd > {
  typedef bool Type_t;
};
struct OpOr
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpOr >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a || b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpOr > {
  typedef bool Type_t;
};
struct OpLeftShift
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLeftShift >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a << b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLeftShift > {
  typedef T1 Type_t;
};
struct OpRightShift
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpRightShift >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a >> b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpRightShift > {
  typedef T1 Type_t;
};
struct OpAddAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpAddAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) += b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpAddAssign > {
  typedef T1 &Type_t;
};
struct OpSubtractAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpSubtractAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) -= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpSubtractAssign > {
  typedef T1 &Type_t;
};
struct OpMultiplyAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpMultiplyAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) *= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpMultiplyAssign > {
  typedef T1 &Type_t;
};
struct OpDivideAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpDivideAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) /= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpDivideAssign > {
  typedef T1 &Type_t;
};
struct OpModAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpModAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) %= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpModAssign > {
  typedef T1 &Type_t;
};
struct OpBitwiseOrAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseOrAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) |= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpBitwiseOrAssign > {
  typedef T1 &Type_t;
};
struct OpBitwiseAndAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseAndAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) &= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpBitwiseAndAssign > {
  typedef T1 &Type_t;
};
struct OpBitwiseXorAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpBitwiseXorAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) ^= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpBitwiseXorAssign > {
  typedef T1 &Type_t;
};
struct OpLeftShiftAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLeftShiftAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) <<= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLeftShiftAssign > {
  typedef T1 &Type_t;
};
struct OpRightShiftAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpRightShiftAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    (const_cast<T1 &>(a) >>= b); return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpRightShiftAssign > {
  typedef T1 &Type_t;
};
struct OpAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (const_cast<T1 &>(a) = b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpAssign > {
  typedef T1 &Type_t;
};
struct FnWhere
{
 
  template<class T1, class T2, class T3>
  inline typename TrinaryReturn<T1, T2, T3, FnWhere >
  ::Type_t
  operator()(T1 &a, const T2 &b, const T3 &c) const
  {
    if (a) return b; else return c;
  }
};
template<class LeafType, class LeafTag>
struct LeafFunctor
{ };
template<class LeafType, class LeafTag>
inline
typename LeafFunctor<LeafType, LeafTag>::Type_t
leafFunctor(const LeafType &leaf, const LeafTag &tag)
{
  return LeafFunctor<LeafType, LeafTag>::apply(leaf, tag);
}
struct EvalLeaf1
{
  int i1_m;
  inline EvalLeaf1(int i1) : i1_m(i1) { }
  inline int val1() const { return i1_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf1>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf1 &)
  {
    return s.value();
  }
};
struct EvalLeaf2
{
  int i1_m, i2_m;
  inline EvalLeaf2(int i1, int i2) : i1_m(i1), i2_m(i2) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf2>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf2 &)
  {
    return s.value();
  }
};
struct EvalLeaf3
{
  int i1_m, i2_m, i3_m;
  inline EvalLeaf3(int i1, int i2, int i3)
    : i1_m(i1), i2_m(i2), i3_m(i3) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf3>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf3 &)
  {
    return s.value();
  }
};
struct EvalLeaf4
{
  int i1_m, i2_m, i3_m, i4_m;
  inline EvalLeaf4(int i1, int i2, int i3, int i4)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf4>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf4 &)
  {
    return s.value();
  }
};
struct EvalLeaf5
{
  int i1_m, i2_m, i3_m, i4_m, i5_m;
  inline EvalLeaf5(int i1, int i2, int i3, int i4, int i5)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf5>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf5 &)
  {
    return s.value();
  }
};
struct EvalLeaf6
{
  int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m;
  inline EvalLeaf6(int i1, int i2, int i3, int i4, int i5, int i6)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
  inline int val6() const { return i6_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf6>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf6 &)
  {
    return s.value();
  }
};
struct EvalLeaf7
{
  int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m;
  inline EvalLeaf7(int i1, int i2, int i3, int i4, int i5, int i6,
    int i7)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7) { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
  inline int val6() const { return i6_m; }
  inline int val7() const { return i7_m; }
};
template<class T>
struct LeafFunctor<Scalar<T>, EvalLeaf7>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const EvalLeaf7 &)
  {
    return s.value();
  }
};
struct IncrementLeaf
{ };
template<class T>
struct LeafFunctor<T, IncrementLeaf>
{
  typedef int Type_t;
  inline static
  Type_t apply(const T &cl, const IncrementLeaf &)
  {
    T &l = const_cast<T &>(cl);
    ++l;
    return 0;
  }
};
template<class T>
struct LeafFunctor<Scalar<T>, IncrementLeaf>
{
  typedef int Type_t;
  inline static
  Type_t apply(const Scalar<T> &, const IncrementLeaf &)
  {
    return 0;
  }
};
struct DecrementLeaf
{ };
template<class T>
struct LeafFunctor<T, DecrementLeaf>
{
  typedef int Type_t;
  inline static
  Type_t apply(const T &cl, const DecrementLeaf &)
  {
    T &l = const_cast<T &>(cl);
    --l;
    return 0;
  }
};
template<class T>
struct LeafFunctor<Scalar<T>, DecrementLeaf>
{
  typedef int Type_t;
  inline static
  Type_t apply(const Scalar<T> &, const DecrementLeaf &)
  {
    return 0;
  }
};
struct DereferenceLeaf
{ };
template<class ForwardIterator>
struct LeafFunctor<ForwardIterator, DereferenceLeaf>
{
  typedef typename std::iterator_traits<ForwardIterator>::value_type Type_t;
  inline static
  Type_t apply(const ForwardIterator &i, const DereferenceLeaf &)
  {
    return *i;
  }
};
template<class T>
struct LeafFunctor<Scalar<T>, DereferenceLeaf>
{
  typedef T Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const DereferenceLeaf &)
  {
    return s.value();
  }
};
template<class A, class Op, class Tag>
struct Combine1
{
  typedef A Type_t;
  inline static
  Type_t combine(const A &a, const Tag &) { return a; }
};
template<class A, class B, class Op, class Tag>
struct Combine2
{
};
template<class A,class B,class C,class Op,class Tag>
struct Combine3
{
  typedef typename Combine2<A, B, Op, Tag>::Type_t Type1_t;
  typedef typename Combine2<Type1_t, C, Op, Tag>::Type_t Type_t;
  inline static
  Type_t combine(const A& a, const B& b, const C& c, const Tag& t)
  {
    return
      Combine2<Type1_t, C,
      Op, Tag>::combine(Combine2<A, B, Op, Tag>::combine(a,b,t),c,t);
  }
};
template<class A, class Op, class Tag>
inline typename Combine1<A, Op, Tag>::Type_t
peteCombine(const A &a, const Op &, const Tag &t)
{
  return Combine1<A, Op, Tag>::combine(a, t);
}
template<class A, class B, class Op, class Tag>
inline typename Combine2<A, B, Op, Tag>::Type_t
peteCombine(const A &a, const B &b, const Op &, const Tag &t)
{
  return Combine2<A, B, Op, Tag>::combine(a, b, t);
}
template<class A, class B, class C, class Op, class Tag>
inline typename Combine3<A, B, C, Op, Tag>::Type_t
peteCombine(const A &a, const B &b, const C &c, const Op &, const Tag &t)
{
  return Combine3<A, B, C, Op, Tag>::combine(a, b, c, t);
}
struct TreeCombine
{
 
};
template<class A, class Op>
struct Combine1<A, Op, TreeCombine >
{
  typedef UnaryNode<Op, A> Type_t;
  inline static
  Type_t combine(const A &a, const TreeCombine &t)
  {
    return Type_t(a);
  }
};
template<class A, class B, class Op>
struct Combine2<A, B, Op, TreeCombine >
{
  typedef BinaryNode<Op, A, B> Type_t;
  inline static
  Type_t combine(const A &a, const B &b, const TreeCombine &t)
  {
    return Type_t(a, b);
  }
};
template<class A, class B, class C, class Op>
struct Combine3<A, B, C, Op, TreeCombine >
{
  typedef TrinaryNode<Op, A, B, C> Type_t;
  inline static
  Type_t combine(const A &a, const B &b, const C &c, const TreeCombine &t)
  {
    return Type_t(a, b, c);
  }
};
struct OpCombine
{
 
};
template<class A,class Op>
struct Combine1<A, Op, OpCombine>
{
  typedef typename UnaryReturn<A, Op>::Type_t Type_t;
  inline static
  Type_t combine(A a, OpCombine) { return Op()(a); }
};
template<class A,class B,class Op>
struct Combine2<A, B, Op, OpCombine>
{
  typedef typename BinaryReturn<A, B, Op>::Type_t Type_t;
  inline static
  Type_t combine(A a, B b, OpCombine)
  {
    return Op()(a, b);
  }
};
template<class A,class B,class C,class Op>
struct Combine3<A, B, C, Op, OpCombine>
{
  typedef typename TrinaryReturn<A, B, C, Op>::Type_t Type_t;
  inline static
  Type_t combine(A a, B b, C c, OpCombine)
  {
    return Op()(a, b, c);
  }
};
struct AndCombine
{
 
};
template<class Op>
struct Combine2<bool, bool, Op, AndCombine>
{
  typedef bool Type_t;
  inline static
  Type_t combine(bool a, bool b, AndCombine)
  {
    return (a && b);
  }
};
struct OrCombine
{
 
};
template<class Op>
struct Combine2<bool, bool, Op, OrCombine>
{
  typedef bool Type_t;
  inline static
  Type_t combine(bool a, bool b, OrCombine)
  {
    return (a || b);
  }
};
struct NullCombine
{
 
};
template<class Op>
struct Combine2<int, int, Op, NullCombine>
{
  typedef int Type_t;
  inline static
  Type_t combine(int, int, NullCombine)
  {
    return 0;
  }
};
struct SumCombine
{
 
};
template<class Op>
struct Combine2<int, int, Op, SumCombine>
{
  typedef int Type_t;
  inline static
  Type_t combine(int a, int b, SumCombine)
  {
    return a + b;
  }
};
template<class Expr, class FTag, class CTag>
struct ForEach
{
  typedef typename LeafFunctor<Expr, FTag>::Type_t Type_t;
  inline static
  Type_t apply(const Expr &expr, const FTag &f, const CTag &)
  {
    return LeafFunctor<Expr, FTag>::apply(expr, f);
  }
};
template<class Expr, class FTag, class CTag>
inline typename ForEach<Expr,FTag,CTag>::Type_t
forEach(const Expr &e, const FTag &f, const CTag &c)
{
  return ForEach<Expr, FTag, CTag>::apply(e, f, c);
}
template<class Op, class A, class FTag, class CTag>
struct ForEach<UnaryNode<Op, A>, FTag, CTag>
{
  typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename Combine1<TypeA_t, Op, CTag>::Type_t Type_t;
  inline static
  Type_t apply(const UnaryNode<Op, A> &expr, const FTag &f,
    const CTag &c)
  {
    return Combine1<TypeA_t, Op, CTag>::
      combine(ForEach<A, FTag, CTag>::apply(expr.child(), f, c), c);
  }
};
template<class Op, class A, class B, class FTag, class CTag>
struct ForEach<BinaryNode<Op, A, B>, FTag, CTag >
{
  typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename ForEach<B, FTag, CTag>::Type_t TypeB_t;
  typedef typename Combine2<TypeA_t, TypeB_t, Op, CTag>::Type_t Type_t;
  inline static
  Type_t apply(const BinaryNode<Op, A, B> &expr, const FTag &f,
        const CTag &c)
  {
    return Combine2<TypeA_t, TypeB_t, Op, CTag>::
      combine(ForEach<A, FTag, CTag>::apply(expr.left(), f, c),
              ForEach<B, FTag, CTag>::apply(expr.right(), f, c),
       c);
  }
};
template<class Op, class A, class B, class C, class FTag, class CTag>
struct ForEach<TrinaryNode<Op, A, B, C>, FTag, CTag >
{
  typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename ForEach<B, FTag, CTag>::Type_t TypeB_t;
  typedef typename ForEach<C, FTag, CTag>::Type_t TypeC_t;
  typedef typename Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::Type_t
    Type_t;
  inline static
  Type_t apply(const TrinaryNode<Op, A, B, C> &expr, const FTag &f,
        const CTag &c)
  {
    return Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::
      combine(ForEach<A, FTag, CTag>::apply(expr.left(), f, c),
       ForEach<B, FTag, CTag>::apply(expr.middle(), f, c),
       ForEach<C, FTag, CTag>::apply(expr.right(), f, c),
       c);
  }
};
template<class T> class Expression;
template<class T, class FTag, class CTag>
struct ForEach<Expression<T>, FTag, CTag>
{
  typedef typename ForEach<T, FTag, CTag>::Type_t Type_t;
  inline static
  Type_t apply(const Expression<T> &expr, const FTag &f,
        const CTag &c)
  {
    return ForEach<T, FTag, CTag>::apply(expr.expression(), f, c);
  }
};
template<class T> struct Reference;
template<class T, class FTag, class CTag>
struct ForEach<Reference<T>, FTag, CTag>
{
  typedef typename ForEach<T, FTag, CTag>::Type_t Type_t;
  inline static
  Type_t apply(const Reference<T> &ref, const FTag &f,
        const CTag &c)
  {
    return ForEach<T, FTag, CTag>::apply(ref.reference(), f, c);
  }
};
template<class T>
class Expression
{
public:
  typedef T Expression_t;
  Expression(const T& expr) : expr_m(expr)
  { }
  const Expression_t& expression() const
  {
    return expr_m;
  }
private:
  T expr_m;
};
template<class T>
struct CreateLeaf
{
  typedef Scalar<T> Leaf_t;
  inline static
  Leaf_t make(const T &a)
  {
    return Scalar<T>(a);
  }
};
template<class T>
struct CreateLeaf<Expression<T> >
{
  typedef typename Expression<T>::Expression_t Leaf_t;
  inline static
  const Leaf_t &make(const Expression<T> &a)
  {
    return a.expression();
  }
};
template<class T>
struct MakeReturn
{
  typedef Expression<T> Expression_t;
  inline static
  Expression_t make(const T &a) { return Expression_t(a); }
};
struct ErrorType
{
};
template<class Expr, class FTag, class CTag>
struct ForEachRef
{
  typedef typename LeafFunctor<Expr, FTag>::Type_t Type_t;
  inline static
  const Type_t &apply(const Expr &expr, const FTag &f, const CTag &)
    {
      return LeafFunctor<Expr, FTag>::apply(expr, f);
    }
};
template<class Expr, class FTag, class CTag>
inline const typename ForEachRef<Expr,FTag,CTag>::Type_t &
forEachRef(const Expr &e, const FTag &f, const CTag &c)
{
  return ForEachRef<Expr, FTag, CTag>::apply(e, f, c);
}
template<class Op, class A, class FTag, class CTag>
struct ForEachRef<UnaryNode<Op, A>, FTag, CTag>
{
  typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename Combine1<TypeA_t, Op, CTag>::Type_t Type_t;
  inline static
  const Type_t &apply(const UnaryNode<Op, A> &expr, const FTag &f,
    const CTag &c)
    {
      return Combine1<TypeA_t, Op, CTag>::
        combine(ForEachRef<A, FTag, CTag>::apply(expr.child(), f, c),
                c);
    }
};
template<class Op, class A, class B, class FTag, class CTag>
struct ForEachRef<BinaryNode<Op, A, B>, FTag, CTag >
{
  typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename ForEachRef<B, FTag, CTag>::Type_t TypeB_t;
  typedef typename Combine2<TypeA_t, TypeB_t, Op, CTag>::Type_t Type_t;
  inline static
  const Type_t &apply(const BinaryNode<Op, A, B> &expr, const FTag &f,
                   const CTag &c)
    {
      return Combine2<TypeA_t, TypeB_t, Op, CTag>::
        combine(ForEachRef<A, FTag, CTag>::apply(expr.left(), f, c),
                ForEachRef<B, FTag, CTag>::apply(expr.right(), f, c),
         c);
    }
};
template<class Op, class A, class B, class C, class FTag, class CTag>
struct ForEachRef<TrinaryNode<Op, A, B, C>, FTag, CTag >
{
  typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
  typedef typename ForEachRef<B, FTag, CTag>::Type_t TypeB_t;
  typedef typename ForEachRef<C, FTag, CTag>::Type_t TypeC_t;
  typedef typename Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::Type_t
    Type_t;
  inline static
  const Type_t &apply(const TrinaryNode<Op, A, B, C> &expr, const FTag &f,
                   const CTag &c)
    {
      return Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::
        combine(ForEachRef<A, FTag, CTag>::apply(expr.left(), f, c),
         ForEachRef<B, FTag, CTag>::apply(expr.middle(), f, c),
         ForEachRef<C, FTag, CTag>::apply(expr.right(), f, c),
         c);
    }
};
template<class T, class FTag, class CTag>
struct ForEachRef<Expression<T>, FTag, CTag>
{
  typedef typename ForEachRef<T, FTag, CTag>::Type_t Type_t;
  inline static
  const Type_t &apply(const Expression<T> &expr, const FTag &f,
                   const CTag &c)
    {
      return ForEachRef<T, FTag, CTag>::apply(expr.expression(), f, c);
    }
};
template<class T, class FTag, class CTag>
struct ForEachRef<Reference<T>, FTag, CTag>
{
  typedef typename ForEachRef<T, FTag, CTag>::Type_t Type_t;
  inline static
  const Type_t &apply(const Reference<T> &ref, const FTag &f,
                   const CTag &c)
    {
      return ForEachRef<T, FTag, CTag>::apply(ref.reference(), f, c);
    }
};
template<int Integer> class WrappedInt
{
public:
  enum { val = Integer };
 
};
template<int Dim, class T, class EngineTag> class Engine;
template<class Eng, class Tag>
struct EngineFunctorDefault
{ };
template<class Eng, class Tag>
struct EngineFunctor
{
  typedef typename EngineFunctorDefault<Eng,Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Eng &e, const Tag &t)
  {
    return EngineFunctorDefault<Eng,Tag>::apply(e,t);
  }
};
template<class Eng, class Tag>
inline typename EngineFunctor<Eng,Tag>::Type_t
engineFunctor(const Eng &e, const Tag &tag)
{
  return EngineFunctor<Eng,Tag>::apply(e,tag);
}
template<class T, class Tag>
struct EngineFunctorScalar
{ };
template<class Tag>
struct EngineView;
template<class Node, class Tag>
struct LeafFunctor<Node, EngineView<Tag> >
{
};
template<class T, class Tag>
struct LeafFunctor<Scalar<T>, EngineView<Tag> >
{
  typedef Scalar<T> Type_t;
  static inline
  Type_t apply(const Scalar<T> &s, const EngineView<Tag> &)
  {
    return s;
  }
};
template<class Engine, class Tag>
struct DefaultEngineView;
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Engine<Dim, T, E>, EngineView<Tag> >
{
  typedef Engine<Dim, T, E> Subject_t;
  typedef DefaultEngineView<Subject_t, Tag> EngineView_t;
  typedef typename EngineView_t::Type_t Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const EngineView<Tag> &tag)
  {
    return EngineView_t::apply(engine, tag);
  }
};
template<class Tag>
struct ExpressionApply
{
  inline
  ExpressionApply(const Tag &tag)
    : tag_m(tag)
  {
  }
  template<class A>
  void operator()(const A &a) const
  {
    forEach(a, *this, NullCombine());
  }
  const Tag &tag() const { return tag_m; }
  const Tag &tag_m;
};
template<class A, class Tag>
inline void
expressionApply(const A &a, const Tag &tag)
{
  forEach(a, ExpressionApply<Tag>(tag), NullCombine());
}
template<class Node, class Tag>
struct LeafFunctor<Node, ExpressionApply<Tag> >
{
};
template<class T, class Tag>
struct LeafFunctor<Scalar<T>, ExpressionApply<Tag> >
{
  typedef int Type_t;
  static inline
  Type_t apply(const Scalar<T> &, const ExpressionApply<Tag> &)
  {
    return 0;
  }
};
template<class Engine, class Tag>
struct DefaultExpressionApply;
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Engine<Dim, T, E>, ExpressionApply<Tag> >
{
  typedef Engine<Dim, T, E> Subject_t;
  typedef DefaultExpressionApply<Subject_t, Tag> ExpressionApply_t;
  typedef int Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const ExpressionApply<Tag> &tag)
  {
    return ExpressionApply_t::apply(engine, tag);
  }
};
namespace Pooma {
class NoInit
{
public:
 
};
}
template <class T> class DomainTraits;
template <class T>
struct SizeTypePromotion
{
  typedef T Type_t;
};
template <>
struct SizeTypePromotion<int>
{
  typedef long Type_t;
};
template <>
struct SizeTypePromotion<float>
{
  typedef double Type_t;
};
template <int I>
struct Dom1Initialize {
  template <class DT>
  static inline void apply(typename DT::Storage_t& s)
  {
    Dom1Initialize<I-1>::template apply<DT>(s);
    DomainTraits<typename DT::OneDomain_t>::initializeStorage(s[I].storage());
  }
};
template <>
struct Dom1Initialize<0> {
  template <class DT>
  static inline void apply(typename DT::Storage_t& s)
  {
    DomainTraits<typename DT::OneDomain_t>::initializeStorage(s[0].storage());
  }
};
template <class Domain>
struct WrapNoInit : public Domain
{
  WrapNoInit() : Domain(Pooma::NoInit()) {}
};
template<class DomT, class T, int Dim>
struct DomainTraitsDomain
{
  typedef typename SizeTypePromotion<T>::Type_t Size_t;
  typedef T Element_t;
  typedef DomT Domain_t;
  typedef DomT NewDomain1_t;
  enum { domain = true };
  enum { dimensions = Dim };
  static bool getIgnorable(const Domain_t &, int) { return false; }
};
template<class DomT, class T>
struct DomainTraitsDomain<DomT, T, 1>
{
  typedef typename SizeTypePromotion<T>::Type_t Size_t;
  typedef T Element_t;
  typedef DomT Domain_t;
  typedef DomT NewDomain1_t;
  enum { domain = true };
  enum { dimensions = 1 };
  inline
  static Element_t getFirst(const Domain_t &d) { return d.first(); }
  inline
  static Element_t getLast(const Domain_t &d) { return d.last(); }
  inline
  static Element_t getStride(const Domain_t &d) { return d.stride(); }
  inline
  static Size_t getLength(const Domain_t &d) { return d.length(); }
  inline
  static Size_t getSize(const Domain_t &d) { return d.size(); }
  inline
  static Element_t getMin(const Domain_t &d) { return d.min(); }
  inline
  static Element_t getMax(const Domain_t &d) { return d.max(); }
  inline
  static bool getEmpty(const Domain_t &d) { return d.empty(); }
  inline
  static int getLoop(const Domain_t &d) { return d.loop(); }
  inline
  static Element_t getElem(const Domain_t &d, int n) { return d.elem(n); }
  inline
  static bool getIgnorable(const Domain_t &, int) { return false; }
};
template<class DomT, class T, class NewDom1T>
struct DomainTraitsScalar
{
  typedef DomT Domain_t;
  typedef DomT OneDomain_t;
  typedef NewDom1T NewDomain1_t;
  typedef T PointDomain_t;
  typedef T Element_t;
  typedef int Size_t;
  enum { domain = false };
  enum { dimensions = 1,
  sliceDimensions = 0 };
  enum { loopAware = false };
  enum { singleValued = true };
  enum { unitStride = true };
  enum { wildcard = false };
  inline
  static OneDomain_t getDomain(T d, int) { return OneDomain_t(d); }
  inline
  static PointDomain_t getPointDomain(T d, int) { return d; }
  inline
  static Element_t getFirst(const Element_t &d) { return d; }
  inline
  static Element_t getLast(const Element_t &d) { return d; }
  inline
  static int getStride(const Element_t &) { return 1; }
  inline
  static Size_t getLength(const Element_t &) { return 1; }
  inline
  static Size_t getSize(const Element_t &d) { return 1; }
  inline
  static Element_t getMin(const Element_t &d) { return d; }
  inline
  static Element_t getMax(const Element_t &d) { return d; }
  inline
  static bool getEmpty(const Element_t &) { return false; }
  inline
  static int getLoop(const Element_t &) { return 0; }
  inline
  static Element_t getElem(const Element_t &d, int) { return d; }
};
template<class T>
struct DomainTraits : public DomainTraitsScalar<T, T, T>
{
  typedef DomainTraitsScalar<T, T, T> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::OneDomain_t OneDomain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef typename Base_t::PointDomain_t PointDomain_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Size_t Size_t;
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = Base_t::sliceDimensions };
  enum { loopAware = Base_t::loopAware };
  enum { singleValued = Base_t::singleValued };
  enum { unitStride = Base_t::unitStride };
  enum { wildcard = Base_t::wildcard };
};
template<class T, int Dim>
struct DomainChangeDim {
  typedef T OldType_t;
  typedef T NewType_t;
  enum { oldDim = Dim,
  newDim = Dim };
};
template <class Dom, class Storage, class T1, class T2>
inline void
setDomain(const Dom&, Storage& data, const T1& beg, const T2& end) {
  DomainTraits<Dom>::setDomain(data, beg, end);
}
template <int Dim> class Interval;
template <> class Interval<1>;
template <int Dim> class Loc;
template <> class Loc<1>;
template<>
struct DomainTraits<char>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<unsigned char>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<short>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<unsigned short>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<int>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<unsigned int>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<long>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<>
struct DomainTraits<unsigned long>
  : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
template<class T1, class T2, bool strided>
struct ContainsDomainSingle {
  static bool contains(const T1 &a, const T2 &b) {
    return (a.min() <= b.min() && a.max() >= b.max());
  }
};
template<class T1, class T2>
struct ContainsDomainSingle<T1,T2,true> {
  static bool contains(const T1 &a, const T2 &b) {
    typedef typename DomainTraits<T1>::Element_t E1_t;
    typedef typename DomainTraits<T2>::Element_t E2_t;
    E1_t a0 = a.min();
    E1_t a1 = a.max();
    E1_t s = a.stride();
    E2_t b0 = b.min();
    E2_t b1 = b.max();
    E2_t t = b.stride();
    if (s < 0)
      s = -s;
    if (t < 0)
      t = -t;
    bool quicktest = (a0 <= b0 && a1 >= b1);
    if (!quicktest || s == 1)
      return quicktest;
    return (t % s == 0) && ((b0-a0) % s == 0) && ((a1-b1) % s == 0);
  }
};
template<class T1, class T2, int Dim>
struct ContainsDomain {
  enum { strided = !DomainTraits<T1>::unitStride };
  enum { n = Dim - 1 };
  static bool contains(const T1 &a, const T2 &b) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    return ContainsDomainSingle<Dom1_t,Dom2_t,strided>::contains(
      DomainTraits<T1>::getDomain(a,n), DomainTraits<T2>::getDomain(b,n)) &&
      ContainsDomain<T1,T2,n>::contains(a,b);
  }
};
template<class T1, class T2>
struct ContainsDomain<T1,T2,1> {
  enum { strided = !DomainTraits<T1>::unitStride };
  static bool contains(const T1 &a, const T2 &b) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    return ContainsDomainSingle<Dom1_t,Dom2_t,strided>::contains(
      DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0));
  }
};
template<class T1, class T2>
inline bool contains(const T1 &a, const T2 &b)
{
  PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
  return ContainsDomain<T1,T2,DomainTraits<T1>::dimensions>::contains(a, b);
}
template<int Dim>
class Loc;
template<int Dim>
class Interval;
template<int Dim>
class Range;
template<class T>
class IndirectionList;
template<int Dim>
class Grid;
template<class T1,class T2 >
struct DomainArithOpsTraits
{
};
template <>
struct DomainArithOpsTraits< Loc<1> , Loc<1> >
{
  typedef Loc<1> AddResult_t;
  typedef Loc<1> SubResult_t;
  typedef Loc<1> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Loc<1> , Loc<Dim> >
{
  typedef Loc<Dim> AddResult_t;
  typedef Loc<Dim> SubResult_t;
  typedef Loc<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Loc<Dim> , Loc<1> >
{
  typedef Loc<Dim> AddResult_t;
  typedef Loc<Dim> SubResult_t;
  typedef Loc<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Loc<Dim> , Loc<Dim2> >
{
  typedef Loc<Dim> AddResult_t;
  typedef Loc<Dim> SubResult_t;
  typedef Loc<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Loc<1> , Interval<Dim> >
{
  typedef Interval<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Interval<Dim>, Loc<1> >
{
  typedef Interval<Dim> AddResult_t;
  typedef Interval<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Loc<Dim> , Interval<Dim2> >
{
  typedef Interval<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Interval<Dim>, Loc<Dim2> >
{
  typedef Interval<Dim> AddResult_t;
  typedef Interval<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Loc<1> , Range<Dim> >
{
  typedef Range<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Range<Dim>, Loc<1> >
{
  typedef Range<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Loc<Dim> , Range<Dim2> >
{
  typedef Range<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Range<Dim>, Loc<Dim2> >
{
  typedef Range<Dim> AddResult_t;
  typedef Range<Dim> SubResult_t;
  typedef Range<Dim> MultResult_t;
};
template< >
struct DomainArithOpsTraits<Loc<1> , IndirectionList<int> >
{
  typedef IndirectionList<int> AddResult_t;
  typedef IndirectionList<int> SubResult_t;
  typedef IndirectionList<int> MultResult_t;
};
template< >
struct DomainArithOpsTraits<IndirectionList<int>, Loc<1> >
{
  typedef IndirectionList<int> AddResult_t;
  typedef IndirectionList<int> SubResult_t;
  typedef IndirectionList<int> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Loc<1> , Grid<Dim> >
{
  typedef Grid<Dim> AddResult_t;
  typedef Grid<Dim> SubResult_t;
  typedef Grid<Dim> MultResult_t;
};
template<int Dim>
struct DomainArithOpsTraits<Grid<Dim>, Loc<1> >
{
  typedef Grid<Dim> AddResult_t;
  typedef Grid<Dim> SubResult_t;
  typedef Grid<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Loc<Dim> , Grid<Dim2> >
{
  typedef Grid<Dim> AddResult_t;
  typedef Grid<Dim> SubResult_t;
  typedef Grid<Dim> MultResult_t;
};
template<int Dim,int Dim2>
struct DomainArithOpsTraits<Grid<Dim>, Loc<Dim2> >
{
  typedef Grid<Dim> AddResult_t;
  typedef Grid<Dim> SubResult_t;
  typedef Grid<Dim> MultResult_t;
};
template <class Dom>
class DomainIterator
{
public:
  typedef DomainIterator<Dom> This_t;
  typedef Dom Domain_t;
  typedef typename Domain_t::AskDomain_t Value_t;
  typedef std::input_iterator_tag iterator_category;
  typedef Value_t value_type;
  typedef ptrdiff_t difference_type;
  typedef const Value_t* pointer;
  typedef const Value_t& reference;
  enum { dimensions = DomainTraits<Dom>::dimensions };
  DomainIterator(const Dom &d, int size = 0)
    : domain_m(d), loc_m(d.firsts()), index_m(domain_m.size()-size)
    {
      ;
      for (int i=0; i < dimensions; ++i)
 current_m[i] = 0;
    }
  DomainIterator(const This_t &model)
    : domain_m(model.domain_m), loc_m(model.loc_m), index_m(model.index_m)
    {
      ;
      for (int i=0; i < dimensions; ++i)
 current_m[i] = model.current_m[i];
    }
  DomainIterator()
    : index_m(0)
    {
      for (int i=0; i < dimensions; ++i)
 current_m[i] = 0;
    }
  inline const Value_t &operator*() const
    {
      ;
      return loc_m;
    }
  inline const Value_t *operator->() const
    {
      ;
      return &loc_m;
    }
  inline bool operator==(const This_t &rhs) const
    {
      return (index_m == rhs.index_m);
    }
  inline bool operator!=(const This_t &rhs) const
    {
      return (index_m != rhs.index_m);
    }
  bool done() const
    {
      return (index_m == 0);
    }
  This_t &operator=(const This_t &model)
    {
      index_m = model.index_m;
      domain_m = model.domain_m;
      loc_m = model.loc_m;
      for (int i=0; i < dimensions; ++i)
 current_m[i] = model.current_m[i];
      return *this;
    }
  This_t &operator++()
    {
      increment(WrappedInt<Domain_t::unitStride>());
      return *this;
    }
  This_t operator++(int)
    {
      DomainIterator<Dom> save(*this);
      increment(WrappedInt<Domain_t::unitStride>());
      return save;
    }
private:
  Domain_t domain_m;
  Value_t loc_m;
  int current_m[dimensions];
  int index_m;
  void increment(const WrappedInt<true>&)
    {
      ;
      --index_m;
      ++(current_m[0]);
      ++loc_m[0];
      if (__builtin_expect(current_m[0] < domain_m[0].length(), 1))
        return;
      for (int i = 1; i < dimensions; ++i)
 {
   current_m[i-1] = 0;
   loc_m[i-1] = domain_m[i-1].first();
   ++(current_m[i]);
   ++loc_m[i];
   if (__builtin_expect(current_m[i] < domain_m[i].length(), 1))
     return;
 }
    }
  void increment(const WrappedInt<false>&)
    {
      ;
      --index_m;
      ++(current_m[0]);
      if (__builtin_expect(current_m[0] < domain_m[0].length(), 1)) {
        loc_m[0] = domain_m[0](current_m[0]);
        return;
      }
      for (int i = 1; i < dimensions; ++i)
 {
   current_m[i-1] = 0;
   loc_m[i-1] = domain_m[i-1].first();
   ++(current_m[i]);
   if (__builtin_expect(current_m[i] < domain_m[i].length(), 1)) {
     loc_m[i] = domain_m[i](current_m[i]);
     return;
   }
 }
    }
};
template <class Dom>
class DomainBlockIterator
{
public:
  typedef DomainBlockIterator<Dom> This_t;
  typedef Dom Domain_t;
  typedef typename Domain_t::OneDomain_t OneDomain_t;
  typedef typename Domain_t::AskDomain_t Value_t;
  typedef typename Domain_t::BlockDomain_t Block_t;
  typedef typename Block_t::OneDomain_t OneBlock_t;
  typedef typename OneDomain_t::iterator iterator;
  typedef typename Domain_t::Element_t Element_t;
  enum { dimensions = DomainTraits<Dom>::dimensions };
  DomainBlockIterator()
    : index_m(-1)
    {
    }
  DomainBlockIterator(const Dom &d);
  DomainBlockIterator(const This_t &model);
  ~DomainBlockIterator()
    {
    }
  inline const Block_t &operator*() const
    {
      ;
      return block_m;
    }
  inline const Block_t *operator->() const
    {
      ;
      return block_m;
    }
  inline const Value_t &point() const
    {
      ;
      return loc_m;
    }
  inline int index() const
    {
      ;
      return index_m;
    }
  inline bool operator==(const This_t &rhs) const
    {
      if (done() || rhs.done())
 return (done() && rhs.done());
      else
 return (block_m == *rhs);
    }
  inline bool operator!=(const This_t &rhs) const
    {
      return !(operator==(rhs));
    }
  bool done() const
    {
      return (index_m < 0);
    }
  This_t &operator=(const This_t &model)
    {
      domain_m = model.domain_m;
      loc_m = model.loc_m;
      block_m = model.block_m;
      index_m = model.index_m;
      for (int i=0; i < dimensions; ++i)
 current_m[i] = model.current_m[i];
      return *this;
    }
  This_t &operator++()
    {
      increment();
      return *this;
    }
  This_t operator++(int)
    {
      This_t save(*this);
      increment();
      return save;
    }
private:
  Domain_t domain_m;
  iterator current_m[dimensions];
  Value_t loc_m;
  Block_t block_m;
  int index_m;
  void setDone()
    {
      index_m = (-1);
    }
  void increment();
};
template<class Dom>
DomainBlockIterator<Dom>::DomainBlockIterator(const Dom &d)
  : domain_m(d), loc_m(0), index_m(0)
{
  for (int i=0; i < dimensions; ++i)
    {
      if (d[i].begin() == d[i].end())
 {
   setDone();
   break;
 }
      else
 {
   current_m[i] = d[i].begin();
   iterator next = current_m[i];
   Element_t a, b;
   if (++next == d[i].end())
     {
       a = b = (*(current_m[i])).first();
     }
   else
     {
       a = (*(current_m[i])).first();
       b = (*next).first();
     }
   if (b < a)
     block_m[i] = OneBlock_t(b + 1, a);
   else if (b == a)
     block_m[i] = OneBlock_t(a, a);
   else
     block_m[i] = OneBlock_t(a, b - 1);
 }
    }
}
template<class Dom>
DomainBlockIterator<Dom>::DomainBlockIterator(const This_t &model)
  : domain_m(model.domain_m), loc_m(model.loc_m),
    block_m(model.block_m), index_m(model.index_m)
{
  for (int i=0; i < dimensions; ++i)
    current_m[i] = model.current_m[i];
}
template<class Dom>
void DomainBlockIterator<Dom>::increment()
{
  ;
  for (int i = 0; i < dimensions; ++i)
    {
      if (++(current_m[i]) == domain_m[i].end())
 {
   if (i >= dimensions-1)
     {
       setDone();
       break;
     }
 }
      else
 {
   iterator next = current_m[i];
   if (++next == domain_m[i].end())
     {
       if (i < dimensions-1)
  {
    current_m[i] = domain_m[i].begin();
    next = current_m[i];
    Element_t a, b;
    if (++next == domain_m[i].end())
      {
        a = b = (*(current_m[i])).first();
      }
    else
      {
        a = (*(current_m[i])).first();
        b = (*next).first();
      }
    if (b < a)
      block_m[i] = OneBlock_t(b + 1, a);
    else if (b == a)
      block_m[i] = OneBlock_t(a, a);
    else
      block_m[i] = OneBlock_t(a, b - 1);
    loc_m[i] = 0;
  }
       else
  {
    setDone();
    break;
  }
     }
   else
     {
       Element_t a = (*(current_m[i])).first();
       Element_t b = (*next).first();
       if (b < a)
  block_m[i] = OneBlock_t(b + 1, a);
       else
  block_m[i] = OneBlock_t(a, b - 1);
       loc_m[i] = loc_m[i].first() + 1;
       index_m++;
       break;
     }
 }
    }
}
template<class DT>
class DomainBase
{
public:
  typedef typename DT::Domain_t Domain_t;
  typedef typename DT::AskDomain_t AskDomain_t;
  typedef typename DT::MultResult_t MultResult_t;
  typedef typename DT::Storage_t Storage_t;
  typedef DomainIterator<Domain_t> const_iterator;
  typedef DomainIterator<Domain_t> iterator;
  typedef DomainBlockIterator<Domain_t> const_blockIterator;
  typedef DomainBlockIterator<Domain_t> blockIterator;
  inline
  DomainBase() {
    PoomaCTAssert<(DT::dimensions > 0)>::test();
    DT::initializeStorage(domain_m);
  }
  inline
  DomainBase(const Pooma::NoInit &) {
    PoomaCTAssert<(DT::dimensions > 0)>::test();
  }
  inline
  Domain_t &unwrap() { return *static_cast<Domain_t *>(this); }
  const Domain_t &unwrap() const {
    return *static_cast<const Domain_t *>(this);
  }
  inline
  AskDomain_t firsts() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].first();
    return retval;
  }
  inline
  AskDomain_t lasts() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].last();
    return retval;
  }
  inline
  AskDomain_t strides() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].stride();
    return retval;
  }
  inline
  AskDomain_t lengths() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].length();
    return retval;
  }
  inline
  AskDomain_t sizes() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].size();
    return retval;
  }
  inline
  AskDomain_t mins() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].min();
    return retval;
  }
  inline
  AskDomain_t maxes() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].max();
    return retval;
  }
  inline
  AskDomain_t loops() const {
    AskDomain_t retval = Pooma::NoInit();
    for (int i=0; i < DT::dimensions; ++i)
      retval[i] = unwrap()[i].loop();
    return retval;
  }
  Storage_t& storage() { return domain_m; }
  const Storage_t& storage() const { return domain_m; }
  MultResult_t operator-() const {
    return (MultResult_t(unwrap()) * (-1));
  }
  const_iterator begin() const { return const_iterator(unwrap()); }
  const_iterator end() const { return const_iterator(unwrap(),
           unwrap().size()); }
  const_blockIterator beginBlock() const{return const_blockIterator(unwrap());}
  const_blockIterator endBlock() const { return const_blockIterator(); }
  template<class Out>
  void print(Out &o) const;
protected:
  Storage_t domain_m;
private:
  DomainBase(const DomainBase<DT> &);
  void operator=(const DomainBase<DT> &);
};
template<class DT>
template<class Out>
void DomainBase<DT>::print(Out &o) const
{
  const Domain_t &d = unwrap();
  o << "[";
  for (int i=0; i < DT::dimensions; ++i) {
    o << d[i].first() << ":" << d[i].last() << ":" << d[i].stride();
    if (i < (DT::dimensions-1))
      o << ",";
  }
  o << "]";
}
template <class T1, class T2, bool SV>
struct DomPair {
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::AddResult_t
  add(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::AddResult_t
      retval(d1.unwrap());
    return (retval += d2.unwrap());
  }
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::SubResult_t
  sub(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::SubResult_t
      retval(d1.unwrap());
    return (retval -= d2.unwrap());
  }
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::MultResult_t
  mult(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::MultResult_t
      retval(d1.unwrap());
    return (retval *= d2.unwrap());
  }
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::MultResult_t
  div(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::MultResult_t
      retval(d1.unwrap());
    return (retval /= d2.unwrap());
  }
};
template <class T1, class T2>
struct DomPair<T1,T2,false> {
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::AddResult_t
  add(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::AddResult_t
      retval(d2.unwrap());
    return (retval += d1.unwrap());
  }
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::SubResult_t
  sub(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::SubResult_t
      retval(d2.unwrap());
    retval = -retval;
    return (retval += d1.unwrap());
  }
  static typename DomainArithOpsTraits<typename T1::Domain_t,
                                       typename T2::Domain_t>::MultResult_t
  mult(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
  {
    typename DomainArithOpsTraits<typename T1::Domain_t,
                                  typename T2::Domain_t>::MultResult_t
      retval(d2.unwrap());
    return (retval *= d1.unwrap());
  }
};
template<class T1, class T2>
inline typename DomainArithOpsTraits<typename T1::Domain_t,
                                     typename T2::Domain_t>::AddResult_t
operator+(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
{
  return DomPair<T1,T2,T2::singleValued>::add(d1,d2);
}
template<class T1, class T2>
inline typename DomainArithOpsTraits<typename T1::Domain_t,
                                     typename T2::Domain_t>::SubResult_t
operator-(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
{
  return DomPair<T1,T2,T2::singleValued>::sub(d1,d2);
}
template<class T1, class T2>
inline typename DomainArithOpsTraits<typename T1::Domain_t,
                                     typename T2::Domain_t>::MultResult_t
operator*(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
{
  return DomPair<T1,T2,T2::singleValued>::mult(d1,d2);
}
template<class T1, class T2>
inline typename DomainArithOpsTraits<typename T1::Domain_t,
                                     typename T2::Domain_t>::MultResult_t
operator/(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
{
  return DomPair<T1,T2,T2::singleValued>::div(d1,d2);
}
template<class T> inline bool operator==(char d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(short d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(int d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(long d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(float d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(double d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); }
template<class T> inline bool operator!=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(float d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); }
template<class T> inline bool operator<(char d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(short d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(int d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(long d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(float d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(double d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); }
template<class T> inline bool operator>(char d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(short d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(int d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(long d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(float d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(double d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); }
template<class T> inline bool operator<=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(float d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); }
template<class T> inline bool operator>=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(float d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); }
template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, float d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(float d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, double d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(double d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); }
template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, float d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(float d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, double d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(double d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); }
template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, float d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(float d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, double d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(double d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); }
template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, float d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(float d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, double d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(double d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); }
template<class D, class V>
inline void DomainToVector(const D &dom, V &vec)
{
  for (int i=0; i < DomainTraits<D>::dimensions; ++i)
    vec(i) = dom[i].first();
}
template<class V, class D>
inline void VectorToDomain(const V &vec, D &dom)
{
  for (int i=0; i < DomainTraits<D>::dimensions; ++i)
    dom[i] = DomainTraits<D>::OneDomain_t(vec(i), vec(i));
}
template<class DT>
std::ostream& operator<<(std::ostream &o, const DomainBase<DT> &dbase)
{
  dbase.print(o);
  return o;
}
template <int Dim, int C>
struct DomainDelta;
template <int Dim, int C>
struct DomainDelta;
template<int Dim, class DT>
class Domain : public DomainBase<DT>
{
  typedef DomainBase<DT> Base_t;
public:
  typedef typename DT::Size_t Size_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename DT::OneDomain_t OneDomain_t;
  typedef typename Base_t::const_iterator const_iterator;
  typedef typename Base_t::iterator iterator;
  typedef typename Base_t::const_blockIterator const_blockIterator;
  typedef typename Base_t::blockIterator blockIterator;
  inline
  Domain() {
    PoomaCTAssert<(DT::dimensions == Dim && Dim > 0)>::test();
  }
  inline Domain(const Pooma::NoInit &d) : Base_t(d) {
    PoomaCTAssert<(DT::dimensions == Dim && Dim > 0)>::test();
  }
  inline
  ~Domain() { }
  inline
  const OneDomain_t &operator[](int d) const { return this->domain_m[d]; }
  inline
  OneDomain_t &operator[](int d) { return this->domain_m[d]; }
  inline
  Size_t size() const {
    Size_t sz = this->domain_m[0].size();
    for (int i = 1; i < Dim; i++)
      sz *= this->domain_m[i].size();
    return sz;
  }
  inline
  bool empty() const {
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i].empty())
        return true;
    return false;
  }
  inline
  bool initialized() const { return (!empty()); }
  template<class T>
  bool operator==(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] != DomainTraits<T>::getDomain(d2, i))
        return false;
    return true;
  }
  template<class T>
  bool operator<(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] >= DomainTraits<T>::getDomain(d2, i))
        return false;
    return true;
  }
  template<class T>
  bool operator!=(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] != DomainTraits<T>::getDomain(d2, i))
        return true;
    return false;
  }
  template<class T>
  bool operator>(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] <= DomainTraits<T>::getDomain(d2, i))
        return false;
    return true;
  }
  template<class T>
  bool operator<=(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] > DomainTraits<T>::getDomain(d2, i))
        return false;
    return true;
  }
  template<class T>
  bool operator>=(const T &d2) const {
    PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
    for (int i = 0; i < Dim; i++)
      if (this->domain_m[i] < DomainTraits<T>::getDomain(d2, i))
        return false;
    return true;
  }
  Domain_t &operator++() {
    for (int i=0; i<Dim; ++i)
      this->domain_m[i] += this->domain_m[i].stride();
    return this->unwrap();
  }
  Domain_t &operator--() {
    for (int i=0; i<Dim; ++i)
      this->domain_m[i] -= this->domain_m[i].stride();
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator+=(const T &d2)
  {
    PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1 || Dim == 1)>::test();
    int d = DomainTraits<T>::dimensions > Dim ?
      DomainTraits<T>::dimensions : Dim;
    for (int i = 0; i < d; i++)
      this->domain_m[i] += DomainTraits<T>::getPointDomain(d2, i);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator-=(const T &d2) {
    PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
    for (int i = 0; i < Dim; i++)
      this->domain_m[i] -= DomainTraits<T>::getPointDomain(d2, i);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator*=(const T &d2) {
    PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
    for (int i = 0; i < Dim; i++)
      this->domain_m[i] *= DomainTraits<T>::getPointDomain(d2, i);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator/=(const T &d2) {
    PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
    for (int i = 0; i < Dim; i++)
      this->domain_m[i] /= DomainTraits<T>::getPointDomain(d2, i);
    return this->unwrap();
  }
  template <int Dim2, int C>
  inline
  Domain_t &operator+=(const DomainDelta<Dim2, C>&)
  {
    if (C < Dim)
      this->domain_m[C] += 1;
    return this->unwrap();
  }
  template <int Dim2, int C>
  inline
  Domain_t &operator-=(const DomainDelta<Dim2, C>&)
  {
    if (C < Dim)
      this->domain_m[C] -= 1;
    return this->unwrap();
  }
private:
  Domain(const Domain<Dim,DT> &);
  void operator=(const Domain<Dim,DT> &);
};
template<class DT, class ST, class T, class UT, bool wildcard>
struct SetDomainFunctor
{
  inline
  static void setDomain(ST &domain, const T &newdom) {
    DT::setDomain(domain, newdom);
  }
  inline
  static void setWildcardDomain(ST &domain, const UT &, const T &newdom) {
    DT::setDomain(domain, newdom);
  }
};
template<class DT, class ST, class T, class UT>
struct SetDomainFunctor<DT, ST, T, UT, true>
{
  inline
  static void setDomain(ST &, const T &) { }
  inline
  static void setWildcardDomain(ST &domain, const UT &u, const T &newdom) {
    DT::setWildcardDomain(domain, u, newdom);
  }
};
template<class DT>
class Domain<1, DT> : public DomainBase<DT>
{
  typedef DomainBase<DT> Base_t;
public:
  typedef typename DT::Size_t Size_t;
  typedef typename DT::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::Storage_t Storage_t;
  typedef typename Base_t::const_iterator const_iterator;
  typedef typename Base_t::iterator iterator;
  typedef typename Base_t::const_blockIterator const_blockIterator;
  typedef typename Base_t::blockIterator blockIterator;
  inline
  Domain() { }
  inline
  Domain(const Pooma::NoInit &d) : Base_t(d) { }
  inline
  Domain_t &operator[](int) { return this->unwrap(); }
  inline
  const Domain_t &operator[](int) const { return this->unwrap(); }
  inline
  Element_t elem(int n) const { return DT::elem(this->domain_m, n); }
  inline
  Element_t operator()(int n) const { return DT::elem(this->domain_m, n); }
  inline
  Element_t first() const { return DT::first(this->domain_m); }
  inline
  Element_t last() const { return DT::last(this->domain_m); }
  inline
  Element_t stride() const { return DT::stride(this->domain_m); }
  inline
  Size_t length() const { return DT::length(this->domain_m); }
  inline
  Element_t min() const { return DT::min(this->domain_m); }
  inline
  Element_t max() const { return DT::max(this->domain_m); }
  inline
  Size_t size() const { return length(); }
  inline
  bool empty() const { return DT::empty(this->domain_m); }
  inline
  bool initialized() const { return (!empty()); }
  inline
  int loop() const { return DT::loop(this->domain_m); }
  template<class T>
  inline
  void setDomain(const T &newdom) {
    SetDomainFunctor<DT,Storage_t,T,T,DomainTraits<T>::wildcard>::
      setDomain(this->domain_m, newdom);
  }
  template<class UT, class T>
  inline
  void setWildcardDomain(const UT &u, const T &newdom) {
    SetDomainFunctor<DT,Storage_t,T,UT,DomainTraits<T>::wildcard>::
      setWildcardDomain(this->domain_m, u, newdom);
  }
  inline
  void setLoop(int newloop) { DT::setLoop(this->domain_m, newloop); }
  template<class T>
  bool operator==(const T &d2) const {
    return DT::isEqualTo(this->domain_m, d2);
  }
  template<class T>
  bool operator<(const T &d2) const {
    return DT::isLessThan(this->domain_m, d2);
  }
  template<class T>
  bool operator!=(const T &d2) const { return !(*this == d2); }
  template<class T>
  bool operator>(const T &d2) const { return !(*this < d2 || *this == d2); }
  template<class T>
  bool operator<=(const T &d2) const { return (*this < d2 || *this == d2); }
  template<class T>
  bool operator>=(const T &d2) const { return !(*this < d2); }
  Domain_t &operator++() {
    DT::addAccum(this->domain_m, DT::stride(this->domain_m));
    return this->unwrap();
  }
  Domain_t &operator--() {
    DT::subtractAccum(this->domain_m, DT::stride(this->domain_m));
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator+=(const T &d2) {
    DT::addAccum(this->domain_m, d2);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator-=(const T &d2) {
    DT::subtractAccum(this->domain_m, d2);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator*=(const T &d2) {
    DT::multiplyAccum(this->domain_m, d2);
    return this->unwrap();
  }
  template<class T>
  inline
  Domain_t &operator/=(const T &d2) {
    DT::divideAccum(this->domain_m, d2);
    return this->unwrap();
  }
  template <int Dim2, int C>
  inline
  Domain_t &operator+=(const DomainDelta<Dim2, C>&)
  {
    if (C == 0)
      DT::addAccum(this->domain_m, 1);
    return this->unwrap();
  }
  template <int Dim2, int C>
  inline
  Domain_t &operator-=(const DomainDelta<Dim2, C>&)
  {
    if (C == 0)
      DT::subtractAccum(this->domain_m, 1);
    return this->unwrap();
  }
private:
  Domain(const Domain<1,DT> &);
  void operator=(const Domain<1,DT> &);
};
template <int Dim> class Loc;
template <> class Loc<1>;
template <int Dim> class Interval;
template <> class Interval<1>;
template <int Dim> class Range;
template <> class Range<1>;
template<int Dim>
struct DomainTraits< Interval<Dim> >
  : public DomainTraitsDomain<Interval<Dim>, int, Dim>
{
  typedef DomainTraitsDomain<Interval<Dim>, int, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef Interval<1> OneDomain_t;
  typedef Interval<1> PointDomain_t;
  typedef Interval<Dim> BlockDomain_t;
  typedef Loc<Dim> AskDomain_t;
  typedef Interval<Dim> AddResult_t;
  typedef Range<Dim> MultResult_t;
  typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = Dim };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = true };
  enum { wildcard = false };
  inline
  static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
  inline
  static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
  inline
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  inline
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  inline
  static void initializeStorage(Storage_t &dom) {
    Dom1Initialize<Dim-1>::template apply<DomainTraits<Interval<Dim> > >(dom);
  }
};
template<>
struct DomainTraits< Interval<1> >
  : public DomainTraitsDomain<Interval<1>, int, 1>
{
  typedef Interval<1> OneDomain_t;
  typedef Interval<1> PointDomain_t;
  typedef Interval<1> BlockDomain_t;
  typedef Loc<1> AskDomain_t;
  typedef Interval<1> AddResult_t;
  typedef Range<1> MultResult_t;
  typedef Element_t Storage_t[2];
  enum { dimensions = 1,
         sliceDimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = true };
  enum { wildcard = false };
  inline
  static Element_t first(const Storage_t &d) { return d[0]; }
  inline
  static Element_t last(const Storage_t &d) { return d[0] + d[1] - 1; }
  inline
  static Element_t stride(const Storage_t &) { return 1; }
  inline
  static Element_t length(const Storage_t &d) { return d[1]; }
  inline
  static Element_t min(const Storage_t &d) { return d[0]; }
  inline
  static Element_t max(const Storage_t &d) { return d[0] + d[1] - 1; }
  inline
  static bool empty(const Storage_t &d) { return (d[1] < 1); }
  inline
  static int loop(const Storage_t &) { return 0; }
  inline
  static Element_t elem(const Storage_t &d, int n) { return d[0] + n; }
  inline
  static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
  inline
  static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
  inline
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  inline
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  inline
  static void initializeStorage(Storage_t &dom) {
    dom[0] = 0;
    dom[1] = 0;
  }
  template<class T>
  inline
  static void setDomain(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    dom[0] = DomainTraits<T>::getFirst(newdom);
    dom[1] = DomainTraits<T>::getLength(newdom);
  }
  template<class T1, class T2>
  inline
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
    dom[0] = begval;
    dom[1] = (endval - begval + 1);
    ;
  }
  inline
  static void setLoop(Storage_t &, int) { }
  template<class UT, class T>
  inline
  static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
    dom[0] = newdom.first(u);
    dom[1] = newdom.length(u);
  }
  template<class T>
  static bool isLessThan(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    return (dom[1] < DomainTraits<T>::getLength(newdom) ||
     (dom[1] == DomainTraits<T>::getLength(newdom) &&
      (dom[0] < DomainTraits<T>::getFirst(newdom) ||
       (dom[0] == DomainTraits<T>::getFirst(newdom) &&
        DomainTraits<T>::getStride(newdom) > 1))));
  }
  template<class T>
  static bool isEqualTo(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    return ((dom[1] == 0 && DomainTraits<T>::getLength(newdom) == 0) ||
     (dom[0] == DomainTraits<T>::getFirst(newdom) &&
      dom[1] == DomainTraits<T>::getLength(newdom) &&
      DomainTraits<T>::getStride(newdom) == 1));
  }
  template<class T>
  inline
  static void addAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] += DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  inline
  static void subtractAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] -= DomainTraits<T>::getFirst(newdom);
  }
};
template<int Dim1, int Dim2>
struct DomainChangeDim<Interval<Dim1>, Dim2>
{
  typedef Interval<Dim1> OldType_t;
  typedef Interval<Dim2> NewType_t;
  enum { oldDim = Dim1,
  newDim = Dim2 };
};
template<int Dim> class Loc;
template<int Dim> class Interval;
template<int Dim> class Range;
template<int Dim> class Grid;
template<int Dim> class AllDomain;
template<int Dim> class LeftDomain;
template<int Dim> class RightDomain;
template<int Dim, int SliceDim> class SliceInterval;
template<int Dim, int SliceDim> class SliceRange;
template<int Dim, class T> class Region;
template<class T> class IndirectionList;
template<class RT, class CT, int DS>
struct CombineDomain {
  enum { DRT = DomainTraits<RT>::dimensions };
  enum { DCT = DomainTraits<CT>::dimensions };
  static void combine(RT &rt, const CT& ct) {
    PoomaCTAssert<(DS >= 0)>::test();
    PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
    for (int i=0; i < DCT; ++i)
      DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
                         DomainTraits<CT>::getDomain(ct, i));
  }
};
template<class RT, class UT, class CT, int DS, int SliceDS,
         bool incl, bool wc>
struct CombineSliceDomainWC {
  enum { DRT = DomainTraits<RT>::dimensions };
  enum { DCT = DomainTraits<CT>::dimensions };
  static void combine(RT &rt, const UT &, const CT& ct) {
    PoomaCTAssert<(DS >= 0)>::test();
    PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
    for (int i=0; i < DCT; ++i)
      DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
                         DomainTraits<CT>::getPointDomain(ct, i));
  }
};
template<class RT, class UT, class CT, int DS, int SliceDS>
struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,true,false> {
  enum { DRT = DomainTraits<RT>::dimensions };
  enum { DCT = DomainTraits<CT>::dimensions };
  static void combine(RT &rt, const UT &, const CT& ct) {
    PoomaCTAssert<(DS >= 0 && SliceDS >= 0)>::test();
    PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
    for (int i=0; i < DCT; ++i) {
      DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
 DomainTraits<CT>::getPointDomain(ct, i));
      DomainTraits<RT>::setIgnorable(rt, DS + i,
        DomainTraits<CT>::getIgnorable(ct, i));
    }
    rt.setSliceFromTotal();
  }
};
template<class RT, class UT, class CT, int DS, int SliceDS>
struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,false,true> {
  enum { DRT = DomainTraits<RT>::dimensions };
  enum { DUT = DomainTraits<UT>::dimensions };
  enum { DCT = DomainTraits<CT>::dimensions };
  static void combine(RT &rt, const UT &u, const CT& ct) {
    PoomaCTAssert<(DS >= 0)>::test();
    PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
    PoomaCTAssert<(DUT == DRT)>::test();
    for (int i=0; i < DCT; ++i)
      DomainTraits<RT>::getDomain(rt, DS + i).setWildcardDomain(
 DomainTraits<UT>::getPointDomain(u, DS + i),
 DomainTraits<CT>::getPointDomain(ct, i));
  }
};
template<class RT, class UT, class CT, int DS, int SliceDS>
struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,true,true> {
  enum { DRT = DomainTraits<RT>::dimensions };
  enum { DUT = DomainTraits<UT>::dimensions };
  enum { DCT = DomainTraits<CT>::dimensions };
  static void combine(RT &rt, const UT &u, const CT& ct) {
    PoomaCTAssert<(DS >= 0 && SliceDS >= 0)>::test();
    PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
    PoomaCTAssert<((int)DUT == DRT)>::test();
    for (int i=0; i < DCT; ++i) {
      DomainTraits<RT>::getDomain(rt, DS + i).setWildcardDomain(
 DomainTraits<UT>::getPointDomain(u, DS + i),
 DomainTraits<CT>::getPointDomain(ct, i));
      DomainTraits<RT>::getSliceDomain(rt, SliceDS + i).setWildcardDomain(
 DomainTraits<UT>::getPointDomain(u, DS + i),
 DomainTraits<CT>::getPointDomain(ct, i));
      DomainTraits<RT>::cantIgnoreDomain(rt, DS + i);
    }
  }
};
template<class RT, class UT, class CT, int DS, int SliceDS, bool incl>
struct CombineSliceDomain {
  static void combine(RT &rt, const UT &u, const CT& ct) {
    CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,incl,
      DomainTraits<CT>::wildcard>::combine(rt, u, ct);
  }
};
template<class T1, class T2, class TCombine, class TSCombine>
struct NewDomain2Base
{
  typedef TCombine Type_t;
  typedef TSCombine SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a, b);
    }
  template<class RT>
  inline static RT &fill(RT &retval, const T1 &a, const T2 &b)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::
 combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::
 combine(retval,u,b);
      return retval;
    }
};
template<class T1, class T2>
struct AddNewDomain2Dimensions
{
  enum { dimensions =
    DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions };
};
template<class T1, class T2>
struct NewDomain2
  : public NewDomain2Base<T1, T2,
                          Interval<AddNewDomain2Dimensions<T1,T2>::dimensions>,
                          Loc<AddNewDomain2Dimensions<T1,T2>::dimensions> >
{ };
template <int D1, int D2> struct NewDomain2< Range<D1>, Range<D2> > : public NewDomain2Base< Range<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Range<D1>, Loc<D2> > : public NewDomain2Base< Range<D1>, Loc<D2>, Range<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Range<D1> > : public NewDomain2Base< Loc<D2>, Range<D1>, Range<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D> struct NewDomain2< Range<D>, char > : public NewDomain2Base< Range<D>, char, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< char, Range<D> > : public NewDomain2Base< char, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned char > : public NewDomain2Base< Range<D>, unsigned char, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, Range<D> > : public NewDomain2Base< unsigned char, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, short > : public NewDomain2Base< Range<D>, short, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< short, Range<D> > : public NewDomain2Base< short, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned short > : public NewDomain2Base< Range<D>, unsigned short, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Range<D> > : public NewDomain2Base< unsigned short, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, int > : public NewDomain2Base< Range<D>, int, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< int, Range<D> > : public NewDomain2Base< int, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned int > : public NewDomain2Base< Range<D>, unsigned int, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, Range<D> > : public NewDomain2Base< unsigned int, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, long > : public NewDomain2Base< Range<D>, long, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< long, Range<D> > : public NewDomain2Base< long, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned long > : public NewDomain2Base< Range<D>, unsigned long, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Range<D> > : public NewDomain2Base< unsigned long, Range<D>, Range<D+1>, SliceRange<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< Range<D1>, Interval<D2> > : public NewDomain2Base< Range<D1>, Interval<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Range<D2> > : public NewDomain2Base< Interval<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Range<D1>, AllDomain<D2> > : public NewDomain2Base< Range<D1>, AllDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Range<D2> > : public NewDomain2Base< AllDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Range<D1>, LeftDomain<D2> > : public NewDomain2Base< Range<D1>, LeftDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Range<D2> > : public NewDomain2Base< LeftDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Range<D1>, RightDomain<D2> > : public NewDomain2Base< Range<D1>, RightDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Range<D2> > : public NewDomain2Base< RightDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Loc<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Loc<D2>, SliceRange<D1+D2,DS1>, SliceRange<D1+D2,DS1> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Loc<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Loc<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1>, SliceRange<D1+D2,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, char > : public NewDomain2Base< SliceRange<D1,DS1>, char ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned char > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned char, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< char, SliceRange<D1,DS1> > : public NewDomain2Base< char, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned char, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned char, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, short > : public NewDomain2Base< SliceRange<D1,DS1>, short ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned short > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned short, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< short, SliceRange<D1,DS1> > : public NewDomain2Base< short, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned short, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned short, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, int > : public NewDomain2Base< SliceRange<D1,DS1>, int ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned int > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned int, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< int, SliceRange<D1,DS1> > : public NewDomain2Base< int, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned int, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned int, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, long > : public NewDomain2Base< SliceRange<D1,DS1>, long ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned long > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned long, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< long, SliceRange<D1,DS1> > : public NewDomain2Base< long, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned long, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned long, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Range<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Range<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Range<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Range<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Interval<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Interval<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Interval<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Interval<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, AllDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, AllDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< AllDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< AllDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, LeftDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, LeftDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< LeftDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< LeftDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, RightDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, RightDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< RightDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< RightDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int D2> struct NewDomain2< Interval<D1>, Interval<D2> > : public NewDomain2Base< Interval<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Loc<D2> > : public NewDomain2Base< Interval<D1>, Loc<D2>, Interval<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Interval<D1> > : public NewDomain2Base< Loc<D2>, Interval<D1>, Interval<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< Interval<D>, char > : public NewDomain2Base< Interval<D>, char, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, Interval<D> > : public NewDomain2Base< char, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned char > : public NewDomain2Base< Interval<D>, unsigned char, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, Interval<D> > : public NewDomain2Base< unsigned char, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, short > : public NewDomain2Base< Interval<D>, short, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, Interval<D> > : public NewDomain2Base< short, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned short > : public NewDomain2Base< Interval<D>, unsigned short, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Interval<D> > : public NewDomain2Base< unsigned short, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, int > : public NewDomain2Base< Interval<D>, int, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, Interval<D> > : public NewDomain2Base< int, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned int > : public NewDomain2Base< Interval<D>, unsigned int, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, Interval<D> > : public NewDomain2Base< unsigned int, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, long > : public NewDomain2Base< Interval<D>, long, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, Interval<D> > : public NewDomain2Base< long, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned long > : public NewDomain2Base< Interval<D>, unsigned long, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Interval<D> > : public NewDomain2Base< unsigned long, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< Interval<D1>, AllDomain<D2> > : public NewDomain2Base< Interval<D1>, AllDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Interval<D2> > : public NewDomain2Base< AllDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Interval<D1>, LeftDomain<D2> > : public NewDomain2Base< Interval<D1>, LeftDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Interval<D2> > : public NewDomain2Base< LeftDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Interval<D1>, RightDomain<D2> > : public NewDomain2Base< Interval<D1>, RightDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Interval<D2> > : public NewDomain2Base< RightDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Loc<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Loc<D2>, SliceInterval<D1+D2,DS1>, SliceInterval<D1+D2,DS1> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Loc<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Loc<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1>, SliceInterval<D1+D2,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, char > : public NewDomain2Base< SliceInterval<D1,DS1>, char ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned char > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned char, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< char, SliceInterval<D1,DS1> > : public NewDomain2Base< char, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned char, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned char, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, short > : public NewDomain2Base< SliceInterval<D1,DS1>, short ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned short > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned short, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< short, SliceInterval<D1,DS1> > : public NewDomain2Base< short, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned short, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned short, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, int > : public NewDomain2Base< SliceInterval<D1,DS1>, int ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned int > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned int, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< int, SliceInterval<D1,DS1> > : public NewDomain2Base< int, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned int, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned int, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, long > : public NewDomain2Base< SliceInterval<D1,DS1>, long ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned long > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned long, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< long, SliceInterval<D1,DS1> > : public NewDomain2Base< long, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned long, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned long, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Interval<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Interval<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Interval<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Interval<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Range<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Range<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Range<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Range<D2>, SliceInterval<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, AllDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, AllDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< AllDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< AllDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, LeftDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, LeftDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< LeftDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< LeftDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, RightDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, RightDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< RightDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< RightDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
template <int D1, int D2> struct NewDomain2< AllDomain<D1>, AllDomain<D2> > : public NewDomain2Base< AllDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Loc<D2> > : public NewDomain2Base< AllDomain<D1>, Loc<D2>, AllDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, AllDomain<D1> > : public NewDomain2Base< Loc<D2>, AllDomain<D1>, AllDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< AllDomain<D>, char > : public NewDomain2Base< AllDomain<D>, char, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, AllDomain<D> > : public NewDomain2Base< char, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned char > : public NewDomain2Base< AllDomain<D>, unsigned char, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, AllDomain<D> > : public NewDomain2Base< unsigned char, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, short > : public NewDomain2Base< AllDomain<D>, short, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, AllDomain<D> > : public NewDomain2Base< short, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned short > : public NewDomain2Base< AllDomain<D>, unsigned short, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, AllDomain<D> > : public NewDomain2Base< unsigned short, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, int > : public NewDomain2Base< AllDomain<D>, int, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, AllDomain<D> > : public NewDomain2Base< int, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned int > : public NewDomain2Base< AllDomain<D>, unsigned int, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, AllDomain<D> > : public NewDomain2Base< unsigned int, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, long > : public NewDomain2Base< AllDomain<D>, long, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, AllDomain<D> > : public NewDomain2Base< long, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned long > : public NewDomain2Base< AllDomain<D>, unsigned long, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, AllDomain<D> > : public NewDomain2Base< unsigned long, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, LeftDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Loc<D2> > : public NewDomain2Base< LeftDomain<D1>, Loc<D2>, LeftDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, LeftDomain<D1> > : public NewDomain2Base< Loc<D2>, LeftDomain<D1>, LeftDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< LeftDomain<D>, char > : public NewDomain2Base< LeftDomain<D>, char, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, LeftDomain<D> > : public NewDomain2Base< char, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned char > : public NewDomain2Base< LeftDomain<D>, unsigned char, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, LeftDomain<D> > : public NewDomain2Base< unsigned char, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, short > : public NewDomain2Base< LeftDomain<D>, short, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, LeftDomain<D> > : public NewDomain2Base< short, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned short > : public NewDomain2Base< LeftDomain<D>, unsigned short, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, LeftDomain<D> > : public NewDomain2Base< unsigned short, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, int > : public NewDomain2Base< LeftDomain<D>, int, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, LeftDomain<D> > : public NewDomain2Base< int, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned int > : public NewDomain2Base< LeftDomain<D>, unsigned int, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, LeftDomain<D> > : public NewDomain2Base< unsigned int, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, long > : public NewDomain2Base< LeftDomain<D>, long, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, LeftDomain<D> > : public NewDomain2Base< long, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned long > : public NewDomain2Base< LeftDomain<D>, unsigned long, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, LeftDomain<D> > : public NewDomain2Base< unsigned long, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< RightDomain<D1>, RightDomain<D2> > : public NewDomain2Base< RightDomain<D1>, RightDomain<D2>, RightDomain<D1+D2>, RightDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Loc<D2> > : public NewDomain2Base< RightDomain<D1>, Loc<D2>, RightDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, RightDomain<D1> > : public NewDomain2Base< Loc<D2>, RightDomain<D1>, RightDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< RightDomain<D>, char > : public NewDomain2Base< RightDomain<D>, char, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, RightDomain<D> > : public NewDomain2Base< char, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned char > : public NewDomain2Base< RightDomain<D>, unsigned char, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, RightDomain<D> > : public NewDomain2Base< unsigned char, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, short > : public NewDomain2Base< RightDomain<D>, short, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, RightDomain<D> > : public NewDomain2Base< short, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned short > : public NewDomain2Base< RightDomain<D>, unsigned short, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, RightDomain<D> > : public NewDomain2Base< unsigned short, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, int > : public NewDomain2Base< RightDomain<D>, int, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, RightDomain<D> > : public NewDomain2Base< int, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned int > : public NewDomain2Base< RightDomain<D>, unsigned int, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, RightDomain<D> > : public NewDomain2Base< unsigned int, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, long > : public NewDomain2Base< RightDomain<D>, long, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, RightDomain<D> > : public NewDomain2Base< long, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned long > : public NewDomain2Base< RightDomain<D>, unsigned long, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, RightDomain<D> > : public NewDomain2Base< unsigned long, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< AllDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< AllDomain<D1>, LeftDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, AllDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< AllDomain<D1>, RightDomain<D2> > : public NewDomain2Base< AllDomain<D1>, RightDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, AllDomain<D2> > : public NewDomain2Base< RightDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, RightDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, RightDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< RightDomain<D1>, LeftDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, Grid<D2> > : public NewDomain2Base< Grid<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Grid<D1>, Loc<D2> > : public NewDomain2Base< Grid<D1>, Loc<D2>, Grid<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Grid<D1> > : public NewDomain2Base< Loc<D2>, Grid<D1>, Grid<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D> struct NewDomain2< Grid<D>, char > : public NewDomain2Base< Grid<D>, char, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< char, Grid<D> > : public NewDomain2Base< char, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned char > : public NewDomain2Base< Grid<D>, unsigned char, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, Grid<D> > : public NewDomain2Base< unsigned char, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, short > : public NewDomain2Base< Grid<D>, short, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< short, Grid<D> > : public NewDomain2Base< short, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned short > : public NewDomain2Base< Grid<D>, unsigned short, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Grid<D> > : public NewDomain2Base< unsigned short, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, int > : public NewDomain2Base< Grid<D>, int, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< int, Grid<D> > : public NewDomain2Base< int, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned int > : public NewDomain2Base< Grid<D>, unsigned int, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, Grid<D> > : public NewDomain2Base< unsigned int, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, long > : public NewDomain2Base< Grid<D>, long, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< long, Grid<D> > : public NewDomain2Base< long, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned long > : public NewDomain2Base< Grid<D>, unsigned long, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Grid<D> > : public NewDomain2Base< unsigned long, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, Range<D2> > : public NewDomain2Base< Grid<D1>, Range<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Range<D1>, Grid<D2> > : public NewDomain2Base< Range<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, Interval<D2> > : public NewDomain2Base< Grid<D1>, Interval<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Grid<D2> > : public NewDomain2Base< Interval<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, AllDomain<D2> > : public NewDomain2Base< Grid<D1>, AllDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Grid<D2> > : public NewDomain2Base< AllDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, LeftDomain<D2> > : public NewDomain2Base< Grid<D1>, LeftDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Grid<D2> > : public NewDomain2Base< LeftDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
template <int D1, int D2> struct NewDomain2< Grid<D1>, RightDomain<D2> > : public NewDomain2Base< Grid<D1>, RightDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Grid<D2> > : public NewDomain2Base< RightDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
template<int D>
struct NewDomain2< Grid<D>, IndirectionList<int> >
  : public NewDomain2Base<Grid<D>,IndirectionList<int>,Grid<D+1>,Grid<D+1> >{};
template<int D>
struct NewDomain2< IndirectionList<int>, Grid<D> >
  : public NewDomain2Base<IndirectionList<int>,Grid<D>,Grid<D+1>,Grid<D+1> >{};
template<int D1, int D2>
struct NewDomain2< Loc<D1>, Loc<D2> >
  : public NewDomain2Base<Loc<D1>, Loc<D2>, Loc<D1+D2>, Loc<D1+D2> > { };
template <int D1, class T1, int D2, class T2> struct NewDomain2< Region<D1,T1>, Region<D2,T2> > : public NewDomain2Base< Region<D1,T1>, Region<D2,T2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, char > : public NewDomain2Base< Region<D1,T1>, char, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< char, Region<D1,T1> > : public NewDomain2Base< char, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned char > : public NewDomain2Base< Region<D1,T1>, unsigned char, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned char, Region<D1,T1> > : public NewDomain2Base< unsigned char, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, short > : public NewDomain2Base< Region<D1,T1>, short, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< short, Region<D1,T1> > : public NewDomain2Base< short, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned short > : public NewDomain2Base< Region<D1,T1>, unsigned short, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned short, Region<D1,T1> > : public NewDomain2Base< unsigned short, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, int > : public NewDomain2Base< Region<D1,T1>, int, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< int, Region<D1,T1> > : public NewDomain2Base< int, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned int > : public NewDomain2Base< Region<D1,T1>, unsigned int, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned int, Region<D1,T1> > : public NewDomain2Base< unsigned int, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, long > : public NewDomain2Base< Region<D1,T1>, long, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< long, Region<D1,T1> > : public NewDomain2Base< long, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned long > : public NewDomain2Base< Region<D1,T1>, unsigned long, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned long, Region<D1,T1> > : public NewDomain2Base< unsigned long, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, float > : public NewDomain2Base< Region<D1,T1>, float, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< float, Region<D1,T1> > : public NewDomain2Base< float, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1> struct NewDomain2< Region<D1,T1>, double > : public NewDomain2Base< Region<D1,T1>, double, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< double, Region<D1,T1> > : public NewDomain2Base< double, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Range<D2> > : public NewDomain2Base< Region<D1,T1>, Range<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Range<D2>, Region<D1,T1> > : public NewDomain2Base< Range<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Interval<D2> > : public NewDomain2Base< Region<D1,T1>, Interval<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Interval<D2>, Region<D1,T1> > : public NewDomain2Base< Interval<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Loc<D2> > : public NewDomain2Base< Region<D1,T1>, Loc<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Loc<D2>, Region<D1,T1> > : public NewDomain2Base< Loc<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, AllDomain<D2> > : public NewDomain2Base< Region<D1,T1>, AllDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< AllDomain<D2>, Region<D1,T1> > : public NewDomain2Base< AllDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, LeftDomain<D2> > : public NewDomain2Base< Region<D1,T1>, LeftDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< LeftDomain<D2>, Region<D1,T1> > : public NewDomain2Base< LeftDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, RightDomain<D2> > : public NewDomain2Base< Region<D1,T1>, RightDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< RightDomain<D2>, Region<D1,T1> > : public NewDomain2Base< RightDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
template <> struct NewDomain2<double, double> : public NewDomain2Base< double, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<float, float> : public NewDomain2Base< float, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<double, char> : public NewDomain2Base< double, char, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<char, double> : public NewDomain2Base< char, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, unsigned char> : public NewDomain2Base< double, unsigned char, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned char, double> : public NewDomain2Base< unsigned char, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, short> : public NewDomain2Base< double, short, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<short, double> : public NewDomain2Base< short, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, unsigned short> : public NewDomain2Base< double, unsigned short, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned short, double> : public NewDomain2Base< unsigned short, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, int> : public NewDomain2Base< double, int, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<int, double> : public NewDomain2Base< int, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, unsigned int> : public NewDomain2Base< double, unsigned int, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned int, double> : public NewDomain2Base< unsigned int, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, long> : public NewDomain2Base< double, long, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<long, double> : public NewDomain2Base< long, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, unsigned long> : public NewDomain2Base< double, unsigned long, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned long, double> : public NewDomain2Base< unsigned long, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<double, float> : public NewDomain2Base< double, float, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<float, double> : public NewDomain2Base< float, double, Region<2,double>, Region<2,double> > { };
template <> struct NewDomain2<float, char> : public NewDomain2Base< float, char, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<char, float> : public NewDomain2Base< char, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, unsigned char> : public NewDomain2Base< float, unsigned char, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned char, float> : public NewDomain2Base< unsigned char, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, short> : public NewDomain2Base< float, short, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<short, float> : public NewDomain2Base< short, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, unsigned short> : public NewDomain2Base< float, unsigned short, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned short, float> : public NewDomain2Base< unsigned short, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, int> : public NewDomain2Base< float, int, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<int, float> : public NewDomain2Base< int, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, unsigned int> : public NewDomain2Base< float, unsigned int, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned int, float> : public NewDomain2Base< unsigned int, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, long> : public NewDomain2Base< float, long, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<long, float> : public NewDomain2Base< long, float, Region<2,float>, Region<2,float> > { };
template <> struct NewDomain2<float, unsigned long> : public NewDomain2Base< float, unsigned long, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned long, float> : public NewDomain2Base< unsigned long, float, Region<2,float>, Region<2,float> > { };
template <int D1> struct NewDomain2< double, Loc<D1> > : public NewDomain2Base< double, Loc<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Loc<D1>, double > : public NewDomain2Base< Loc<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
template <int D1> struct NewDomain2< double, Interval<D1> > : public NewDomain2Base< double, Interval<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Interval<D1>, double > : public NewDomain2Base< Interval<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
template <int D1> struct NewDomain2< double, Range<D1> > : public NewDomain2Base< double, Range<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Range<D1>, double > : public NewDomain2Base< Range<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
template <int D1> struct NewDomain2< float, Loc<D1> > : public NewDomain2Base< float, Loc<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Loc<D1>, float > : public NewDomain2Base< Loc<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
template <int D1> struct NewDomain2< float, Interval<D1> > : public NewDomain2Base< float, Interval<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Interval<D1>, float > : public NewDomain2Base< Interval<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
template <int D1> struct NewDomain2< float, Range<D1> > : public NewDomain2Base< float, Range<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Range<D1>, float > : public NewDomain2Base< Range<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
template<class ND, class T>
struct NewDomainNBase
{
  typedef typename ND::Type_t PrevType_t;
  typedef typename ND::SliceType_t PrevSliceType_t;
  typedef typename NewDomain2<PrevType_t,T>::Type_t Type_t;
  typedef typename NewDomain2<PrevSliceType_t,T>::SliceType_t SliceType_t;
};
template<class T1>
struct NewDomain1
{
  typedef typename DomainTraits<T1>::Domain_t Type_t;
  typedef typename DomainTraits<T1>::NewDomain1_t SliceType_t;
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  inline static Type_t combine(const T1 &a)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a);
    }
  template<class RT>
  inline static RT &fill(RT &retval, const T1 &a)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u, const T1 &a)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      return retval;
    }
};
template<class T1, class T2, class T3>
struct NewDomain3 : public NewDomainNBase<NewDomain2<T1,T2>, T3>
{
  typedef typename NewDomainNBase<NewDomain2<T1,T2>, T3>::Type_t Type_t;
  typedef typename NewDomainNBase<NewDomain2<T1,T2>, T3>::SliceType_t SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { S3 = S2 + DomainTraits<T2>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  enum { DX3 = DomainTraits<T3>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a, b, c);
    }
  template<class RT>
  inline static RT &fill(RT &retval,
    const T1 &a, const T2 &b, const T3 &c)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      CombineDomain<RT,T3,S3>::combine(retval,c);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b, const T3 &c)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b, c);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b, const T3 &c)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
      CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
        combine(retval,u,c);
      return retval;
    }
};
template<class T1, class T2, class T3, class T4>
struct NewDomain4 : public NewDomainNBase<NewDomain3<T1,T2,T3>, T4>
{
  typedef typename NewDomainNBase<NewDomain3<T1,T2,T3>, T4>::Type_t Type_t;
  typedef typename NewDomainNBase<NewDomain3<T1,T2,T3>, T4>::SliceType_t
    SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { S3 = S2 + DomainTraits<T2>::dimensions };
  enum { S4 = S3 + DomainTraits<T3>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  enum { DX3 = DomainTraits<T3>::sliceDimensions };
  enum { DX4 = DomainTraits<T4>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c,
          const T4 &d)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a, b, c, d);
    }
  template<class RT>
  inline static RT &fill(RT &retval,
    const T1 &a, const T2 &b, const T3 &c,
    const T4 &d)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      CombineDomain<RT,T3,S3>::combine(retval,c);
      CombineDomain<RT,T4,S4>::combine(retval,d);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b, const T3 &c,
      const T4 &d)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b, c, d);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b, const T3 &c,
         const T4 &d)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
      CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
        combine(retval,u,c);
      CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
        combine(retval,u,d);
      return retval;
    }
};
template<class T1, class T2, class T3, class T4, class T5>
struct NewDomain5 : public NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>
{
  typedef typename NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>::Type_t Type_t;
  typedef typename NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>::SliceType_t
    SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { S3 = S2 + DomainTraits<T2>::dimensions };
  enum { S4 = S3 + DomainTraits<T3>::dimensions };
  enum { S5 = S4 + DomainTraits<T4>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  enum { DX3 = DomainTraits<T3>::sliceDimensions };
  enum { DX4 = DomainTraits<T4>::sliceDimensions };
  enum { DX5 = DomainTraits<T5>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c,
          const T4 &d, const T5 &e)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a, b, c, d, e);
    }
  template<class RT>
  inline static RT &fill(RT &retval,
    const T1 &a, const T2 &b, const T3 &c,
    const T4 &d, const T5 &e)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      CombineDomain<RT,T3,S3>::combine(retval,c);
      CombineDomain<RT,T4,S4>::combine(retval,d);
      CombineDomain<RT,T5,S5>::combine(retval,e);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b, const T3 &c,
      const T4 &d, const T5 &e)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b, c, d, e);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b, const T3 &c,
         const T4 &d, const T5 &e)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
      CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
        combine(retval,u,c);
      CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
        combine(retval,u,d);
      CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
        combine(retval,u,e);
      return retval;
    }
};
template<class T1, class T2, class T3, class T4, class T5, class T6>
struct NewDomain6 : public NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>
{
  typedef typename
    NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>::Type_t Type_t;
  typedef typename
    NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>::SliceType_t SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { S3 = S2 + DomainTraits<T2>::dimensions };
  enum { S4 = S3 + DomainTraits<T3>::dimensions };
  enum { S5 = S4 + DomainTraits<T4>::dimensions };
  enum { S6 = S5 + DomainTraits<T5>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  enum { DX3 = DomainTraits<T3>::sliceDimensions };
  enum { DX4 = DomainTraits<T4>::sliceDimensions };
  enum { DX5 = DomainTraits<T5>::sliceDimensions };
  enum { DX6 = DomainTraits<T6>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b,
          const T3 &c, const T4 &d,
          const T5 &e, const T6 &f)
    {
      Type_t retval = Pooma::NoInit();
      return fill(retval, a, b, c, d, e, f);
    }
  template<class RT>
  inline static RT &fill(RT &retval,
    const T1 &a, const T2 &b,
    const T3 &c, const T4 &d,
    const T5 &e, const T6 &f)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      CombineDomain<RT,T3,S3>::combine(retval,c);
      CombineDomain<RT,T4,S4>::combine(retval,d);
      CombineDomain<RT,T5,S5>::combine(retval,e);
      CombineDomain<RT,T6,S6>::combine(retval,f);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b,
      const T3 &c, const T4 &d,
      const T5 &e, const T6 &f)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b, c, d, e, f);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b, const T3 &c,
         const T4 &d, const T5 &e, const T6 &f)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
      CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
        combine(retval,u,c);
      CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
        combine(retval,u,d);
      CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
        combine(retval,u,e);
      CombineSliceDomain<RT,UT,T6,S6,DX1+DX2+DX3+DX4+DX5,(DX6>0 && RDX)>::
        combine(retval,u,f);
      return retval;
    }
};
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
struct NewDomain7 : public NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>
{
  typedef typename
    NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>::Type_t Type_t;
  typedef typename
    NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>::SliceType_t SliceType_t;
  enum { S2 = DomainTraits<T1>::dimensions };
  enum { S3 = S2 + DomainTraits<T2>::dimensions };
  enum { S4 = S3 + DomainTraits<T3>::dimensions };
  enum { S5 = S4 + DomainTraits<T4>::dimensions };
  enum { S6 = S5 + DomainTraits<T5>::dimensions };
  enum { S7 = S6 + DomainTraits<T6>::dimensions };
  enum { DX1 = DomainTraits<T1>::sliceDimensions };
  enum { DX2 = DomainTraits<T2>::sliceDimensions };
  enum { DX3 = DomainTraits<T3>::sliceDimensions };
  enum { DX4 = DomainTraits<T4>::sliceDimensions };
  enum { DX5 = DomainTraits<T5>::sliceDimensions };
  enum { DX6 = DomainTraits<T6>::sliceDimensions };
  enum { DX7 = DomainTraits<T7>::sliceDimensions };
  inline static Type_t combine(const T1 &a, const T2 &b,
          const T3 &c, const T4 &d,
          const T5 &e, const T6 &f,
          const T7 &g)
    {
      Type_t retval = Pooma::NoInit();
      NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(retval, a, b, c, d, e, f, g);
      return fill(retval, a, b, c, d, e, f,g);
    }
  template<class RT>
  inline static RT &fill(RT &retval,
    const T1 &a, const T2 &b,
    const T3 &c, const T4 &d,
    const T5 &e, const T6 &f,
    const T7 &g)
    {
      CombineDomain<RT,T1,0>::combine(retval,a);
      CombineDomain<RT,T2,S2>::combine(retval,b);
      CombineDomain<RT,T3,S3>::combine(retval,c);
      CombineDomain<RT,T4,S4>::combine(retval,d);
      CombineDomain<RT,T5,S5>::combine(retval,e);
      CombineDomain<RT,T6,S6>::combine(retval,f);
      CombineDomain<RT,T7,S7>::combine(retval,g);
      return retval;
    }
  template<class UT>
  inline static SliceType_t combineSlice(const UT &u,
      const T1 &a, const T2 &b,
      const T3 &c, const T4 &d,
      const T5 &e, const T6 &f,
      const T7 &g)
    {
      SliceType_t retval = Pooma::NoInit();
      return fillSlice(retval, u, a, b, c, d, e, f, g);
    }
  template<class RT, class UT>
  inline static RT &fillSlice(RT &retval, const UT &u,
         const T1 &a, const T2 &b,
         const T3 &c, const T4 &d,
         const T5 &e, const T6 &f,
         const T7 &g)
    {
      enum { RDX =
        DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
      CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
      CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
      CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
        combine(retval,u,c);
      CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
        combine(retval,u,d);
      CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
        combine(retval,u,e);
      CombineSliceDomain<RT,UT,T6,S6,DX1+DX2+DX3+DX4+DX5,(DX6>0 && RDX)>::
        combine(retval,u,f);
      CombineSliceDomain<RT,UT,T7,S7,DX1+DX2+DX3+DX4+DX5+DX6,(DX7>0 && RDX)>::
        combine(retval,u,g);
      return retval;
    }
};
template<class Domain, class Sub>
struct TemporaryNewDomain1
{
  typedef typename NewDomain1<Sub>::SliceType_t SliceType_t;
  static inline
  SliceType_t combineSlice(const Domain &d, const Sub &s)
  {
    return NewDomain1<Sub>::combineSlice(d, s);
  }
};
template<class Domain, int N>
struct TemporaryNewDomain1<Domain, AllDomain<N> >
{
  typedef Domain SliceType_t;
  static inline
  const SliceType_t &combineSlice(const Domain &d, const AllDomain<N> &)
  {
    return d;
  }
};
template<int Dim>
class Interval : public Domain<Dim, DomainTraits<Interval<Dim> > >
{
  typedef DomainTraits< Interval<Dim> > DT_t;
  typedef Domain<Dim, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Interval() { }
  Interval(const Interval<Dim> &a)
    : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
    NewDomain1<Interval<Dim> >::fill(*this, a);
  }
  Interval(const Pooma::NoInit &a)
    : Domain<Dim, DomainTraits<Interval<Dim> > >(a)
  { }
  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);
  }
  ~Interval() { }
  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:
};
template<>
class Interval<1> : public Domain<1, DomainTraits<Interval<1> > >
{
  typedef DomainTraits< Interval<1> > DT_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Interval() { }
  Interval(const Interval<1> &a)
    : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
    NewDomain1<Interval<1> >::fill(*this, a);
  }
  Interval(const Pooma::NoInit &a)
    : Domain<1, DomainTraits<Interval<1> > >(a)
  { }
  template<class T1>
  explicit Interval(const T1 &a)
    : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
    NewDomain1<T1>::fill(*this, a);
  }
  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);
  }
  template<class T1, class T2>
  Interval(const T1 &m, const T2 &n);
  template<class T1, class T2, class T3>
  Interval(const T1 &m, const T2 &n, const T3 &s);
  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);
  }
  const OneDomain_t &operator[](int d) const { return *this; }
  OneDomain_t &operator[](int d) { return *this; }
};
template <class T1, class T2>
inline
Interval<1>::Interval(const T1 &m, const T2 &n)
  : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
  DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
}
template <class T1, class T2, class T3>
inline
Interval<1>::Interval(const T1 &m, const T2 &n, const T3 &s)
  : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
  ;
  DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
}
template <int Dim> class Loc;
template <> class Loc<1>;
template <int Dim> class Interval;
template <> class Interval<1>;
template<int Dim>
struct DomainTraits< Loc<Dim> >
  : public DomainTraitsDomain<Loc<Dim>, int, Dim>
{
  typedef DomainTraitsDomain<Loc<Dim>, int, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef Loc<1> OneDomain_t;
  typedef Loc<1> PointDomain_t;
  typedef Interval<Dim> BlockDomain_t;
  typedef Loc<Dim> AskDomain_t;
  typedef Loc<Dim> AddResult_t;
  typedef Loc<Dim> MultResult_t;
  typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = 0 };
  enum { loopAware = false };
  enum { singleValued = true };
  enum { unitStride = true };
  enum { wildcard = false };
  inline
  static OneDomain_t &getDomain(Domain_t &d, int n) {
    return d[n];
  }
  inline
  static const OneDomain_t &getDomain(const Domain_t &d, int n) {
    return d[n];
  }
  inline
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return d[n];
  }
  inline
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return d[n];
  }
  static void initializeStorage(Storage_t &dom) {
    Dom1Initialize<Dim-1>::template apply<DomainTraits<Loc<Dim> > >(dom);
  }
  template<class T>
  inline
  static void addAccum(Storage_t &dom, const T &newdom)
  {
    PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
    if (DomainTraits<T>::dimensions > 1)
      for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
 dom[i] += DomainTraits<T>::getFirst(newdom[i]);
    else
      for (int i = 0;i< dimensions ; ++i)
 dom[i] += DomainTraits<T>::getFirst(newdom[0]);
  }
  template<class T>
  inline
  static void subtractAccum(Storage_t &dom, const T &newdom)
  {
    PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
    if (DomainTraits<T>::dimensions > 1)
      for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
 dom[i] -= DomainTraits<T>::getFirst(newdom[i]);
    else
      for (int i = 0;i< dimensions ; ++i)
 dom[i] -= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void multiplyAccum(Storage_t &dom, const T &newdom)
  {
    PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
    if (DomainTraits<T>::dimensions > 1)
      for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
 dom[i] *= DomainTraits<T>::getFirst(newdom[i]);
    else
      for (int i = 0;i< dimensions ; ++i)
 dom[i] *= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void divideAccum(Storage_t &dom, const T &newdom)
  {
    PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
    if (DomainTraits<T>::dimensions > 1)
      for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
 dom[i] /= DomainTraits<T>::getFirst(newdom[i]);
    else
      for (int i = 0;i< dimensions ; ++i)
 dom[i] /= DomainTraits<T>::getFirst(newdom);
  }
};
template<>
struct DomainTraits< Loc<1> >
  : public DomainTraitsDomain<Loc<1>, int, 1>
{
  typedef Loc<1> OneDomain_t;
  typedef Loc<1> PointDomain_t;
  typedef Interval<1> BlockDomain_t;
  typedef Loc<1> AskDomain_t;
  typedef Loc<1> AddResult_t;
  typedef Loc<1> MultResult_t;
  typedef Element_t Storage_t;
  enum { dimensions = 1,
         sliceDimensions = 0 };
  enum { loopAware = false };
  enum { singleValued = true };
  enum { unitStride = true };
  enum { wildcard = false };
  inline
  static Element_t first(Storage_t d) { return d; }
  inline
  static Element_t last(Storage_t d) { return d; }
  inline
  static Element_t stride(Storage_t) { return 1; }
  inline
  static Element_t length(Storage_t) { return 1; }
  inline
  static Element_t min(Storage_t d) { return d; }
  inline
  static Element_t max(Storage_t d) { return d; }
  inline
  static bool empty(Storage_t) { return false; }
  inline
  static int loop(Storage_t) { return 0; }
  inline
  static Element_t elem(Storage_t d, int) { return d; }
  inline
  static OneDomain_t &getDomain(Domain_t &d, int) {
    return d;
  }
  inline
  static const OneDomain_t &getDomain(const Domain_t &d, int) {
    return d;
  }
  inline
  static PointDomain_t &getPointDomain(Domain_t &d, int) {
    return d;
  }
  inline
  static const PointDomain_t &getPointDomain(const Domain_t &d, int) {
    return d;
  }
  inline
  static void initializeStorage(Storage_t &dom) {
    dom = 0;
  }
  template<class T>
  inline
  static void setDomain(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    dom = DomainTraits<T>::getFirst(newdom);
  }
  inline
  static void setLoop(Storage_t &, int) { }
  template<class UT, class T>
  inline
  static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
    dom = newdom.first(u);
  }
  template<class T>
  static bool isLessThan(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    return (dom < DomainTraits<T>::getFirst(newdom));
  }
  template<class T>
  static bool isEqualTo(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    return (dom == DomainTraits<T>::getFirst(newdom));
  }
  template<class T>
  inline
  static void addAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
   dom += DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  inline
  static void subtractAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom -= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void multiplyAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom *= DomainTraits<T>::getFirst(newdom);
  }
 template<class T>
  static void divideAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom /= DomainTraits<T>::getFirst(newdom);
  }
};
template<int Dim1, int Dim2>
struct DomainChangeDim<Loc<Dim1>, Dim2>
{
  typedef Loc<Dim1> OldType_t;
  typedef Loc<Dim2> NewType_t;
  enum { oldDim = Dim1,
  newDim = Dim2 };
};
template <int dstIndex, int toGo>
struct FillLocStorage
{
  template <int Dim, class T>
  static inline
  void fill(Loc<Dim> &loc, const T &a)
  {
    PoomaCTAssert<(dstIndex < Dim)>::test();
    loc[dstIndex].setDomain(DomainTraits<T>::getPointDomain(a, DomainTraits<T>::dimensions-toGo-1));
    FillLocStorage<dstIndex+1,toGo-1>::fill(loc, a);
  }
};
template <int dstIndex>
struct FillLocStorage<dstIndex, 0>
{
  template <int Dim, class T>
  static inline
  void fill(Loc<Dim> &loc, const T &a)
  {
    PoomaCTAssert<(dstIndex < Dim)>::test();
    loc[dstIndex].setDomain(DomainTraits<T>::getPointDomain(a, DomainTraits<T>::dimensions-1));
  }
};
template <int i>
struct FillAllLocStorage
{
  template <int Dim, class T>
  inline
  static void fill(Loc<Dim> &loc, const T &a)
  {
    loc[Dim-i-1].setDomain(DomainTraits<T>::getPointDomain(a, 0));
    FillAllLocStorage<i-1>::fill(loc, a);
  }
};
template <>
struct FillAllLocStorage<0>
{
  template <int Dim, class T>
  inline
  static void fill(Loc<Dim> &loc, const T &a)
  {
    loc[Dim-1].setDomain(DomainTraits<T>::getPointDomain(a, 0));
  }
};
template<int Dim, class T1>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a)
{
  FillLocStorage<0, DomainTraits<T1>::dimensions-1>::fill(loc, a);
}
template<int Dim, class T1, class T2>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b)
{
  fillLocStorage(loc, a);
  FillLocStorage<DomainTraits<T1>::dimensions, DomainTraits<T2>::dimensions-1>::fill(loc, b);
}
template<int Dim, class T1, class T2, class T3>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c)
{
  fillLocStorage(loc, a, b);
  FillLocStorage<DomainTraits<T1>::dimensions
     + DomainTraits<T2>::dimensions,
                 DomainTraits<T3>::dimensions-1>::fill(loc, c);
}
template<int Dim, class T1, class T2, class T3, class T4>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
      const T4 &d)
{
  fillLocStorage(loc, a, b, c);
  FillLocStorage<DomainTraits<T1>::dimensions
     + DomainTraits<T2>::dimensions
     + DomainTraits<T3>::dimensions,
                 DomainTraits<T4>::dimensions-1>::fill(loc, d);
}
template<int Dim, class T1, class T2, class T3, class T4, class T5>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
      const T4 &d, const T5 &e)
{
  fillLocStorage(loc, a, b, c, d);
  FillLocStorage<DomainTraits<T1>::dimensions
     + DomainTraits<T2>::dimensions
     + DomainTraits<T3>::dimensions
     + DomainTraits<T4>::dimensions,
                 DomainTraits<T5>::dimensions-1>::fill(loc, e);
}
template<int Dim, class T1, class T2, class T3, class T4, class T5, class T6>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
      const T4 &d, const T5 &e, const T6 &f)
{
  fillLocStorage(loc, a, b, c, d, e);
  FillLocStorage<DomainTraits<T1>::dimensions
     + DomainTraits<T2>::dimensions
     + DomainTraits<T3>::dimensions
     + DomainTraits<T4>::dimensions
     + DomainTraits<T5>::dimensions,
                 DomainTraits<T6>::dimensions-1>::fill(loc, f);
}
template<int Dim, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
inline
void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
      const T4 &d, const T5 &e, const T6 &f, const T7 &g)
{
  fillLocStorage(loc, a, b, c, d, e, f);
  FillLocStorage<DomainTraits<T1>::dimensions
     + DomainTraits<T2>::dimensions
     + DomainTraits<T3>::dimensions
     + DomainTraits<T4>::dimensions
     + DomainTraits<T5>::dimensions
     + DomainTraits<T6>::dimensions,
                 DomainTraits<T7>::dimensions-1>::fill(loc, g);
}
template<int Dim, class T, int DimT, bool wildcard>
struct CopyLocStorageImpl
{
  inline
  static void copy(Loc<Dim> &, const T &) { }
};
template<int Dim, class T, int DimT>
struct CopyLocStorageImpl<Dim, T, DimT, false>
{
  inline
  static void copy(Loc<Dim> &loc, const T &a) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == DimT)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions <= Dim)>::test();
    fillLocStorage(loc, a);
  }
};
template<int Dim, class T>
struct CopyLocStorageImpl<Dim, T, 1, false>
{
  inline
  static void copy(Loc<Dim> &loc, const T &a) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    FillAllLocStorage<Dim-1>::fill(loc, a);
  }
};
template<int Dim, class T>
struct CopyLocStorage
{
  inline
  static void copy(Loc<Dim> &loc, const T &a) {
    CopyLocStorageImpl<Dim, T, DomainTraits<T>::dimensions,
                       DomainTraits<T>::wildcard>::copy(loc, a);
  }
};
template<int Dim>
class Loc : public Domain<Dim, DomainTraits<Loc<Dim> > >
{
  typedef DomainTraits< Loc<Dim> > DT_t;
  typedef Domain<Dim, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  inline
  Loc() { }
  inline
  Loc(const Loc<Dim> &a)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    fillLocStorage(*this, a);
  }
  Loc(const Pooma::NoInit &a)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(a)
  { }
  template<class T1>
  inline
  explicit Loc(const T1 &a)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    CopyLocStorage<Dim, T1>::copy(*this, a);
  }
  template<class T1, class T2>
  inline
  Loc(const T1 &a, const T2 &b)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions))>::test();
    fillLocStorage(*this, a, b);
  }
  template<class T1, class T2, class T3>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions))>::test();
    fillLocStorage(*this, a, b, c);
  }
  template<class T1, class T2, class T3, class T4>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions))>::test();
    fillLocStorage(*this, a, b, c, d);
  }
  template<class T1, class T2, class T3, class T4, class T5>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions))>::test();
    fillLocStorage(*this, a, b, c, d, e);
  }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions + DomainTraits<T6>::dimensions))>::test();
    fillLocStorage(*this, a, b, c, d, e, f);
  }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6, class T7>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f, const T7 &g)
    : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
    PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions + DomainTraits<T6>::dimensions + DomainTraits<T7>::dimensions))>::test();
    fillLocStorage(*this, a, b, c, d, e, f, g);
  }
  inline
  ~Loc() { }
  template<class T>
  inline
  Loc<Dim> &operator=(const T &newdom) {
    CopyLocStorage<Dim, T>::copy(*this, newdom);
    return *this;
  }
  inline
  Loc<Dim> &operator=(const Loc<Dim> &newdom) {
    fillLocStorage(*this, newdom);
    return *this;
  }
  template<class Out>
  void print(Out &o) const;
protected:
private:
};
template<int Dim>
template<class Out>
void Loc<Dim>::print(Out &o) const
{
  const Domain_t &d = this->unwrap();
  o << "[";
  for (int i=0; i < Dim; ++i) {
    o << d[i].first();
    if (i < (Dim-1))
      o << ",";
  }
  o << "]";
}
template<>
class Loc<1> : public Domain<1, DomainTraits<Loc<1> > >
{
  typedef DomainTraits< Loc<1> > DT_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  inline
  Loc() { }
  inline
  Loc(const Loc<1> &a)
    : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
    setDomain(a);
  }
  Loc(const Pooma::NoInit &a)
    : Domain<1, DomainTraits<Loc<1> > >(a)
  { }
  template<class T1>
  inline
  explicit Loc(const T1 &a)
    : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
    setDomain(DomainTraits<T1>::getPointDomain(a, 0));
  }
  template<class T1, class T2>
  inline
  Loc(const T1 &a, const T2 &b)
    : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1 && DomainTraits<T2>::dimensions == 1 && DomainTraits<T1>::singleValued && DomainTraits<T2>::singleValued)>::test();
    ;
    setDomain(DomainTraits<T1>::getPointDomain(a, 0));
  }
  template<class T1, class T2, class T3>
  inline
  Loc(const T1 &a, const T2 &b, const T3 &c)
    : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1 && DomainTraits<T2>::dimensions == 1 && DomainTraits<T3>::dimensions == 1 && DomainTraits<T1>::singleValued && DomainTraits<T2>::singleValued && DomainTraits<T3>::singleValued)>::test();
    ;
    setDomain(DomainTraits<T1>::getPointDomain(a, 0));
  }
  template<class T>
  inline
  Loc<1> &operator=(const T &newdom) {
    setDomain(DomainTraits<T>::getPointDomain(newdom, 0));
    return *this;
  }
  inline
  Loc<1> &operator=(const Loc<1> &newdom) {
    setDomain(newdom);
    return *this;
  }
  const OneDomain_t &operator[](int d) const { return *this; }
  OneDomain_t &operator[](int d) { return *this; }
  template<class Out>
  void print(Out &o) const;
};
template<class Out>
void Loc<1>::print(Out &o) const
{
  const Domain_t &d = this->unwrap();
  o << "[";
  o << d[0].first();
  o << "]";
}
template<int Dim>
std::ostream& operator<<(std::ostream &o, const Loc<Dim> &loc)
{
  loc.print(o);
  return o;
}
#include <vector>
class Pool
{
public:
  Pool(size_t sz);
  Pool();
  ~Pool();
  inline void* alloc()
    {
      outstandingAllocs_m += 1;
      if ( head_m==0 )
 grow();
      Link *p = head_m;
      memcpy(&head_m, &p->next_m, sizeof(head_m));
      return p;
    }
  inline void free(void *b)
    {
      outstandingAllocs_m -= 1;
      Link *p = (Link*)b;
      p->next_m = head_m;
      memcpy(&p->next_m, &head_m, sizeof(head_m));
      head_m = p;
    }
private:
  struct Link { Link *next_m; };
  enum { page=4096-8 };
  enum { align = 8 };
  enum { alignMask = align-1 };
  static inline int blocksInPage(size_t sz)
    {
      return (page>sz)?(page/sz):1;
    }
  static inline size_t roundToAlign(size_t s)
    {
      if (s)
 s = (s & ~alignMask) + ((s&alignMask)?align:0);
      else
 s = align;
      return s;
    }
  void grow();
  Link *head_m;
  int outstandingAllocs_m;
  size_t bsize_m;
  size_t nblock_m;
  std::vector<char*> chunks_m;
};
template<class T>
class Pooled
{
public:
  inline void* operator new(size_t) { return pool_s.alloc(); }
  inline void operator delete(void *p, size_t) { if (p) pool_s.free(p); }
  inline void* operator new(size_t, void* ptr) { return ptr; }
  inline void operator delete(void *, void *) { }
private:
  static Pool pool_s;
};
template<class T>
Pool Pooled<T>::pool_s(sizeof(T));
template<class Dom, class OrigDom = Dom>
class Node : public Pooled<Node<Dom, OrigDom> >
{
public:
  typedef Dom Domain_t;
  typedef OrigDom AllocatedDomain_t;
  typedef int Context_t;
  typedef int ID_t;
  typedef Node<Dom,OrigDom> This_t;
  Node()
    : local_m(-1), global_m(0), context_m(0), affinity_m(-1)
  {
  }
  Node(const Domain_t &owned, const AllocatedDomain_t &allocated,
       Context_t c, ID_t gid, ID_t lid = (-1))
    : domain_m(owned), allocated_m(allocated),
      local_m(lid), global_m(gid),
      context_m(c), affinity_m(-1)
  {
    ;
    ;
    ;
  }
  Node(const Domain_t &d, Context_t c, ID_t gid, ID_t lid = (-1))
    : domain_m(d), allocated_m(d),
      local_m(lid), global_m(gid),
      context_m(c), affinity_m(-1)
  {
    ;
    ;
  }
  Node(int affinity, const Domain_t &owned, const AllocatedDomain_t &allocated,
       Context_t c, ID_t gid, ID_t lid = (-1))
    : domain_m(owned), allocated_m(allocated),
      local_m(lid), global_m(gid), context_m(c),
      affinity_m(affinity)
  {
    ;
    ;
    ;
  }
  Node(int affinity, const Domain_t &d,
       Context_t c, ID_t gid, ID_t lid = (-1))
    : domain_m(d), allocated_m(d),
      local_m(lid), global_m(gid),
      context_m(c), affinity_m(affinity)
  {
    ;
    ;
  }
  Node(const This_t &n)
    : domain_m(n.domain_m), allocated_m(n.allocated_m),
      local_m(n.local_m), global_m(n.global_m),
      context_m(n.context_m), affinity_m(n.affinity_m)
  {
  }
  template<class ODom, class OAlloc>
  Node(const Node<ODom,OAlloc> &n)
    : domain_m(n.domain()), allocated_m(n.allocated()),
      local_m(n.localID()), global_m(n.globalID()),
      context_m(n.context()), affinity_m(n.affinity())
  {
  }
  void initialize(const Domain_t &owned, const AllocatedDomain_t &allocated,
                  Context_t c, ID_t gid, ID_t lid = (-1))
  {
    ;
    ;
    domain_m = owned;
    allocated_m = allocated;
    context_m = c;
    local_m = lid;
    global_m = gid;
  }
  void initialize(const Domain_t &d, Context_t c, ID_t gid, ID_t lid = (-1))
  {
    ;
    ;
    domain_m = d;
    allocated_m = d;
    context_m = c;
    local_m = lid;
    global_m = gid;
  }
  ~Node()
  {
  }
  inline const Domain_t &domain() const { return domain_m; }
  inline const AllocatedDomain_t &allocated() const { return allocated_m; }
  Context_t context() const { return context_m; }
  ID_t localID() const { return local_m; }
  ID_t globalID() const { return global_m; }
  bool isLocal() const { return (local_m >= 0); }
  int affinity() const { return affinity_m; }
  int& affinity() { return affinity_m; }
  int& context() { return context_m; }
  int& localID() { return local_m; }
  void setDomain(const Domain_t &dom) { domain_m = dom; }
  Domain_t &domain() { return domain_m; }
  void setAllocated(const AllocatedDomain_t &dom) { allocated_m = dom; }
  AllocatedDomain_t &allocated() { return allocated_m; }
  This_t &operator=(const This_t &n)
  {
    domain_m = n.domain();
    allocated_m = n.allocated();
    context_m = n.context();
    local_m = n.localID();
    global_m = n.globalID();
    affinity_m = n.affinity();
    return *this;
  }
  template<class ODom, class OAlloc>
  This_t &operator=(const Node<ODom,OAlloc> &n)
  {
    domain_m = n.domain();
    allocated_m = n.allocated();
    context_m = n.context();
    local_m = n.localID();
    global_m = n.globalID();
    affinity_m = n.affinity();
    return *this;
  }
  This_t &operator=(const Domain_t &d)
  {
    domain_m = d;
    return *this;
  }
  template<class Out>
  void print(Out &o) const
  {
    o << "{" << domain();
    o << ": allocated=" << allocated();
    o << ", con=" << context();
    o << ", aff=" << affinity();
    o << ", gid=" << globalID();
    o << ", lid=" << localID();
    o << "}";
  }
private:
  enum { dim = DomainTraits<Dom>::dimensions };
  enum { origDim = DomainTraits<OrigDom>::dimensions };
  Domain_t domain_m;
  AllocatedDomain_t allocated_m;
  ID_t local_m;
  ID_t global_m;
  Context_t context_m;
  int affinity_m;
};
template <class D, class A>
std::ostream &operator<<(std::ostream &o, const Node<D,A> &node)
{
  node.print(o);
  return o;
}
template<int Dim, class Dom, class OrigDom>
inline bool contains(const Interval<Dim> &i, const Node<Dom, OrigDom> &n)
{
  return contains(i, n.domain());
}
template<class Dom, class OrigDom>
struct DomainTraits<Node<Dom, OrigDom> >
{
  enum { singleValued = 0 };
};
template<class Domain, class Sub>
struct TemporaryNewDomain1;
template<class Domain, class OwnedDomain, class AllocatedDomain>
struct TemporaryNewDomain1<Domain, Node<OwnedDomain, AllocatedDomain> >
{
  typedef Node<OwnedDomain,AllocatedDomain> SliceType_t;
  static inline
  const SliceType_t &combineSlice(const Domain &,
    const Node<OwnedDomain,AllocatedDomain> &n)
  {
    return n;
  }
};
#include <utility>
class GlobalIDDataBase
{
public:
  typedef int LayoutID_t;
  typedef int GlobalID_t;
  typedef int NodeKey_t;
  typedef std::map<LayoutID_t, GlobalID_t> Shared_t;
  GlobalIDDataBase() { }
  inline static
  NodeKey_t nullNodeKey()
  {
    return -1;
  }
  NodeKey_t push(LayoutID_t layoutID, int context, GlobalID_t globalID);
  NodeKey_t push(LayoutID_t layoutID,
   int context,
   GlobalID_t globalID,
   NodeKey_t parentNode);
  void shared(LayoutID_t idNew, LayoutID_t idOld);
  GlobalID_t globalID(LayoutID_t layoutID, NodeKey_t key) const;
  int context(LayoutID_t layoutID, NodeKey_t key) const;
  int context(NodeKey_t key) const;
  bool contextParticipates(int context, NodeKey_t key) const;
  template<class OSTR>
  inline void print(OSTR &ostr)
  {
    typedef std::vector<Pack> Store_t;
    typedef typename Store_t::const_iterator Iterator_t;
    Iterator_t p = data_m.begin();
    for (; p != data_m.end(); ++p)
    {
      ostr << "(" << (*p).layoutID() << ","
    << (*p).globalID() << ","
    << (*p).context() << ","
    << (*p).parent() << ")";
    }
  }
private:
  struct Pack
  {
    Pack()
      : layoutID_m(0), context_m(0), globalID_m(0), parent_m(0)
    { }
    inline
    Pack(LayoutID_t layoutID, int context, GlobalID_t globalID,
  NodeKey_t parent)
      : layoutID_m(layoutID),
 context_m(context),
 globalID_m(globalID),
 parent_m(parent)
    { }
    inline LayoutID_t layoutID() const { return layoutID_m; }
    inline int context() const { return context_m; }
    inline GlobalID_t globalID() const { return globalID_m; }
    inline NodeKey_t parent() const { return parent_m; }
    LayoutID_t layoutID_m;
    int context_m;
    GlobalID_t globalID_m;
    NodeKey_t parent_m;
  };
  std::vector<Pack> data_m;
  Shared_t shared_m;
};
class Unique
{
public:
  typedef long Value_t;
  Unique()
    {
    }
  ~Unique()
    {
    }
  static inline Value_t get()
    {
      mutex_s.lock();
      Value_t retval = next_s++;
      mutex_s.unlock();
      return retval;
    }
  static inline Value_t lockedGet()
    {
      return get();
    }
private:
  static Value_t next_s;
  static Pooma::Mutex_t mutex_s;
};
struct TouchesConstructNodePtr {
  TouchesConstructNodePtr(){};
  ~TouchesConstructNodePtr(){};
};
struct TouchesConstructNodeObj {
  TouchesConstructNodeObj(){};
  ~TouchesConstructNodeObj(){};
};
template<class Domain>
inline Node<Domain> *
touchesConstruct(const Domain &owned,
   int affinity, int c, int gid, int lid,
   const TouchesConstructNodePtr &)
{
  return new Node<Domain>(affinity, owned, c, gid, lid);
}
template<class Domain, class AllocatedDomain>
inline Node<Domain,AllocatedDomain> *
touchesConstruct(const Domain &owned, const AllocatedDomain &allocated,
   int affinity, int c, int gid, int lid,
   const TouchesConstructNodePtr &)
{
  return new Node<Domain,AllocatedDomain>
             (affinity, owned, allocated, c, gid, lid);
}
template<class Domain>
inline Node<Domain>
touchesConstruct(const Domain &owned,
   int affinity, int c, int gid, int lid,
    const TouchesConstructNodeObj &)
{
  return Node<Domain>(affinity, owned, c, gid, lid);
}
template<class Domain, class AllocatedDomain>
inline Node<Domain,AllocatedDomain>
touchesConstruct(const Domain &owned, const AllocatedDomain &allocated,
   int affinity, int c, int gid, int lid,
   const TouchesConstructNodeObj &)
{
  return Node<Domain,AllocatedDomain>(affinity, owned, allocated, c, gid, lid);
}
template<int Dim> class INode;
template<int Dim>
struct TouchesConstructINode
{
  typedef GlobalIDDataBase::NodeKey_t NodeKey_t;
  typedef Unique::Value_t LayoutID_t;
  TouchesConstructINode(LayoutID_t layoutID,
   NodeKey_t parent,
   GlobalIDDataBase *globalIDDataBase)
    : layoutID_m(layoutID), parent_m(parent),
      globalIDDataBase_m(globalIDDataBase)
  { }
  inline LayoutID_t layoutID() const { return layoutID_m; }
  inline NodeKey_t parent() const { return parent_m; }
  inline GlobalIDDataBase *globalIDDataBase() const
  {
    return globalIDDataBase_m;
  }
  LayoutID_t layoutID_m;
  NodeKey_t parent_m;
  GlobalIDDataBase *globalIDDataBase_m;
};
template <int Dim>
class INode
{
public:
  typedef INode<Dim> This_t;
  typedef Interval<Dim> Domain_t;
  typedef GlobalIDDataBase::LayoutID_t LayoutID_t;
  typedef GlobalIDDataBase::GlobalID_t GlobalID_t;
  typedef GlobalIDDataBase::NodeKey_t NodeKey_t;
  enum { dimensions = Dim };
  inline INode() : domain_m(Pooma::NoInit()) { }
  inline INode(const INode<Dim> &model)
    : domain_m(model.domain_m),
      globalIDDataBase_m(model.globalIDDataBase_m),
      key_m(model.key_m)
  { }
  template<int D2, class Dom>
  inline INode(const INode<D2> &model, const Dom &dom)
    : domain_m(dom),
      globalIDDataBase_m(model.globalIDDataBase()),
      key_m(model.key())
  { }
  inline
  INode(const Interval<Dim> &dom, LayoutID_t layoutID, int context,
 GlobalID_t globalID,
 GlobalIDDataBase *globalIDDataBase, NodeKey_t parent = -1)
    : domain_m(dom),
      globalIDDataBase_m(globalIDDataBase)
  {
    key_m = globalIDDataBase_m->push(layoutID, context, globalID, parent);
  }
  template<class Alloc>
  inline
  INode(const Node<Interval<Dim>, Alloc> &node, LayoutID_t layoutID,
 GlobalIDDataBase *globalIDDataBase)
    : domain_m(node.domain()),
      globalIDDataBase_m(globalIDDataBase)
  {
    key_m = globalIDDataBase_m->push(layoutID, node.context(),
         node.globalID());
  }
  inline
  INode(const Interval<Dim> &dom, int context, GlobalID_t globalID,
 const TouchesConstructINode<Dim> &tcin)
    : domain_m(dom),
      globalIDDataBase_m(tcin.globalIDDataBase())
  {
    key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
         tcin.parent());
  }
  inline
  INode(const INode<Dim> &inode, int context, GlobalID_t globalID,
 const TouchesConstructINode<Dim> &tcin)
    : domain_m(inode.domain()),
      globalIDDataBase_m(tcin.globalIDDataBase())
  {
    key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
         tcin.parent());
  }
  template<class Alloc>
  inline
  INode(const Node<Interval<Dim>, Alloc> &node, int context,
 GlobalID_t globalID,
 const TouchesConstructINode<Dim> &tcin)
    : domain_m(node.domain()),
      globalIDDataBase_m(tcin.globalIDDataBase())
  {
    key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
         tcin.parent());
  }
  inline INode(const Range<Dim> &range, int context, int globalID,
        const TouchesConstructINode<Dim> &tcin)
    : globalIDDataBase_m(tcin.globalIDDataBase())
  {
    key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
         tcin.parent());
    int i;
    for (i = 0; i < Dim; ++i)
    {
      domain_m[i] = Interval<1>(range[i].first(), range[i].last());
    }
  }
  inline INode<Dim> &operator=(const INode<Dim> &rhs)
  {
    if (&rhs != this)
    {
      domain_m = rhs.domain();
      globalIDDataBase_m = rhs.globalIDDataBase();
      key_m = rhs.key();
    }
    return *this;
  }
  inline ~INode() { }
  inline const Domain_t &domain() const { return domain_m; }
  inline
  GlobalID_t globalID(LayoutID_t id) const
  {
    ;
    return globalIDDataBase_m->globalID(id, key_m);
  }
  inline int context() const
  {
    ;
    return globalIDDataBase_m->context(key_m);
  }
  inline int context(LayoutID_t id) const
  {
    ;
    return globalIDDataBase_m->context(id, key_m);
  }
  inline bool contextParticipates(int context) const
  {
    ;
    return globalIDDataBase_m->contextParticipates(context, key_m);
  }
  inline
  GlobalIDDataBase *globalIDDataBase() const { return globalIDDataBase_m; }
  inline NodeKey_t key() const { return key_m; }
  inline
  TouchesConstructINode<Dim> touchesConstructINode(LayoutID_t layoutID)
  {
    return TouchesConstructINode<Dim>(layoutID, key_m, globalIDDataBase_m);
  }
  template<int Dim2>
  inline static
  TouchesConstructINode<Dim> touchesConstructINode(LayoutID_t layoutID,
         const INode<Dim2> &inode)
  {
    return TouchesConstructINode<Dim>(layoutID, inode.key(),
          inode.globalIDDataBase());
  }
  template<class Out>
  void print(Out &o) const
  {
    o << "{" << domain();
    o << ": key=" << key();
    o << "}";
  }
private:
  Domain_t domain_m;
  GlobalIDDataBase *globalIDDataBase_m;
  NodeKey_t key_m;
};
template<int Dim>
inline INode<Dim> operator+(const INode<Dim> &inode, const Loc<Dim> &loc)
{
  return INode<Dim>(inode, inode.domain() + loc);
}
template <int Dim>
std::ostream &operator<<(std::ostream &o, const INode<Dim> &inode)
{
  inode.print(o);
  return o;
}
template<int Dim>
inline bool contains(const Interval<Dim> &i, const INode<Dim> &n)
{
  return contains(i, n.domain());
}
template<int Dim>
struct DomainTraits<INode<Dim> >
{
  enum { singleValued = 0 };
};
template<class Domain, class Sub>
struct TemporaryNewDomain1;
template<class Domain, int N>
struct TemporaryNewDomain1<Domain, INode<N> >
{
  typedef INode<N> SliceType_t;
  static inline
  const SliceType_t &combineSlice(const Domain &, const INode<N> &i)
  {
    return i;
  }
};
template<class Domain, int Dim>
inline INode<Dim>
touchesConstruct(const Domain &d,
   int, int context, int gid, int,
   const TouchesConstructINode<Dim> &tcin)
{
  return INode<Dim>(d, context, gid, tcin);
}
template<class Domain, class AllocatedDomain, int Dim>
inline INode<Dim>
touchesConstruct(const Domain &d, const AllocatedDomain &,
   int, int context, int gid, int,
   const TouchesConstructINode<Dim> & tcin)
{
  return INode<Dim>(d, context, gid, tcin);
}
template <int Dim>
class GuardLayers
{
public:
  explicit GuardLayers(int gcs = 0)
  {
    ;
    for (int i = 0; i < Dim; ++i)
      {
        lower_m[i] = gcs;
        upper_m[i] = gcs;
      }
  }
  GuardLayers(int lower[Dim], int upper[Dim])
  {
    for (int i = 0; i < Dim; ++i)
      {
        ;
        lower_m[i] = lower[i];
        upper_m[i] = upper[i];
      }
  }
  GuardLayers(const Loc<Dim> &lower, const Loc<Dim> &upper)
  {
    for (int i = 0; i < Dim; ++i)
      {
        ;
        lower_m[i] = lower[i].first();
        upper_m[i] = upper[i].first();
      }
  }
  void initialize(const Loc<Dim> &lower, const Loc<Dim> &upper)
  {
    for (int i = 0; i < Dim; ++i)
      {
        ;
        lower_m[i] = lower[i].first();
        upper_m[i] = upper[i].first();
      }
  }
  void initialize(const GuardLayers<Dim> &gl)
  {
    *this = gl;
  }
  int lower(int i) const
  {
    return lower_m[i];
  }
  int upper(int i) const
  {
    return upper_m[i];
  }
  int &lower(int i)
  {
    return lower_m[i];
  }
  int &upper(int i)
  {
    return upper_m[i];
  }
  bool operator==(const GuardLayers<Dim> &gcs) const
  {
    bool result = true;
    for (int d = 0; d < Dim; ++d)
      {
        result = result && lower_m[d] == gcs.lower_m[d];
        result = result && upper_m[d] == gcs.upper_m[d];
      }
    return result;
  }
  bool operator==(int gcw) const
  {
    bool result = true;
    for (int d = 0; d < Dim; ++d)
      {
        result = result && lower_m[d] == gcw;
        result = result && upper_m[d] == gcw;
      }
    return result;
  }
  bool operator!=(const GuardLayers<Dim> &gcs) const
  {
    return !operator==(gcs);
  }
  bool operator!=(int gcw) const
  {
    return !operator==(gcw);
  }
  GuardLayers<Dim> operator-(const GuardLayers<Dim> &gcs)
  {
    GuardLayers<Dim> result;
    for (int d = 0; d < Dim; ++d)
      {
        result.lower(d) = lower_m[d] - gcs.lower_m[d];
        ;
        result.upper(d) = upper_m[d] - gcs.upper_m[d];
        ;
      }
    return result;
  }
  GuardLayers<Dim> operator-(int dw)
  {
    GuardLayers<Dim> result;
    for (int d = 0; d < Dim; ++d)
      {
        result.lower(d) = lower_m[d] - dw;
        ;
        result.upper(d) = upper_m[d] - dw;
        ;
      }
    return result;
  }
  inline static void
  addGuardLayers(Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
  {
    for (int d = 0; d < Dim; ++d)
      {
        int a = dom[d].first() - gcs.lower(d);
        int b = dom[d].last() + gcs.upper(d);
        dom[d] = Interval<1>(a,b);
      }
  }
  Interval<Dim> addGuardLayersToDomain(const Interval<Dim> &d) const
  {
    Interval<Dim> dom(d);
    addGuardLayers(dom, *this);
    return dom;
  }
  template <class Ostream>
  void print(Ostream &ostr) const
  {
    ostr << "GuardLayers<" << Dim << "> [";
    for (int d = 0; d < Dim; ++d)
      {
        ostr << "l: " << lower_m[d] << ", u: " << upper_m[d];
        if (d != Dim - 1)
          ostr << "; ";
      }
    ostr << "]";
  }
private:
  int lower_m[Dim];
  int upper_m[Dim];
};
template<int Dim>
inline Interval<Dim>
grow(const Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - gcs.lower(d);
      int b = dom[d].last() + gcs.upper(d);
      ret[d] = Interval<1>(a,b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrink(const Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + gcs.lower(d);
      int b = dom[d].last() - gcs.upper(d);
      ret[d] = Interval<1>(a,b);
    }
  return ret;
}
template<int Dim>
std::ostream &operator<<(std::ostream &ostr,
  const GuardLayers<Dim> &gl)
{
  gl.print(ostr);
  return ostr;
}
template <int Dim> class Loc;
template <> class Loc<1>;
template <int Dim> class Interval;
template <> class Interval<1>;
template <int Dim> class Range;
template <> class Range<1>;
template<int Dim>
struct DomainTraits< Range<Dim> >
  : public DomainTraitsDomain<Range<Dim>, int, Dim>
{
  typedef DomainTraitsDomain<Range<Dim>, int, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef Range<1> OneDomain_t;
  typedef Range<1> PointDomain_t;
  typedef Interval<Dim> BlockDomain_t;
  typedef Loc<Dim> AskDomain_t;
  typedef Range<Dim> AddResult_t;
  typedef Range<Dim> MultResult_t;
  typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = Dim };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  enum { wildcard = false };
  static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
  static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void initializeStorage(Storage_t &dom) {
    Dom1Initialize<Dim-1>::template apply<DomainTraits<Range<Dim> > >(dom);
  }
};
template<>
struct DomainTraits< Range<1> >
  : public DomainTraitsDomain<Range<1>, int, 1>
{
  typedef Range<1> OneDomain_t;
  typedef Range<1> PointDomain_t;
  typedef Interval<1> BlockDomain_t;
  typedef Loc<1> AskDomain_t;
  typedef Range<1> AddResult_t;
  typedef Range<1> MultResult_t;
  typedef Element_t Storage_t[3];
  enum { dimensions = 1,
         sliceDimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  enum { wildcard = false };
  static Element_t first(const Storage_t &d) { return d[0]; }
  static Element_t last(const Storage_t &d) { return d[0] + (d[1]-1)*d[2]; }
  static Element_t stride(const Storage_t &d) { return d[2]; }
  static Element_t length(const Storage_t &d) { return d[1]; }
  static Element_t min(const Storage_t &d) {
    return (d[2] > 0 ? d[0] : d[0] + (d[1]-1)*d[2]);
  }
  static Element_t max(const Storage_t &d) {
    return (d[2] < 0 ? d[0] : d[0] + (d[1]-1)*d[2]);
  }
  static bool empty(const Storage_t &d) { return (d[1] < 1); }
  static int loop(const Storage_t &) { return 0; }
  static Element_t elem(const Storage_t &d, int n) { return d[0] + n*d[2]; }
  static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
  static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void initializeStorage(Storage_t &dom) {
    dom[0] = 0;
    dom[1] = 0;
    dom[2] = 1;
  }
  template<class T>
  static void setDomain(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    dom[0] = DomainTraits<T>::getFirst(newdom);
    dom[1] = DomainTraits<T>::getLength(newdom);
    dom[2] = DomainTraits<T>::getStride(newdom);
  }
  template<class T1, class T2>
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
    Element_t strideval = (endval < begval ? -1 : 1);
    dom[0] = begval;
    dom[1] = (endval - begval)/strideval + 1;
    dom[2] = strideval;
  }
  template<class T1, class T2, class T3>
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval,
   const T3 &strideval) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T3>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T3>::singleValued)>::test();
    dom[0] = begval;
    dom[1] = (endval - begval)/strideval + 1;
    dom[2] = strideval;
  }
  static void setLoop(Storage_t &, int) { }
  template<class UT, class T>
  static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
    dom[0] = newdom.first(u);
    dom[1] = newdom.length(u);
    dom[2] = newdom.stride(u);
  }
  template<class T>
  static bool isLessThan(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    return (dom[1] < DomainTraits<T>::getLength(newdom) ||
     (dom[1] == DomainTraits<T>::getLength(newdom) &&
      (dom[0] < DomainTraits<T>::getFirst(newdom) ||
       (dom[0] == DomainTraits<T>::getFirst(newdom) &&
        dom[2] < DomainTraits<T>::getStride(newdom)))));
  }
  template<class T>
  static bool isEqualTo(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    return ((dom[1] == 0 && DomainTraits<T>::getLength(newdom) == 0) ||
     (dom[0] == DomainTraits<T>::getFirst(newdom) &&
      dom[1] == DomainTraits<T>::getLength(newdom) &&
      dom[2] == DomainTraits<T>::getStride(newdom)));
  }
  template<class T>
  static void addAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] += DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void subtractAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] -= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void multiplyAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] *= DomainTraits<T>::getFirst(newdom);
    dom[2] *= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void divideAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom[0] /= DomainTraits<T>::getFirst(newdom);
    dom[2] /= DomainTraits<T>::getFirst(newdom);
  }
};
template<int Dim1, int Dim2>
struct DomainChangeDim<Range<Dim1>, Dim2>
{
  typedef Range<Dim1> OldType_t;
  typedef Range<Dim2> NewType_t;
  enum { oldDim = Dim1,
  newDim = Dim2 };
};
template <int Dim> class Range;
template<int Dim>
inline
void fillRangeScalar(Range<Dim> &r, const int &a);
template<int Dim>
class Range : public Domain<Dim, DomainTraits<Range<Dim> > >
{
  typedef DomainTraits< Range<Dim> > DT_t;
  typedef Domain<Dim, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Range() { }
  Range(const Range<Dim> &a)
    : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
    NewDomain1<Range<Dim> >::fill(*this, a);
  }
  Range(const Pooma::NoInit &a)
    : Domain<Dim, DomainTraits<Range<Dim> > >(a)
  { }
  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);
  }
  ~Range() { }
  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:
};
template<>
class Range<1> : public Domain<1, DomainTraits<Range<1> > >
{
  typedef DomainTraits< Range<1> > DT_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Range() { }
  Range(const Range<1> &a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    NewDomain1<Range<1> >::fill(*this, a);
  }
  Range(const Pooma::NoInit &a)
    : Domain<1, DomainTraits<Range<1> > >(a)
  { }
  template<class T1>
  explicit Range(const T1 &a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    NewDomain1<T1>::fill(*this, a);
  }
  Range(char a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    ;
    DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
  }
  Range(unsigned char a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    ;
    DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
  }
  Range(short a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    ;
    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()) {
    ;
    DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
  }
  Range(int a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    ;
    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()) {
    ;
    DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
  }
  Range(long a)
    : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
    ;
    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()) {
    ;
    DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
  }
  template<class T1, class T2>
  Range(const T1 &m, const T2 &n);
  template<class T1, class T2, class T3>
  Range(const T1 &m, const T2 &n, const T3 &s);
  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);
  }
  const OneDomain_t &operator[](int d) const { return *this; }
  OneDomain_t &operator[](int d) { return *this; }
};
template <class T1, class T2>
inline
Range<1>::Range(const T1 &m, const T2 &n)
  : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
  DomainTraits<Range<1> >::setDomain(domain_m, m, n);
}
template <class T1, class T2, class T3>
inline
Range<1>::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);
}
template<int Dim>
inline
void fillRangeScalar(Range<Dim> &r, const int &a)
{
  for (int i=0; i < Dim; ++i)
    r[i]=Range<1>(a);
}
class ObserverEvent
{
public:
  typedef Unique::Value_t ID_t;
  ObserverEvent(int event)
    : event_m(event), ID_m(Unique::get())
    {
    }
  ObserverEvent(const ObserverEvent &oe)
    : event_m(oe.event_m), ID_m(oe.ID_m)
    {
    }
  ObserverEvent &operator=(const ObserverEvent &oe)
    {
      event_m = oe.event();
      ID_m = oe.ID();
      return *this;
    }
  virtual ~ObserverEvent()
    {
    }
  inline int event() const
    {
      return event_m;
    }
  inline ID_t ID() const
    {
      return ID_m;
    }
  static inline ID_t nullID()
    {
      return (-1);
    }
private:
  int event_m;
  ID_t ID_m;
};
template<class Obj>
inline bool checkDynamicID(Obj &, ObserverEvent::ID_t)
{
  return true;
}
template<class T>
class Observer
{
public:
  Observer()
    {
    }
  virtual ~Observer()
    {
    }
  virtual void notify(T &observed, const ObserverEvent &event) = 0;
  inline void notify(T &observed, int event)
    {
      notify(observed, ObserverEvent(event));
    }
};
template<class T>
class SingleObserver
{
public:
  SingleObserver() { }
  virtual ~SingleObserver() { }
  virtual void notify(const T &observed, const ObserverEvent &event) = 0;
  inline void notify(const T &observed, int event)
    {
      notify(observed, ObserverEvent(event));
    }
};
template<class T>
class Observable
{
public:
  enum { deleteEvent = 0 };
  Observable(T &o) : observed_m(o), count_m(0)
    {
    }
  ~Observable()
    {
      notify(deleteEvent);
    }
  int observers() const
    {
      return count_m;
    }
  void attach(Observer<T> *o)
    {
      mutex_m.lock();
      observers_m.push_back(o);
      count_m += 1;
      mutex_m.unlock();
    }
  void attach(Observer<T> &o)
    {
      attach(&o);
    }
  void detach(Observer<T> *o)
    {
      mutex_m.lock();
      for (int i=0; i < count_m; ++i) {
 if (observers_m[i] == o) {
   count_m -= 1;
   observers_m.erase(observers_m.begin() + i);
   break;
 }
      }
      mutex_m.unlock();
    }
  void detach(Observer<T> &o)
    {
      detach(&o);
    }
  inline void notify(int event)
    {
      for (int i=0; i < count_m; ++i)
 observers_m[i]->notify(observed_m, event);
    }
  inline void notify(const ObserverEvent &event)
    {
      for (int i=0; i < count_m; ++i)
 observers_m[i]->notify(observed_m, event);
    }
private:
  T &observed_m;
  std::vector<Observer<T> *> observers_m;
  int count_m;
  Pooma::Mutex_t mutex_m;
  Observable();
  Observable(const Observable<T> &);
  Observable<T> &operator=(const Observable<T> &);
};
template<class T>
class SingleObservable
{
public:
  enum { deleteEvent = 0 };
  SingleObservable() : observer_m(0)
    {
    }
  ~SingleObservable()
    {
      notify(T(),0);
    }
  void attach(SingleObserver<T> *o)
    {
      ;
      observer_m = o;
    }
  void attach(SingleObserver<T> &o)
    {
      attach(&o);
    }
  void detach()
    {
      observer_m = 0;
    }
  inline void notify(const T& value, int event)
    {
      if (observer_m != 0)
 observer_m->notify(value, event);
    }
  inline void notify(const T& value, const ObserverEvent &event)
    {
      if (observer_m != 0)
 observer_m->notify(value, event);
    }
private:
  SingleObserver<T> *observer_m;
  SingleObservable(const SingleObservable<T> &);
  SingleObservable<T> &operator=(const SingleObservable<T> &);
};
template <class T>
struct ElementProperties
{
  typedef T This_t;
  enum { hasTrivialDefaultConstructor = false };
  enum { hasTrivialDestructor = false };
  enum { concrete = false };
  enum { basicType = false };
  static void construct(This_t * addr)
  {
    new (addr) This_t();
  }
  static void construct(This_t * addr, const This_t & model)
  {
    new (addr) This_t(model);
  }
  static This_t * clone(const This_t &model)
  {
    return new This_t(model);
  }
  static void destruct(This_t * addr)
  {
    addr->~This_t();
  }
};
template <class T>
struct TrivialElementPropertiesBase
{
  typedef T This_t;
  enum { hasTrivialDefaultConstructor = true };
  enum { hasTrivialDestructor = true };
  enum { concrete = true };
  static void construct(This_t * addr, const This_t & model)
  {
    new (addr) This_t(model);
  }
  static This_t * clone(const This_t &model)
  {
    return new This_t(model);
  }
  static void construct(This_t *addr)
  {
    new (addr) This_t();
  }
  static void destruct(This_t *)
  {
    if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("TrivialElementProperties<T>::destruct(addr) not allowed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/ElementProperties.h", 213);
  }
};
template <class T>
struct TrivialElementProperties : public TrivialElementPropertiesBase<T>
{
  enum { basicType = false };
};
template <class T>
struct BasicTypeProperties : public TrivialElementPropertiesBase<T>
{
  enum { basicType = true };
};
template <class T>
struct MakeOwnCopyProperties
{
  typedef T This_t;
  enum { hasTrivialDefaultConstructor = false };
  enum { hasTrivialDestructor = false };
  enum { concrete = false };
  enum { basicType = false };
  static void construct(This_t * addr)
  {
    new (addr) This_t;
    addr->makeOwnCopy();
  }
  static void construct(This_t * addr, const This_t & model)
  {
    new (addr) This_t(model);
    addr->makeOwnCopy();
  }
  static This_t * clone(const This_t &model)
  {
    This_t * temp = new This_t(model);
    temp->makeOwnCopy();
    return temp;
  }
  static void destruct(This_t * addr)
  {
    addr->~This_t();
  }
};
template <>
struct ElementProperties<bool> : public BasicTypeProperties<bool>
{ };
template <>
struct ElementProperties<char> : public BasicTypeProperties<char>
{ };
template <>
struct ElementProperties<unsigned char>
  : public BasicTypeProperties<unsigned char>
{ };
template <>
struct ElementProperties<short> : public BasicTypeProperties<short>
{ };
template <>
struct ElementProperties<unsigned short>
  : public BasicTypeProperties<unsigned short>
{ };
template <>
struct ElementProperties<int> : public BasicTypeProperties<int>
{ };
template <>
struct ElementProperties<unsigned int>
  : public BasicTypeProperties<unsigned int>
{ };
template <>
struct ElementProperties<long> : public BasicTypeProperties<long>
{ };
template <>
struct ElementProperties<long long> : public BasicTypeProperties<long long>
{ };
template <>
struct ElementProperties<unsigned long>
  : public BasicTypeProperties<unsigned long>
{ };
template <>
struct ElementProperties<float> : public BasicTypeProperties<float>
{ };
template <>
struct ElementProperties<double> : public BasicTypeProperties<double>
{ };
template <class FloatType>
struct ElementProperties<std::complex<FloatType> >
  : public TrivialElementProperties<std::complex<FloatType> >
{ };
class RefCounted
{
public:
  RefCounted()
    : count_m(0)
    { }
  RefCounted(const RefCounted &)
    : count_m(0)
    { }
  ~RefCounted() { }
  bool isShared() const;
  void addReference();
  void removeReference();
  bool removeRefAndCheckGarbage();
  void lock() const
  {
    mutex_m.lock();
  }
  void unlock() const
  {
    mutex_m.unlock();
  }
  int count() const;
  int countUnlocked() const;
private:
  RefCounted & operator=(const RefCounted &);
  int count_m;
  mutable Pooma::Mutex_t mutex_m;
};
inline bool
RefCounted::isShared() const
{
  mutex_m.lock();
  bool test = count_m > 1;
  mutex_m.unlock();
  return test;
}
inline void
RefCounted::addReference()
{
  mutex_m.lock();
  ++count_m;
  mutex_m.unlock();
}
inline void
RefCounted::removeReference()
{
  mutex_m.lock();
  --count_m;
  ;
  mutex_m.unlock();
}
inline bool
RefCounted::removeRefAndCheckGarbage()
{
  mutex_m.lock();
  ;
  bool test = --count_m == 0;
  mutex_m.unlock();
  return test;
}
inline int
RefCounted::count() const
{
  mutex_m.lock();
  int count = count_m;
  mutex_m.unlock();
  return count;
}
inline int
RefCounted::countUnlocked() const
{
  return count_m;
}
template <class T>
class Shared : public RefCounted
{
public:
  Shared(const T &d) : data_m(d) {};
  Shared(const Shared<T> & model)
    : data_m(model.data_m)
  { }
  Shared<T> & operator=(const Shared<T> &model)
  {
    if (&model == this) return *this;
    data_m = model.data_m;
    return *this;
  }
  Shared<T> & operator=(const T & d)
  {
    data_m = d;
    return *this;
  }
  inline
  T &data() { return data_m; }
  inline
  const T &data() const { return data_m; }
  bool operator==(const Shared<T> &rhs) const
    { return data_m == rhs.data_m; }
  bool operator!=(const Shared<T> &rhs) const
    { return data_m != rhs.data_m; }
protected:
  T data_m;
};
template <class T>
class RefCountedPtr
{
public:
  typedef RefCountedPtr<T> This_t;
  typedef T Pointee_t;
  RefCountedPtr() : ptr_m(0) { }
  RefCountedPtr(T * const pT)
    : ptr_m(pT)
    { if (isValid()) ptr_m->addReference(); }
  RefCountedPtr(const This_t &model)
    : ptr_m(model.ptr_m)
    { if (isValid()) ptr_m->addReference(); }
  ~RefCountedPtr();
  RefCountedPtr & operator=(const RefCountedPtr &);
  RefCountedPtr & operator=(T *);
  inline T * operator->() const { return ptr_m; }
  inline T & operator*() const { return *ptr_m; }
  bool operator==(const This_t& a) const
  { return ptr_m == a.ptr_m; }
  bool operator!=(const This_t& a) const
  { return ptr_m != a.ptr_m; }
  void invalidate();
  inline bool isValid() const { return ptr_m != 0; }
  inline bool isShared() const { return ptr_m->isShared(); }
  inline int count() const { return ptr_m->count(); }
  RefCountedPtr<T> & makeOwnCopy();
  inline T * rawPointer() { return ptr_m; }
  inline const T * rawPointer() const { return ptr_m; }
private:
  template <class T2, bool val, class Controller>
  friend class RefCountedBlockPtr;
  T * ptr_m;
};
template <class T>
inline void RefCountedPtr<T>::invalidate()
{
  if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
    delete ptr_m;
  ptr_m = 0;
}
template <class T>
inline RefCountedPtr<T>::~RefCountedPtr()
{
  invalidate();
}
template <class T>
inline RefCountedPtr<T> &
RefCountedPtr<T>::operator=(const RefCountedPtr<T>& rhs)
{
  if (ptr_m != rhs.ptr_m)
    {
      if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
 delete ptr_m;
      ptr_m = rhs.ptr_m;
      if ( isValid() ) ptr_m->addReference();
    }
  return *this;
}
template <class T>
inline RefCountedPtr<T> &
RefCountedPtr<T>::operator=(T *pp)
{
  if (ptr_m != pp)
    {
      if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
 delete ptr_m;
      ptr_m = pp;
      if ( isValid() ) ptr_m->addReference();
    }
  return *this;
}
template <class T>
inline RefCountedPtr<T> &
RefCountedPtr<T>::makeOwnCopy()
{
  if ( isValid() && ptr_m->isShared() )
    {
      T * temp = ElementProperties<T>::clone(*ptr_m);
      ptr_m->removeReference();
      ptr_m = temp;
      ptr_m->addReference();
    }
  return *this;
}
template <class T>
class RefBlockController : public RefCounted
{
public:
  struct NoInitTag
  {
     NoInitTag() { }
     NoInitTag(const NoInitTag &) { }
     NoInitTag & operator=(const NoInitTag &) { return *this; }
  };
  explicit
  RefBlockController(size_t size)
    : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
  {
    reallocateStorage(size, false);
    if (!ElementProperties<T>::hasTrivialDefaultConstructor)
      {
 for (T * pt = begin(); pt != end(); ++pt)
   ElementProperties<T>::construct(pt);
      }
  }
  RefBlockController(size_t size, const T & model)
    : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
  {
    reallocateStorage(size, false);
    for (T * pt = begin(); pt != end(); ++pt)
      ElementProperties<T>::construct(pt, model);
  }
  RefBlockController(size_t size, const NoInitTag &)
    : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
  {
    reallocateStorage(size, false);
  }
  RefBlockController(T *p, size_t size)
    : pBegin_m(p), pEnd_m(p+size), pEndOfStorage_m(p+size), dealloc_m(false)
  { }
  RefBlockController(const RefBlockController &model)
    : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
  {
    size_t allocatedSize = model.pEndOfStorage_m - model.pBegin_m;
    size_t size = model.end() - model.begin();
    reallocateStorage(allocatedSize, false);
    pEnd_m = pBegin_m + size;
    T * pOld = model.begin();
    T * pNew = begin();
    while (pNew != end())
      {
 ElementProperties<T>::construct(pNew++,*pOld++);
      }
  }
  ~RefBlockController()
  {
    deleteStorage();
  }
  bool resize(size_t newsize, const NoInitTag &)
  {
    T *pNewEnd = pBegin_m + newsize;
    if (pNewEnd <= pEndOfStorage_m)
      {
        pEnd_m = pNewEnd;
        return true;
      }
    else
      {
        return false;
      }
  }
  bool resize(size_t newsize)
  {
    bool success = resize(newsize,NoInitTag());
    if (!ElementProperties<T>::hasTrivialDefaultConstructor)
      if (success)
 for (T * pt = begin(); pt != end(); ++pt)
          ElementProperties<T>::construct(pt);
    return success;
  }
  bool resize(size_t newsize, const T &model)
  {
    bool success = resize(newsize,NoInitTag());
    if (success)
      for (T * pt = begin(); pt != end(); ++pt)
        ElementProperties<T>::construct(pt, model);
    return success;
  }
  T *resizeAndCopy(size_t newsize)
  {
    size_t oldsize = size();
    if (!resize(newsize, NoInitTag()))
      {
 reallocateStorage(newsize, true);
 if (newsize > oldsize)
   for (T *pt = begin() + oldsize; pt != end(); ++pt)
     ElementProperties<T>::construct(pt);
      }
    return begin();
  }
  T *resizeAndCopy(size_t newsize, const T &model)
  {
    size_t oldsize = size();
    if (!resize(newsize, NoInitTag()))
      {
 reallocateStorage(newsize, true);
 if (newsize > oldsize)
   for (T *pt = begin() + oldsize; pt != end(); ++pt)
     ElementProperties<T>::construct(pt, model);
      }
    return begin();
  }
  T *resizeAndCopy(size_t newsize, const NoInitTag &)
  {
    if (!resize(newsize, NoInitTag()))
      {
 reallocateStorage(newsize, true);
      }
    return begin();
  }
  inline T *begin() const
  {
    return pBegin_m;
  }
  inline T *end() const
  {
    return pEnd_m;
  }
  inline size_t size() const
  {
    return static_cast<size_t>(pEnd_m - pBegin_m);
  }
  inline size_t capacity() const
  {
    return static_cast<size_t>(pEndOfStorage_m - pBegin_m);
  }
  inline bool empty() const
  {
    return pEnd_m == pBegin_m;
  }
  inline bool isMine() const
  {
    return dealloc_m;
  }
  inline bool checkDeref(const T *p) const
  {
    return ((pBegin_m <= p) && (p < pEnd_m));
  }
private:
  void deleteStorage()
  {
    if (isMine() && pBegin_m != 0)
      {
 if (!ElementProperties<T>::hasTrivialDestructor)
   for (T *pt = begin(); pt != end(); ++pt)
     ElementProperties<T>::destruct(pt);
 char *tmp = reinterpret_cast<char *>(pBegin_m);
 delete [] tmp;
      }
  }
  void reallocateStorage(size_t newsize, bool copyold = false)
  {
    T *pBeginNew = 0;
    T *pEndNew = 0;
    T *pEndOfStorageNew = 0;
    if (newsize > 0)
      {
 int nsize = newsize * sizeof(T);
 char *tmp = new char[nsize];
 pBeginNew = reinterpret_cast<T *>(tmp);
 pEndNew = pBeginNew + newsize;
 pEndOfStorageNew = pBeginNew + (nsize / sizeof(T));
 if (copyold)
   {
     T * pOld = begin();
     T * pNew = pBeginNew;
     while (pOld != end() && pNew != pEndNew)
       ElementProperties<T>::construct(pNew++,*pOld++);
   }
      }
    deleteStorage();
    pBegin_m = pBeginNew;
    pEnd_m = pEndNew;
    pEndOfStorage_m = pEndOfStorageNew;
    dealloc_m = true;
  }
  T *pBegin_m;
  T *pEnd_m;
  T *pEndOfStorage_m;
  bool dealloc_m;
};
template <class T,
  bool BoundsChecked=false,
  class Controller=RefBlockController<T> >
class RefCountedBlockPtr
{
public:
  typedef std::random_access_iterator_tag iterator_category;
  typedef T value_type;
  typedef ptrdiff_t difference_type;
  typedef T* pointer;
  typedef T& reference;
  typedef T Element_t;
  typedef T Pointee_t;
  typedef ptrdiff_t Offset_t;
  typedef RefCountedBlockPtr<T,BoundsChecked,Controller> This_t;
  typedef RefCountedBlockPtr<T,!BoundsChecked,Controller> That_t;
  struct NoInitTag
  {
     NoInitTag() { }
     NoInitTag(const NoInitTag &) { }
     NoInitTag & operator=(const NoInitTag &) { return *this; }
  };
  inline RefCountedBlockPtr()
    : offset_m(0)
  { }
  inline explicit RefCountedBlockPtr(size_t size)
    : offset_m(0),
      blockControllerPtr_m(new Controller(size))
  { }
  inline RefCountedBlockPtr(size_t size, const T & model)
    : offset_m(0),
      blockControllerPtr_m(new Controller(size,model))
  { }
  inline RefCountedBlockPtr(size_t size, const NoInitTag &)
    : offset_m(0),
      blockControllerPtr_m(new Controller(size,
       typename Controller::NoInitTag()))
  {
    blockControllerPtr_m->resize(0,typename Controller::NoInitTag());
  }
  inline RefCountedBlockPtr(T *p, size_t size)
    : offset_m(0),
      blockControllerPtr_m(new Controller(p, size))
  { }
  inline RefCountedBlockPtr(const This_t & model)
    : offset_m(model.offset_m),
      blockControllerPtr_m(model.blockControllerPtr_m)
  { }
  inline RefCountedBlockPtr(const That_t & model)
    : offset_m(model.offset_m),
      blockControllerPtr_m(model.blockControllerPtr_m)
  { }
  inline RefCountedBlockPtr(const This_t & model, Offset_t offset)
    : offset_m(model.offset_m + offset),
      blockControllerPtr_m(model.blockControllerPtr_m)
  { }
  inline ~RefCountedBlockPtr() {}
  inline This_t & operator=(const This_t & rhs)
  {
    blockControllerPtr_m = rhs.blockControllerPtr_m;
    offset_m = rhs.offset_m;
    return *this;
  }
  inline This_t & operator=(const That_t & rhs)
  {
    blockControllerPtr_m = rhs.blockControllerPtr_m;
    offset_m = rhs.offset_m;
    return *this;
  }
  template<class T1, bool BoundsChecked1, class Controller1>
  inline bool operator==(
    const RefCountedBlockPtr<T1, BoundsChecked1, Controller1>&) const
  {
    return false;
  }
  template<class T1, bool BoundsChecked1, class Controller1>
  inline bool operator!=(
    const RefCountedBlockPtr<T1, BoundsChecked1, Controller1>&) const
  {
    return true;
  }
  inline bool operator==(const This_t& a) const
  {
    return (beginPointer() == a.beginPointer() && offset() == a.offset());
  }
  inline bool operator!=(const This_t& a) const
  {
    return (beginPointer() != a.beginPointer() || offset() != a.offset());
  }
  inline bool operator<(const This_t& a) const
  {
    ;
    return offset() < a.offset();
  }
  inline bool operator>(const This_t& a) const
  {
    ;
    return offset() > a.offset();
  }
  inline bool operator<=(const This_t& a) const
  {
    ;
    return offset() <= a.offset();
  }
  inline bool operator>=(const This_t& a) const
  {
    ;
    return offset() >= a.offset();
  }
  inline bool operator==(const That_t& a) const
  {
    return (beginPointer() == a.beginPointer() && offset() == a.offset());
  }
  inline bool operator!=(const That_t& a) const
  {
    return (beginPointer() != a.beginPointer() || offset() != a.offset());
  }
  inline T& operator*() const
  {
    T *p = currentPointer();
    boundsAssert(p);
    return *p;
  }
  inline T& operator[](Offset_t i) const
  {
    T *p = currentPointer() + i;
    boundsAssert(p);
    return *p;
  }
  inline T *operator->() const
  {
    T *p = currentPointer();
    boundsAssert(p);
    return p;
  }
  inline This_t & operator++()
  {
    ++offset_m;
    return *this;
  }
  inline This_t & operator--()
  {
    --offset_m;
    return *this;
  }
  inline This_t operator++(int)
  {
    This_t save(*this);
    ++offset_m;
    return save;
  }
  inline This_t operator--(int)
  {
    This_t save(*this);
    --offset_m;
    return save;
  }
  inline void operator+=(Offset_t i)
  {
    offset_m += i;
  }
  inline void operator-=(Offset_t i)
  {
    offset_m -= i;
  }
  inline This_t operator+(Offset_t i) const
  {
    This_t ret(*this);
    ret += i;
    return ret;
  }
  inline This_t operator-(Offset_t i) const
  {
    This_t ret(*this);
    ret -= i;
    return ret;
  }
  inline This_t begin() const
  {
    return This_t(*this, -offset_m);
  }
  inline This_t end() const
  {
    return This_t(*this, size() - offset_m);
  }
  void reserve(size_t size)
  {
    ;
    typedef typename Controller::NoInitTag NoInit_t;
    blockControllerPtr_m = new Controller(size, NoInit_t());
    blockControllerPtr_m->resize(0,NoInit_t());
    offset_m = 0;
  }
  bool resize(size_t size, const NoInitTag &)
  {
    ;
    typedef typename Controller::NoInitTag NoInit_t;
    return blockControllerPtr_m->resize(size, NoInit_t());
  }
  bool resize(size_t size)
  {
    ;
    return blockControllerPtr_m->resize(size);
  }
  bool resize(size_t size, const T &model)
  {
    ;
    return blockControllerPtr_m->resize(size, model);
  }
  void resizeAndCopy(size_t size, const NoInitTag &)
  {
    ;
    typedef typename Controller::NoInitTag NoInit_t;
    blockControllerPtr_m->resizeAndCopy(size, NoInit_t());
  }
  void resizeAndCopy(size_t size)
  {
    ;
    blockControllerPtr_m->resizeAndCopy(size);
  }
  void resizeAndCopy(size_t size, const T &model)
  {
    ;
    blockControllerPtr_m->resizeAndCopy(size, model);
  }
  void invalidate()
  {
    blockControllerPtr_m.invalidate();
    offset_m = 0;
  }
  This_t & makeOwnCopy()
  {
    blockControllerPtr_m.makeOwnCopy();
    return *this;
  }
  inline Offset_t offset() const
  {
    return offset_m;
  }
  inline bool isValid() const
  {
    return blockControllerPtr_m.isValid();
  }
  inline bool isShared() const
  {
    return blockControllerPtr_m.isShared();
  }
  inline int count() const
  {
    return isValid() ? blockControllerPtr_m.count() : 0;
  }
  inline size_t size() const
  {
    return isValid() ? blockControllerPtr_m->size() : 0;
  }
  inline size_t capacity() const
  {
    return isValid() ? blockControllerPtr_m->capacity() : 0;
  }
  inline bool empty() const
  {
    return isValid() ? blockControllerPtr_m->empty() : true;
  }
  inline bool isAtBeginning() const
  {
    return (offset() == 0);
  }
  inline bool isMine() const
  {
    return isValid() ? blockControllerPtr_m->isMine() : true;
  }
  inline T *beginPointer() const
  {
    ;
    return blockControllerPtr_m->begin();
  }
  inline T *endPointer() const
  {
    ;
    return blockControllerPtr_m->end();
  }
  inline T *currentPointer() const
  {
    return beginPointer() + offset();
  }
protected:
  friend class RefCountedBlockPtr<T,!BoundsChecked,Controller>;
  RefCountedBlockPtr(Controller *con)
    : offset_m(0), blockControllerPtr_m(con)
  { }
  inline void boundsAssert(T *p) const
  {
    if (BoundsChecked)
      {
        if (__builtin_expect(!!(isValid() && blockControllerPtr_m->checkDeref(p)), true)) {} else Pooma::toss_cookies("RefCountedBlockPtr: Bounds Violation.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/RefCountedBlockPtr.h", 1038);
      }
  }
  Offset_t offset_m;
  RefCountedPtr<Controller> blockControllerPtr_m;
};
template <class T, bool C1, bool C2, class Controller>
inline ptrdiff_t
operator-(const RefCountedBlockPtr<T,C1,Controller> &first,
          const RefCountedBlockPtr<T,C2,Controller> &second)
{
  return first.currentPointer() - second.currentPointer();
}
template <class T> class SingleObserver;
template <class T>
class DataBlockController
  : public RefBlockController<T>
{
public:
  typedef Pooma::DataObject_t DataObject_t;
  typedef SingleObservable<int> Observable_t;
  typedef RefBlockController<T> Base_t;
  typedef typename RefBlockController<T>::NoInitTag NoInitTag;
  typedef ObserverEvent::ID_t DynamicID_t;
  explicit
  DataBlockController(size_t size)
    : Base_t(size), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, const T & model)
    : Base_t(size,model), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(T *p, size_t size)
    : Base_t(p,size), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, const NoInitTag &tag)
    : Base_t(size,tag), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  struct WithAffinity
  {
    WithAffinity() { }
    WithAffinity(const WithAffinity&) { }
    WithAffinity &operator=(const WithAffinity &) { return *this; }
  };
  DataBlockController(size_t size, int affinity, const WithAffinity &)
    : Base_t(size), dataObjectPtr_m(new DataObject_t(affinity)), owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, int affinity, const WithAffinity &,
                      const NoInitTag &tag)
    : Base_t(size,tag), dataObjectPtr_m(new DataObject_t(affinity)),
      owned_m(true),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, DataObject_t &dobj)
    : Base_t(size), dataObjectPtr_m(&dobj), owned_m(false),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, const T& model, DataObject_t &dobj)
    : Base_t(size,model), dataObjectPtr_m(&dobj), owned_m(false),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(size_t size, DataObject_t &dobj, const NoInitTag &tag)
    : Base_t(size,tag), dataObjectPtr_m(&dobj), owned_m(false),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(const DataBlockController &model)
    : Base_t(model),
      dataObjectPtr_m(model.dataObjectPtr_m ?
        new DataObject_t(model.affinity()) : 0),
      owned_m(model.dataObjectPtr_m ? true : false),
      observable_m(),
      dynamicID_m(ObserverEvent::nullID())
  { }
  DataBlockController(const DataBlockController &model, DataObject_t &dobj)
    : Base_t(model), observable_m(), owned_m(false),
      dataObjectPtr_m(&dobj),
      dynamicID_m(ObserverEvent::nullID())
  { }
  ~DataBlockController()
  {
    if (owned_m) delete dataObjectPtr_m;
  }
  void attach(SingleObserver<int> *o)
  {
    observable_m.attach(o);
  }
  void detach()
  {
    observable_m.detach();
  }
  inline DataObject_t* dataObject() const
  {
    return dataObjectPtr_m;
  }
  inline void dataObject(DataObject_t *obj)
  {
    if (owned_m) delete dataObjectPtr_m;
    owned_m = false;
    dataObjectPtr_m = obj;
  }
  inline int affinity() const
  {
    return dataObjectPtr_m->affinity();
  }
  inline void affinity(int affin)
  {
    dataObjectPtr_m->affinity(affin);
  }
  enum Notifier { addViewEvent, removeViewEvent };
  inline void notifyOnDestruct()
  {
    observable_m.notify(0,removeViewEvent);
  }
  inline void notifyOnConstruct()
  {
    observable_m.notify(0,addViewEvent);
  }
  DynamicID_t dynamicID() const
  {
    return dynamicID_m;
  }
  void setDynamicID(DynamicID_t id)
  {
    dynamicID_m = id;
  }
private:
  mutable DataObject_t *dataObjectPtr_m;
  bool owned_m;
  Observable_t observable_m;
  DynamicID_t dynamicID_m;
};
template <class T,
          bool BoundsChecked=false>
class DataBlockPtr
  : public RefCountedBlockPtr<T,BoundsChecked,DataBlockController<T> >
{
public:
  typedef T Pointee_t;
  typedef T Element_t;
  typedef DataBlockPtr<T,BoundsChecked> This_t;
  typedef Pooma::DataObject_t DataObject_t;
  typedef SingleObservable<int> Observable_t;
  typedef DataBlockPtr<T,!BoundsChecked> That_t;
  typedef DataBlockController<T> Controller_t;
  typedef RefCountedBlockPtr<T,BoundsChecked,Controller_t> RCBPtr_t;
  typedef typename Controller_t::DynamicID_t DynamicID_t;
  typedef typename RCBPtr_t::NoInitTag NoInitTag;
  DataBlockPtr() : RCBPtr_t()
  { }
  explicit DataBlockPtr(size_t size)
    : RCBPtr_t(size)
  { }
  DataBlockPtr(size_t size, const NoInitTag &tag)
    : RCBPtr_t(size,tag)
  { }
  DataBlockPtr(int size, const T& model)
    : RCBPtr_t(size,model)
  { }
  DataBlockPtr(T* foreignData, int size)
    : RCBPtr_t(foreignData,size)
  { }
  typedef typename Controller_t::WithAffinity WithAffinity_t;
  DataBlockPtr(int size, int affin, const WithAffinity_t&)
    : RCBPtr_t(new Controller_t(size,affin,WithAffinity_t()))
  { }
  DataBlockPtr(int size, int affin, const WithAffinity_t&,
        const NoInitTag &tag)
    : RCBPtr_t(new Controller_t(size,affin,WithAffinity_t(),tag))
  { }
  DataBlockPtr(int size, DataObject_t &dobj)
    : RCBPtr_t(new Controller_t(size,dobj))
  { }
  DataBlockPtr(int size, const T& model, DataObject_t &dobj)
    : RCBPtr_t(new Controller_t(size,model,dobj))
  { }
  DataBlockPtr(int size, DataObject_t &dobj, const NoInitTag &tag)
    : RCBPtr_t(new Controller_t(size,dobj,tag))
  { }
  DataBlockPtr(const This_t& model)
    : RCBPtr_t(model)
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
  }
  DataBlockPtr(const This_t& model, DataObject_t &dobj)
    : RCBPtr_t(new Controller_t(model, dobj))
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
  }
  DataBlockPtr(const That_t& model)
    : RCBPtr_t(model)
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
  }
  DataBlockPtr(const RCBPtr_t& model)
    : RCBPtr_t(model)
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
  }
  DataBlockPtr(const This_t& model, ptrdiff_t offset)
    : RCBPtr_t(model,offset)
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
  }
  ~DataBlockPtr()
  {
    if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
  }
  This_t & operator=(const This_t & rhs)
  {
    if (this != &rhs)
      {
 if (rhs.isValid()) rhs.blockControllerPtr_m->notifyOnConstruct();
 if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
 RCBPtr_t::operator=(rhs);
      }
    return *this;
  }
  This_t & operator=(const That_t & rhs)
  {
    if (this != &rhs)
      {
 if (rhs.isValid()) rhs.blockControllerPtr_m->notifyOnConstruct();
 if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
 RCBPtr_t::operator=(rhs);
      }
    return *this;
  }
  This_t & operator++()
  { RCBPtr_t::operator++(); return *this; }
  This_t & operator--()
  { RCBPtr_t::operator--(); return *this; }
  This_t operator++(int)
  {
    This_t tmp(*this);
    RCBPtr_t::operator++();
    return tmp;
  }
  This_t operator--(int)
  {
    This_t tmp(*this);
    RCBPtr_t::operator--();
    return tmp;
  }
  This_t operator+(ptrdiff_t i) const
  {
    This_t ret(*this);
    ret += i;
    return ret;
  }
  This_t operator-(ptrdiff_t i) const
  {
    This_t ret(*this);
    ret -= i;
    return ret;
  }
  This_t begin() const
  { return RCBPtr_t::begin(); }
  This_t end() const
  { return RCBPtr_t::end(); }
  void attach(SingleObserver<int> *o)
  {
    this->blockControllerPtr_m->attach(o);
  }
  void detach()
  {
    this->blockControllerPtr_m->detach();
  }
  inline DataObject_t* dataObject() const
  {
    return this->blockControllerPtr_m->dataObject();
  }
  inline void dataObject(DataObject_t *obj)
  {
    this->blockControllerPtr_m->dataObject(obj);
  }
  inline int affinity() const
  {
    return this->blockControllerPtr_m->affinity();
  }
  inline void affinity(int affin)
  {
    this->blockControllerPtr_m->affinity(affin);
  }
  bool sameDataObject(const DataBlockPtr<T>& x) const
  {
    return dataObject() == x.dataObject();
  }
  void lockRefCount() const { this->blockControllerPtr_m->lock(); }
  void unlockRefCount() const { this->blockControllerPtr_m->unlock(); }
  DynamicID_t dynamicID() const
  {
    return this->isValid() ?
      this->blockControllerPtr_m->dynamicID() :
      ObserverEvent::nullID();
  }
  void setDynamicID(DynamicID_t id)
  {
    ;
    this->blockControllerPtr_m->setDynamicID(id);
  }
private:
  friend class DataBlockPtr<T,!BoundsChecked>;
};
template <class T, bool C1, bool C2>
ptrdiff_t operator-(const DataBlockPtr<T,C1> &first,
      const DataBlockPtr<T,C2> &second)
{
  return first.currentPointer() - second.currentPointer();
}
template<class T>
class IndirectionList
{
public:
  typedef IndirectionList<T> This_t;
  typedef T Element_t;
  typedef IndirectionList<T> Domain_t;
  typedef DataBlockPtr<T> Storage_t;
  typedef long Size_t;
  enum { dimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  IndirectionList()
    : size_m(0)
    {
    }
  IndirectionList(const This_t &a)
    : iList_m(a.iList_m), size_m(a.size_m)
    {
    }
  IndirectionList(int num) : iList_m(num), size_m(num) { ; }
  IndirectionList(long num) : iList_m(num), size_m(num) { ; }
  IndirectionList(unsigned int num) : iList_m(num), size_m(num) { }
  IndirectionList(unsigned long num) : iList_m(num), size_m(num) { }
  template<class T1>
  IndirectionList(const T1 &first, const T1 &stride, Size_t num)
    : iList_m(num), size_m(num)
    {
      ;
      T1 val = first;
      for (Size_t i=0; i < num; ++i)
 {
   iList_m[i] = val;
   val += stride;
 }
    }
  template<class T1>
  explicit IndirectionList(const T1 &a)
    : iList_m(a.engine().dataBlock()), size_m(a.domain().size())
    {
    }
  ~IndirectionList()
    {
    }
  This_t &operator=(const This_t &newilist)
    {
      iList_m = newilist.iList_m;
      size_m = newilist.size_m;
      return *this;
    }
  template<class T1>
  This_t &operator=(const T1 &a)
    {
      iList_m = a.engine().dataBlock();
      size_m = a.domain().size();
      return *this;
    }
  This_t &operator[](int i)
    {
      ;
      return *this;
    }
  const This_t &operator[](int i) const
    {
      ;
      return *this;
    }
  const T &operator()(Size_t i1) const
    {
      return iList_m[i1];
    }
  T &operator()(Size_t i1)
    {
      return iList_m[i1];
    }
  Size_t length() const
    {
      return size_m;
    }
  T first() const
    {
      return iList_m[0];
    }
  T last() const
    {
      return iList_m[size_m-1];
    }
  T stride() const
    {
      return T(0);
    }
  T min() const
    {
      T result = iList_m[0];
      for (Size_t i=1; i<size_m; ++i)
 result = (iList_m[i] < result) ? iList_m[i] : result;
      return result;
    }
  T max() const
    {
      T result = iList_m[0];
      for (Size_t i=1; i<size_m; ++i)
 result = (result < iList_m[i]) ? iList_m[i] : result;
      return result;
    }
  Size_t size() const
    {
      return size_m;
    }
  bool empty() const
    {
      return (size() == 0);
    }
  bool initialized() const
    {
      return (!empty());
    }
  template<class T1>
  This_t &operator+=(const T1 &val)
    {
      Size_t n = size();
      if (n > 0)
 {
   iList_m.makeOwnCopy();
   for (Size_t i=0; i < n; ++i)
     iList_m[i] += val;
 }
      return *this;
    }
  template<class T1>
  This_t &operator-=(const T1 &val)
    {
      Size_t n = size();
      if (n > 0)
 {
   iList_m.makeOwnCopy();
   for (Size_t i=0; i < n; ++i)
     iList_m[i] -= val;
 }
      return *this;
    }
  template<class T1>
  This_t &operator*=(const T1 &val)
    {
      Size_t n = size();
      if (n > 0)
 {
   iList_m.makeOwnCopy();
   for (Size_t i=0; i < n; ++i)
     iList_m[i] *= val;
 }
      return *this;
    }
  template<class T1>
  This_t &operator/=(const T1 &val)
    {
      Size_t n = size();
      if (n > 0)
 {
   iList_m.makeOwnCopy();
   for (Size_t i=0; i < n; ++i)
     iList_m[i] /= val;
 }
      return *this;
    }
  template<class Out>
  void print(Out &o) const;
private:
  Storage_t iList_m;
  Size_t size_m;
};
template<class T>
template<class Out>
void IndirectionList<T>::print(Out &o) const
{
  o << "[";
  for (Size_t i=0; i < size(); ++i)
    {
      o << (*this)(i);
      if (i < (size() - 1))
 o << ",";
    }
  o << "]";
}
template<class T>
std::ostream& operator<<(std::ostream &o, const IndirectionList<T> &list)
{
  list.print(o);
  return o;
}
namespace Pooma {
template <class Iter>
class IteratorPairDomain
{
public:
  typedef IteratorPairDomain<Iter> This_t;
  typedef Iter iterator;
  typedef std::iterator_traits<Iter> IterTraits_t;
  typedef typename IterTraits_t::value_type Element_t;
  typedef typename IterTraits_t::reference ElementRef_t;
  typedef long Size_t;
  enum { dimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  IteratorPairDomain() : size_m(0) { }
  IteratorPairDomain(Iter begin, Iter end)
    : begin_m(begin), end_m(end)
  {
    size_m = std::distance(begin_m,end_m);
  }
  IteratorPairDomain(const This_t &a)
    : begin_m(a.begin_m), end_m(a.end_m), size_m(a.size_m)
  { }
  template <class OtherIter>
  IteratorPairDomain(const IteratorPairDomain<OtherIter> &a)
    : begin_m(a.begin()), end_m(a.end()), size_m(a.size())
  { }
  This_t &operator=(const This_t &model)
  {
    begin_m = model.begin_m;
    end_m = model.end_m;
    size_m = model.size_m;
    return *this;
  }
  This_t &operator[](int i)
  {
    ;
    return *this;
  }
  const This_t &operator[](int i) const
  {
    ;
    return *this;
  }
  Element_t operator()(Size_t i) const
  {
    ;
    Iter pos = begin_m;
    std::advance(pos,i);
    return *pos;
  }
  ElementRef_t operator()(Size_t i)
  {
    ;
    Iter pos = begin_m;
    std::advance(pos,i);
    return *pos;
  }
  Size_t length() const { return size_m; }
  Size_t size() const { return size_m; }
  bool empty() const { return size_m == 0; }
  bool initialized() const { return size_m != 0; }
  Element_t first() const { return *begin_m; }
  Element_t last() const
  {
    Iter lpos = begin_m;
    std::advance(lpos,size_m-1);
    return *lpos;
  }
  Element_t min() const
  {
    Iter pos = begin_m;
    Element_t result = *pos++;
    for (Size_t i = 1; i < size_m; ++i)
      {
        if (*pos < result) result = *pos;
        ++pos;
      }
    return result;
  }
  Element_t max() const
  {
    Iter pos = begin_m;
    Element_t result = *pos++;
    for (Size_t i = 1; i < size_m; ++i)
      {
        if (result < *pos) result = *pos;
        ++pos;
      }
    return result;
  }
  Iter begin() const { return begin_m; }
  Iter end() const { return end_m; }
  template <class Out>
  void print(Out &o) const;
private:
  Iter begin_m;
  Iter end_m;
  Size_t size_m;
};
template <class Iter>
template <class Out>
void IteratorPairDomain<Iter>::print(Out &o) const
{
  o << "[";
  Iter pos = begin_m;
  o << *pos++;
  for (Size_t i = 1; i < size_m; ++i)
    {
      o << "," << *pos++;
    }
  o << "]";
}
template <class Iter>
std::ostream&
operator<<(std::ostream &o, const IteratorPairDomain<Iter> &list)
{
  list.print(o);
  return o;
}
}
using Pooma::IteratorPairDomain;
struct DynamicEvents
{
  enum EventCode {
         create = 1000,
  extend,
  destroyInterval, destroyRange, destroyList, destroyIterList,
  copyInterval, copyRange, copyList,
  copyPatchList,
  sync,
  unknownEvent };
  static bool isDynamic(int eventcode)
  {
    return eventcode >= DynamicEvents::create &&
           eventcode < DynamicEvents::unknownEvent;
  }
  enum { backfill = 100, shiftup, unknownMethod };
  typedef int PatchID_t;
  typedef int CreateSize_t;
};
struct BackFill
{
  enum { code = DynamicEvents::backfill };
  BackFill(){};
};
struct ShiftUp
{
  enum { code = DynamicEvents::shiftup };
  ShiftUp(){};
};
template<class T>
struct DynamicEventType
{
  enum { destroyCode = DynamicEvents::destroyList };
  enum { copyCode = DynamicEvents::copyList };
  enum { dimensions = 1 };
  typedef IndirectionList<int> Domain_t;
};
template <>
struct DynamicEventType<IteratorPairDomain<const int*> >
{
  enum { destroyCode = DynamicEvents::destroyIterList };
  enum { copyCode = DynamicEvents::copyList };
  enum { dimensions = 1 };
  typedef IteratorPairDomain<const int*> Domain_t;
};
template <>
struct DynamicEventType<IteratorPairDomain<int*> >
{
  enum { destroyCode = DynamicEvents::destroyIterList };
  enum { copyCode = DynamicEvents::copyList };
  enum { dimensions = 1 };
  typedef IteratorPairDomain<const int*> Domain_t;
};
template<>
struct DynamicEventType< IndirectionList< IndirectionList<int> > >
{
  enum { destroyCode = DynamicEvents::unknownEvent };
  enum { copyCode = DynamicEvents::copyPatchList };
  enum { dimensions = 1 };
  typedef IndirectionList< IndirectionList<int> > Domain_t;
};
template<int Dim>
struct DynamicEventType< Interval<Dim> >
{
  enum { destroyCode = DynamicEvents::destroyInterval };
  enum { copyCode = DynamicEvents::copyInterval };
  enum { dimensions = Dim };
  typedef Interval<Dim> Domain_t;
};
template<int Dim>
struct DynamicEventType< Range<Dim> >
{
  enum { destroyCode = DynamicEvents::destroyRange };
  enum { copyCode = DynamicEvents::copyRange };
  enum { dimensions = Dim };
  typedef Range<Dim> Domain_t;
};
template<int Dim>
struct DynamicEventType< Loc<Dim> >
{
  enum { destroyCode = DynamicEvents::destroyInterval };
  enum { copyCode = DynamicEvents::copyInterval };
  enum { dimensions = Dim };
  typedef Interval<Dim> Domain_t;
};
template<>
struct DynamicEventType<int>
{
  enum { destroyCode = DynamicEvents::destroyInterval };
  enum { copyCode = DynamicEvents::copyInterval };
  enum { dimensions = 1 };
  typedef Interval<1> Domain_t;
};
class CreateEvent : public ObserverEvent
{
public:
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  CreateEvent(CreateSize_t num, PatchID_t p)
    : ObserverEvent(DynamicEvents::create),
      amount_m(num), patch_m(p)
    {
    }
  virtual ~CreateEvent()
    {
    }
  inline CreateSize_t amount() const
    {
      return amount_m;
    }
  inline PatchID_t patch() const
    {
      return patch_m;
    }
private:
  CreateSize_t amount_m;
  PatchID_t patch_m;
};
template<class Dom>
class DestroyEvent : public ObserverEvent
{
public:
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef typename DynamicEventType<Dom>::Domain_t Domain_t;
  template<class D>
  DestroyEvent(const D &d, PatchID_t p, int method)
    : ObserverEvent(DynamicEventType<Dom>::destroyCode),
      domain_m(d), patch_m(p), method_m(method)
    {
      PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
    }
  virtual ~DestroyEvent()
    {
    }
  inline const Domain_t &domain() const
    {
      return domain_m;
    }
  inline PatchID_t patch() const
    {
      return patch_m;
    }
  inline int method() const
    {
      return method_m;
    }
private:
  Domain_t domain_m;
  PatchID_t patch_m;
  int method_m;
};
template<class Dom>
class CopyEvent : public ObserverEvent
{
public:
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef typename DynamicEventType<Dom>::Domain_t Domain_t;
  CopyEvent(const Dom &d, PatchID_t fromp, PatchID_t top)
    : ObserverEvent(DynamicEventType<Dom>::copyCode),
      domain_m(d), from_m(fromp), to_m(top)
    {
      PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
    }
  template<class D>
  CopyEvent(const D &d, PatchID_t fromp, PatchID_t top)
    : ObserverEvent(DynamicEventType<Dom>::copyCode),
      domain_m(d), from_m(fromp), to_m(top)
    {
      PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
    }
  virtual ~CopyEvent()
    {
    }
  inline const Domain_t &domain() const
    {
      return domain_m;
    }
  inline PatchID_t fromPatch() const
    {
      return from_m;
    }
  inline PatchID_t toPatch() const
    {
      return to_m;
    }
private:
  Domain_t domain_m;
  PatchID_t from_m;
  PatchID_t to_m;
};
class CopyPatchEvent : public ObserverEvent
{
public:
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef IndirectionList< IndirectionList<int> > Domain_t;
  typedef IndirectionList<int> IDList_t;
  CopyPatchEvent(const Domain_t &domlists, const IDList_t &fromlist,
   PatchID_t top, bool create)
    : ObserverEvent(DynamicEvents::copyPatchList),
      lists_m(domlists), from_m(fromlist), to_m(top), create_m(create)
    {
    }
  virtual ~CopyPatchEvent()
    {
    }
  inline const Domain_t &domainLists() const
    {
      return lists_m;
    }
  inline const IDList_t &fromPatch() const
    {
      return from_m;
    }
  inline PatchID_t toPatch() const
    {
      return to_m;
    }
  inline bool create() const
    {
      return create_m;
    }
private:
  Domain_t lists_m;
  IDList_t from_m;
  PatchID_t to_m;
  bool create_m;
};
class SyncEvent : public ObserverEvent
{
public:
  SyncEvent()
    : ObserverEvent(DynamicEvents::sync)
    {
    }
  virtual ~SyncEvent()
    {
    }
private:
};
template<int Dim>
class ContextMapper
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  ContextMapper(){};
  virtual ~ContextMapper(){};
  virtual void map(const List_t & templist) const = 0;
  void setAffinity(const List_t & templist) const;
};
template<int Dim>
void ContextMapper<Dim>::setAffinity(const List_t & templist) const
{
  int affinityMax = Smarts::concurrency();
  int idMax = 0;
  typename List_t::const_iterator start = templist.begin();
  typename List_t::const_iterator end = templist.end();
  for ( ; start != end ; ++start)
    if((*start)->context()==Pooma::context())
      {
 (*start)->localID()=idMax;
 ++idMax;
      }
  start = templist.begin();
  for ( ; start != end ; ++start)
    {
      if((*start)->context()==Pooma::context())
 (*start)->affinity() = static_cast<int>
   ( affinityMax * ( (*start)->localID()
       / static_cast<double>(idMax) ) );
    }
  return;
}
template<int Dim>
class LocalMapper
  : public ContextMapper<Dim>
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template<class Partitioner>
  LocalMapper(const Partitioner &)
  {}
  LocalMapper()
  {}
  void map(const List_t & templist) const;
};
template<int Dim>
void LocalMapper<Dim>::map(const List_t & templist) const
{
  int idMax = templist.size();
  int naff = Smarts::concurrency();
  for (int i = 0; i< templist.size(); ++i)
    {
      templist[i]->context() = -1;
      templist[i]->localID() = i;
      templist[i]->affinity() = static_cast<int>( ( naff * ( i /
    static_cast<double>(idMax) ) ) );
    }
}
template<int Dim>
class DefaultTPmapper
  : public ContextMapper<Dim>
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template<class Partitioner>
  DefaultTPmapper(const Partitioner & gp)
  {
  }
  void map(const List_t & templist) const;
private:
};
template<int Dim>
void DefaultTPmapper<Dim>::map(const List_t & templist) const
{
  int ncontexts = Pooma::contexts();
  int npc = templist.size()/ncontexts;
  if (templist.size()%ncontexts!=0) ++npc;
  typename List_t::const_iterator start = templist.begin();
  typename List_t::const_iterator end = templist.end();
  int c = 0;
  int p = 0;
  for ( ; start!=end ; ++start)
    {
      (*start)->context() = p;
      if(p == Pooma::context())
 (*start)->localID() = c;
      ++c;
      if (c > npc)
 {
   ++p;
   c = 0;
 }
    }
  int affinityMax = Smarts::concurrency();
  int idMax = 0;
  start = templist.begin();
  for ( ; start != end ; ++start)
    if((*start)->context()==Pooma::context())
      {
 (*start)->localID()=idMax;
 ++idMax;
      }
  start = templist.begin();
  for ( ; start != end ; ++start)
    {
      if((*start)->context()==Pooma::context())
 (*start)->affinity() = static_cast<int>( affinityMax *
       ( (*start)->localID() /
          static_cast<double>(idMax) ) );
    }
}
template<int Dim>
class TilePartition
{
public:
  typedef LocalMapper<Dim> DefaultMapper_t;
  typedef Interval<Dim> Domain_t;
  typedef std::vector<Domain_t> PatchList_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  enum { uniform = false };
  enum { gridded = false };
  enum { tile = true };
  enum { general = true };
  enum { dimensions = Dim };
  TilePartition()
    : hasInternalGuards_m(false),
      hasExternalGuards_m(false),
      num_m(0),
      internalGuards_m(0),
      externalGuards_m(0)
  {
  }
  TilePartition(const PatchList_t &pList)
    : hasInternalGuards_m(false),
      hasExternalGuards_m(false),
      internalGuards_m(0),
      externalGuards_m(0),
      tile_m(pList)
  {
    num_m = pList.size();
  }
  TilePartition(const PatchList_t &pList,
  const GuardLayers<Dim> &gcs)
    : hasInternalGuards_m(true),
      hasExternalGuards_m(false),
      internalGuards_m(gcs),
      externalGuards_m(gcs),
      tile_m(pList)
  {
    num_m = tile_m.size();
  }
  TilePartition(const PatchList_t &pList,
  const GuardLayers<Dim> &igcs,
  const GuardLayers<Dim> &egcs)
    : hasInternalGuards_m(true),
      hasExternalGuards_m(true),
      internalGuards_m(igcs),
      externalGuards_m(egcs),
      tile_m(pList)
  {
    num_m = tile_m.size();
  }
  TilePartition(const TilePartition<Dim> & b)
    : hasInternalGuards_m(b.hasInternalGuards_m),
      hasExternalGuards_m(b.hasExternalGuards_m),
      internalGuards_m(b.internalGuards_m),
      externalGuards_m(b.externalGuards_m),
      tile_m(b.tile_m),
      num_m(b.num_m)
  {
  }
  ~TilePartition() { }
  TilePartition<Dim> &operator=(const TilePartition<Dim> &g)
  {
    if (this != &g)
      {
 hasInternalGuards_m = g.hasInternalGuards_m;
 hasExternalGuards_m = g.hasExternalGuards_m;
 internalGuards_m = g.internalGuards_m;
 externalGuards_m = g.externalGuards_m;
 tile_m = const_cast<TilePartition<Dim>&>(g).tileList();
 num_m = g.maxSize();
 if (!hasInternalGuards_m)
   internalGuards_m = GuardLayers<Dim>(0);
 if (!hasExternalGuards_m)
   externalGuards_m = GuardLayers<Dim>(0);
      }
    return *this;
  }
  int maxSize() const { return num_m; }
  PatchList_t tileList() { return tile_m; }
  bool hasGuards() const { return hasInternalGuards_m||hasExternalGuards_m; }
  bool hasCustomEdgeGuards() const
  {
    if (hasInternalGuards_m&&!hasExternalGuards_m) return true;
    if (!hasInternalGuards_m&&hasExternalGuards_m) return true;
    if (hasInternalGuards_m&&hasExternalGuards_m
       &&(internalGuards_m!=externalGuards_m)) return true;
    return false;
  }
  bool hasInternalGuards() const { return hasInternalGuards_m; }
  bool hasExternalGuards() const { return hasExternalGuards_m;}
  const GuardLayers<Dim> &internalGuards() const
  {
    return internalGuards_m;
  }
  const GuardLayers<Dim> &externalGuards() const
  {
    return externalGuards_m;
  }
  template<class D>
  int partition(const D &bbox,List_t &all,const ContextMapper<Dim> &cmapper) const;
  template<class D>
  int partition(const D &bbox,List_t &all) const
  {
    return partition(bbox,all,LocalMapper<Dim>(*this));
  }
  template<class Out>
  void print(Out &o) const;
private:
  bool hasInternalGuards_m;
  bool hasExternalGuards_m;
  GuardLayers<Dim> internalGuards_m;
  GuardLayers<Dim> externalGuards_m;
  int num_m;
  PatchList_t tile_m;
};
template<int Dim>
template<class D>
int TilePartition<Dim>::partition(const D &bbox, List_t &all,
      const ContextMapper<Dim> &cmapper) const
{
  typedef typename DomainTraits<Domain_t>::Element_t Element_t;
  PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
  typename PatchList_t::const_iterator start = tile_m.begin();
  typename PatchList_t::const_iterator end = tile_m.end();
  while (start!=end)
    {
      Domain_t o = Pooma::NoInit();
      o = * start;
      Domain_t oo = o;
      Domain_t a = Pooma::NoInit();
      a = * start;
      if (hasInternalGuards()||hasExternalGuards())
 {
   for (int i=0;i<Dim;i++)
     {
       if (oo[i].first() == bbox[i].first())
  {
    if (hasExternalGuards())
      {
        o[i]=Interval<1>(o[i].first()-externalGuards().lower(i),
           o[i].last());
        a[i]=Interval<1>(a[i].first()-externalGuards().lower(i),
           a[i].last());
      }
    if (hasInternalGuards() && oo[i].last() != bbox[i].last() )
      a[i]=Interval<1>(a[i].first(),
         a[i].last()+internalGuards().upper(i));
  }
       if (oo[i].last()== bbox[i].last())
  {
    if (hasExternalGuards())
      {
        o[i]=Interval<1>(o[i].first(),
           o[i].last()+externalGuards().upper(i));
        a[i]=Interval<1>(a[i].first(),
           a[i].last()+externalGuards().upper(i));
      }
    if (hasInternalGuards()&&(oo[i].first() != bbox[i].first()))
      a[i]=Interval<1>(a[i].first()-internalGuards().lower(i),
         a[i].last());
  }
       if (oo[i].first()!=bbox[i].first() &&
    oo[i].last() != bbox[i].last() &&
    hasInternalGuards())
  a[i]=Interval<1>(o[i].first()-internalGuards().lower(i),
     o[i].last()+internalGuards().upper(i));
     }
 }
      Value_t * node = new Value_t(o,a,-1,all.size(),-1);
      all.push_back(node);
      ++start;
    }
  cmapper.map(all);
  return all.size();
}
template<int Dim>
template<class Out>
void TilePartition<Dim>::print(Out &o) const
{
  int i;
  o << "TilePartition<" << Dim << ">:" << std::endl;
  o << "  hasInternalGuards_m  hasExternalGuards_m = ";
  o << hasInternalGuards_m<< " "<<hasExternalGuards_m<< std::endl;
  o << "  internalGuards_m:" << std::endl;
  o << "      upper       ";
  for (i=0; i < Dim; ++i)
    o << internalGuards_m.upper(i) << " ";
  o << std::endl;
  o << "      lower       ";
  for (i=0; i < Dim; ++i)
    o << internalGuards_m.lower(i) << " ";
  o << std::endl;
  o << "  externalGuards_m:" << std::endl;
  o << "      upper       ";
  for (i=0; i < Dim; ++i)
    o << externalGuards_m.upper(i) << " ";
  o << std::endl;
  o << "      lower       ";
  for (i=0; i < Dim; ++i)
    o << externalGuards_m.lower(i) << " ";
  o << std::endl;
  o << "  num_m = " << num_m << std::endl;
}
template <int Dim>
std::ostream &operator<<(std::ostream &o, const TilePartition<Dim> &gp)
{
  gp.print(o);
  return o;
}
extern
bool findLeftCommonEndpoint(int a0, int a1, int s, int b0, int b1, int t,
                            int &endpoint);
extern
bool findIntersectionEndpoints(int a0, int a1, int s, int b0, int b1, int t,
                               int &i0, int &i1, int &is);
template<class T1, class T2, class T3, int Dim, bool strided>
struct IntersectDomainSingle {
  static void intersect(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::Element_t E1_t;
    typedef typename DomainTraits<T2>::Element_t E2_t;
    E1_t a0 = a.min();
    E1_t a1 = a.max();
    E2_t b0 = b.min();
    E2_t b1 = b.max();
    if (a1 < b0 || a0 > b1)
      return;
    if (b0 > a0)
      a0 = b0;
    if (b1 < a1)
      a1 = b1;
    typedef typename DomainTraits<T3>::OneDomain_t Dom_t;
    c[Dim-1] = Dom_t(a0, a1);
  }
};
template<class T1, class T2, class T3, int Dim>
struct IntersectDomainSingle<T1,T2,T3,Dim,true> {
  static void intersect(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::Element_t E1_t;
    typedef typename DomainTraits<T2>::Element_t E2_t;
    E1_t s = a.stride();
    E2_t t = b.stride();
    if (s == 1 && t == 1) {
      IntersectDomainSingle<T1,T2,T3,Dim,false>::intersect(a,b,c);
      return;
    }
    E1_t a0 = a.min();
    E1_t a1 = a.max();
    E2_t b0 = b.min();
    E2_t b1 = b.max();
    if (a1 < b0 || a0 > b1)
      return;
    int i1, i2, is;
    if (findIntersectionEndpoints(a0, a1, s, b0, b1, t, i1, i2, is)) {
      typedef typename DomainTraits<T3>::OneDomain_t Dom_t;
      if (s < 0)
        c[Dim-1] = Dom_t(i2, i1, -is);
      else
        c[Dim-1] = Dom_t(i1, i2, is);
    }
  }
};
template<class T1, class T2, class T3, int Dim>
struct IntersectDomain {
  enum { strided =
    !DomainTraits<T1>::unitStride || !DomainTraits<T2>::unitStride };
  static void intersect(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    IntersectDomainSingle<Dom1_t,Dom2_t,T3,Dim,strided>::intersect(
      DomainTraits<T1>::getDomain(a,Dim-1),
      DomainTraits<T2>::getDomain(b,Dim-1), c);
    IntersectDomain<T1,T2,T3,Dim-1>::intersect(a,b,c);
  }
};
template<class T1, class T2, class T3>
struct IntersectDomain<T1,T2,T3,1> {
  enum { strided =
    !DomainTraits<T1>::unitStride || !DomainTraits<T2>::unitStride };
  static void intersect(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    IntersectDomainSingle<Dom1_t,Dom2_t,T3,1,strided>::intersect(
      DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0), c);
  }
};
template<class T1, class T2>
struct IntersectReturnType {
  typedef typename NewDomain2<T1,T2>::Type_t Combine_t;
  typedef typename
    DomainChangeDim<Combine_t,DomainTraits<T1>::dimensions>::NewType_t Type_t;
};
template<class T1, class T2>
inline typename IntersectReturnType<T1,T2>::Type_t
intersect(const T1 &a, const T2 &b)
{
  typedef typename IntersectReturnType<T1,T2>::Type_t T3;
  PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
  T3 c;
  IntersectDomain<T1,T2,T3,DomainTraits<T1>::dimensions>::intersect(a, b, c);
  return c;
}
template<int TotalDim, int SliceDim> class SliceRange;
template<int TotalDim, int SliceDim>
struct DomainTraits< SliceRange<TotalDim,SliceDim> >
{
  enum { domain = true };
  enum { dimensions = TotalDim,
  sliceDimensions = SliceDim };
  enum { unitStride = false };
  enum { singleValued = false };
  enum { wildcard = false };
  typedef SliceRange<TotalDim,SliceDim> Domain_t;
  typedef SliceRange<TotalDim,SliceDim> NewDomain1_t;
  typedef Range<SliceDim> SliceDomain_t;
  typedef Range<TotalDim> TotalDomain_t;
  typedef Range<1> OneDomain_t;
  typedef Range<1> PointDomain_t;
  static OneDomain_t &getDomain(Domain_t &d, int n) {
    return d.totalDomain()[n];
  }
  static const OneDomain_t &getDomain(const Domain_t &d,int n) {
    return d.totalDomain()[n];
  }
  static OneDomain_t &getSliceDomain(Domain_t &d, int n) {
    return d.sliceDomain()[n];
  }
  static const OneDomain_t &getSliceDomain(const Domain_t &d, int n) {
    return d.sliceDomain()[n];
  }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void cantIgnoreDomain(Domain_t &d, int n) {
    d.cantIgnoreDomain(n);
  }
  static bool getIgnorable(const Domain_t &d, int n) {
    return d.ignorable(n);
  }
  static void setIgnorable(Domain_t &d, int n, bool i) {
    d.ignorable(n) = i;
  }
};
template<class DT>
class SliceDomain
{
public:
  typedef typename DT::Domain_t Domain_t;
  typedef typename DT::SliceDomain_t SliceDomain_t;
  typedef typename DT::TotalDomain_t TotalDomain_t;
  SliceDomain()
    : slice_m(Pooma::NoInit()),
      domain_m(Pooma::NoInit()) {
    PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
    for (int d = 0; d < DT::dimensions; ++d)
      ignore_m[d] = true;
  }
  SliceDomain(const Pooma::NoInit &e)
    : slice_m(e), domain_m(e) {
    PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
    for (int d = 0; d < DT::dimensions; ++d)
      ignore_m[d] = true;
  }
  SliceDomain(const SliceDomain<DT> &sd)
    : slice_m(sd.slice_m),
      domain_m(sd.domain_m) {
    PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
    for (int d = 0; d < DT::dimensions; ++d)
      ignore_m[d] = sd.ignore_m[d];
  }
  template <class DTO>
  SliceDomain(const SliceDomain<DTO> &sd)
    : slice_m(sd.sliceDomain()),
      domain_m(sd.totalDomain()) {
    PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
    for (int d = 0; d < DT::dimensions; ++d)
      ignore_m[d] = sd.ignorable(d);
  }
  Domain_t &unwrap() { return *static_cast<Domain_t *>(this); }
  const Domain_t &unwrap() const {
    return *static_cast<const Domain_t *>(this);
  }
  ~SliceDomain() { }
  const SliceDomain_t &sliceDomain() const { return slice_m; }
  SliceDomain_t &sliceDomain() { return slice_m; }
  const TotalDomain_t &totalDomain() const { return domain_m; }
  TotalDomain_t &totalDomain() { return domain_m; }
  void cantIgnoreDomain(int d)
  {
    ;
    ignore_m[d] = false;
  }
  bool &ignorable(int d)
  {
    ;
    return ignore_m[d];
  }
  bool ignorable(int d) const
  {
    ;
    return ignore_m[d];
  }
  SliceDomain<DT> &operator=(const SliceDomain<DT> &sd) {
    slice_m = sd.slice_m;
    domain_m = sd.domain_m;
    for (int d = 0; d < DT::dimensions; ++d)
      ignore_m[d] = sd.ignore_m[d];
    return *this;
  }
  void setSliceFromTotal() {
    for (int d = 0, dt = 0; d < DT::dimensions; ++d)
      if (!ignore_m[d])
        slice_m[dt++] = domain_m[d];
  }
  template<class Out>
  void print(Out &o) const;
private:
  SliceDomain_t slice_m;
  TotalDomain_t domain_m;
  bool ignore_m[DT::dimensions];
};
template<class DT>
template<class Out>
void SliceDomain<DT>::print(Out &o) const
{
  o << totalDomain() << "==>" << sliceDomain();
}
template <class T1, class T2> inline typename T1::Domain_t operator+(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator+(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
template <class T1, class T2> inline typename T1::Domain_t operator-(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator-(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
template <class T1, class T2> inline typename T1::Domain_t operator*(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator*(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
template <class T1, class T2> inline typename T1::Domain_t operator/(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator/(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
template<class DT>
std::ostream& operator<<(std::ostream &o, const SliceDomain<DT> &dbase) {
  dbase.print(o);
  return o;
}
template<int Dim, int SliceDim>
class SliceRange
  : public SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >
{
public:
  SliceRange() { }
  SliceRange(const Pooma::NoInit &e)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(e) { }
  SliceRange(const SliceRange<Dim,SliceDim> &nd)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(nd) {
  }
  SliceRange(const SliceInterval<Dim,SliceDim> &nd)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(nd) {
  }
  template <class Base, class D1>
  SliceRange(const Base &baseDomain, const D1 &d1)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain1<D1> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1);
  }
  template <class Base, class D1, class D2>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain2<D1,D2> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2);
  }
  template <class Base, class D1, class D2, class D3>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain3<D1,D2,D3> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3);
  }
  template <class Base, class D1, class D2, class D3,
            class D4>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
             const D4 &d4)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain4<D1,D2,D3,D4> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
             const D4 &d4, const D5 &d5)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain5<D1,D2,D3,D4,D5> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5, class D6>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
             const D4 &d4, const D5 &d5, const D6 &d6)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain6<D1,D2,D3,D4,D5,D6> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5, class D6, class D7>
  SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
             const D4 &d4, const D5 &d5, const D6 &d6, const D7 &d7)
    : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain7<D1,D2,D3,D4,D5,D6,D7> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6, d7);
  }
  ~SliceRange() { }
  SliceRange<Dim,SliceDim> &
    operator=(const SliceRange<Dim,SliceDim> &nd) {
      SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >::operator=(nd);
      return *this;
  }
protected:
private:
};
template<class T, int Dim, bool strided>
struct SplitDomainSingle {
  static void split(const T &a, int axis, T &b, T &c) {
    typedef typename DomainTraits<T>::Element_t E1_t;
    typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
    if (axis != (Dim - 1)) {
      b[Dim-1] = a[Dim-1];
      c[Dim-1] = a[Dim-1];
    } else if (a[Dim-1].length() < 2) {
      b[Dim-1] = a[Dim-1];
    } else {
      E1_t a0 = a[Dim-1].first();
      E1_t a1 = a[Dim-1].last();
      E1_t mid = a0 + a[Dim-1].length()/2;
      b[Dim-1] = OneDomain_t(a0, mid-1);
      c[Dim-1] = OneDomain_t(mid, a1);
    }
  }
  static void split(const T &a, int axis, int leftLength, T &b, T &c) {
    typedef typename DomainTraits<T>::Element_t E1_t;
    typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
    if (axis != (Dim - 1)) {
      b[Dim-1] = a[Dim-1];
      c[Dim-1] = a[Dim-1];
    } else if (a[Dim-1].length() < 2) {
      b[Dim-1] = a[Dim-1];
    } else {
      E1_t a0 = a[Dim-1].first();
      E1_t a1 = a[Dim-1].last();
      E1_t mid = a0 + leftLength;
      b[Dim-1] = OneDomain_t(a0, mid-1);
      c[Dim-1] = OneDomain_t(mid, a1);
    }
  }
  static void split(const T &a, T &b, T &c) { split(a, Dim-1, b, c); }
};
template<class T, int Dim>
struct SplitDomainSingle<T,Dim,true> {
  static void split(const T &a, int axis, T &b, T &c) {
    typedef typename DomainTraits<T>::Element_t E1_t;
    typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
    if (axis != (Dim - 1)) {
      b[Dim-1] = a[Dim-1];
      c[Dim-1] = a[Dim-1];
    } else if (a[Dim-1].length() < 2) {
      b[Dim-1] = a[Dim-1];
    } else {
      E1_t a0 = a[Dim-1].first();
      E1_t a1 = a[Dim-1].last();
      E1_t s = a[Dim-1].stride();
      E1_t mid = a0 + (a[Dim-1].length()/2 * s);
      b[Dim-1] = OneDomain_t(a0, mid - s, s);
      c[Dim-1] = OneDomain_t(mid, a1, s);
    }
  }
  static void split(const T &a, int axis, int leftLength, T &b, T &c) {
    typedef typename DomainTraits<T>::Element_t E1_t;
    typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
    if (axis != (Dim - 1)) {
      b[Dim-1] = a[Dim-1];
      c[Dim-1] = a[Dim-1];
    } else if (a[Dim-1].length() < 2) {
      b[Dim-1] = a[Dim-1];
    } else {
      E1_t a0 = a[Dim-1].first();
      E1_t a1 = a[Dim-1].last();
      E1_t s = a[Dim-1].stride();
      E1_t mid = a0 + (leftLength * s);
      b[Dim-1] = OneDomain_t(a0, mid - s, s);
      c[Dim-1] = OneDomain_t(mid, a1, s);
    }
  }
  static void split(const T &a, T &b, T &c) { split(a, Dim-1, b, c); }
};
template<int Dim, bool strided>
struct SplitDomainSingle<int,Dim,strided> {
  static void split(int a, int, int &b, int &c) {
    b = a;
    c = 0;
  }
  static void split(int a, int, int, int &b, int &c) {
    b = a;
    c = 0;
  }
  static void split(int a, int &b, int &c) {
    b = a;
    c = 0;
  }
};
template<class T, int Dim>
struct SplitDomain {
  enum { strided = !DomainTraits<T>::unitStride };
  static void split(const T &a, T &b, T &c) {
    SplitDomainSingle<T,Dim,strided>::split(a, b, c);
    SplitDomain<T,Dim-1>::split(a, b, c);
  }
  static void split(const T &a, int axis, T &b, T &c) {
    SplitDomainSingle<T,Dim,strided>::split(a, axis, b, c);
    SplitDomain<T,Dim-1>::split(a, axis, b, c);
  }
  static void split(const T &a, int axis, int leftLength, T &b, T &c) {
    SplitDomainSingle<T,Dim,strided>::split(a, axis, leftLength, b, c);
    SplitDomain<T,Dim-1>::split(a, axis, leftLength, b, c);
  }
};
template<class T>
struct SplitDomain<T,1> {
  enum { strided = !DomainTraits<T>::unitStride };
  static void split(const T &a, T &b, T &c) {
    SplitDomainSingle<T,1,strided>::split(a, b, c);
  }
  static void split(const T &a, int axis, T &b, T &c) {
    SplitDomainSingle<T,1,strided>::split(a, axis, b, c);
  }
  static void split(const T &a, int axis, int leftLength, T &b, T &c) {
    SplitDomainSingle<T,1,strided>::split(a, axis, leftLength, b, c);
  }
};
template<class T>
inline void split(const T &a, T &b, T &c)
{
  SplitDomain<T,DomainTraits<T>::dimensions>::split(a, b, c);
}
template<class T>
inline void split(const T &a, int axis, T &b, T &c)
{
  SplitDomain<T,DomainTraits<T>::dimensions>::split(a, axis, b, c);
}
template<class T>
inline void split(const T &a, int axis, int leftLength, T &b, T &c)
{
  SplitDomain<T,DomainTraits<T>::dimensions>::split(a, axis, leftLength, b, c);
}
template<class T1, class T2, bool strided>
struct TouchesDomainSingle {
  static bool touches(const T1 &a, const T2 &b) {
    return (a.min() <= b.max() && a.max() >= b.min());
  }
};
template<class T1, class T2>
struct TouchesDomainSingle<T1,T2,true> {
  static bool touches(const T1 &a, const T2 &b) {
    bool quicktest = TouchesDomainSingle<T1,T2,false>::touches(a, b);
    if (!quicktest || a.stride() == 1 || a.stride() == (-1) ||
 b.stride() == 1 || b.stride() == (-1)) {
      return quicktest;
    }
    int endpoint = 0;
    return findLeftCommonEndpoint(a.min(), a.max(), a.stride(),
      b.min(), b.max(), b.stride(), endpoint);
  }
};
template<class T1, class T2, int Dim>
struct TouchesDomain {
  enum { strided =
    !DomainTraits<T1>::unitStride && !DomainTraits<T2>::unitStride };
  static bool touches(const T1 &a, const T2 &b) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    return TouchesDomainSingle<Dom1_t,Dom2_t,strided>::touches(
      DomainTraits<T1>::getDomain(a,Dim-1),
      DomainTraits<T2>::getDomain(b,Dim-1)) &&
      TouchesDomain<T1,T2,Dim-1>::touches(a,b);
  }
};
template<class T1, class T2>
struct TouchesDomain<T1,T2,1> {
  enum { strided =
    !DomainTraits<T1>::unitStride && !DomainTraits<T2>::unitStride };
  static bool touches(const T1 &a, const T2 &b) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    return TouchesDomainSingle<Dom1_t,Dom2_t,strided>::touches(
      DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0));
  }
};
template<class T1, class T2, int Dim1, int Dim2>
inline bool touches2(const T1 &, const T2 &, const WrappedInt<Dim1> &,
  const WrappedInt<Dim2> &)
{
  return false;
}
template<class T1, class T2, int Dim>
inline bool touches2(const T1 &a, const T2 &b, const WrappedInt<Dim> &,
  const WrappedInt<Dim> &)
{
  return TouchesDomain<T1,T2,Dim>::touches(a, b);
}
template<class T1, class T2>
inline bool touches(const T1 &a, const T2 &b)
{
  if (a.empty() || b.empty())
    return false;
  else
    return touches2(a, b, WrappedInt<DomainTraits<T1>::dimensions>(),
      WrappedInt<DomainTraits<T2>::dimensions>());
}
#include <list>
template<class Dom, class T>
class DomainMapNode : public Pooled<DomainMapNode<Dom,T> >
{
public:
  typedef Dom Domain_t;
  typedef T Data_t;
  typedef std::pair<Domain_t,Data_t> Value_t;
  typedef std::list<Value_t> List_t;
  typedef DomainMapNode<Dom,T> Node_t;
  typedef typename List_t::iterator iterator;
  DomainMapNode(const Domain_t &d, Node_t *p = 0)
    : domain_m(d), left_m(0), right_m(0), parent_m(p) {
  }
  ~DomainMapNode() {
    if (left_m != 0)
      delete left_m;
    if (right_m != 0)
      delete right_m;
  }
  const Domain_t &domain() const { return domain_m; }
  iterator begin() { return list_m.begin(); }
  iterator end() { return list_m.end(); }
  void insert(const Value_t &v) {
    ;
    if (left_m == 0)
      {
 Domain_t leftdom, rightdom;
 split(domain_m, leftdom, rightdom);
 left_m = new Node_t(leftdom, this);
 right_m = new Node_t(rightdom, this);
      }
    if (contains(v.first, domain_m))
      {
 list_m.push_back(v);
      }
    else if (contains(left_m->domain_m, v.first))
      {
 left_m->insert(v);
      }
    else if (contains(right_m->domain_m, v.first))
      {
 right_m->insert(v);
      }
    else
      {
 list_m.push_back(v);
      }
  }
  Node_t *nextRightNode() {
    Node_t *y, *p = this;
    if (p->right_m != 0) {
      p = p->right_m;
      while (p->left_m != 0)
        p = p->left_m;
    } else {
      for (y=p->parent_m; y != 0 && p == y->right_m; y=y->parent_m)
        p = y;
      p = y;
    }
    return p;
  }
  Node_t *nextRightTouchNode(const Domain_t &d) {
    Node_t *p = this;
    Node_t *y = right_m;
    if (y != 0 && touches(d, y->domain_m)) {
      p = y;
      for (y=y->left_m; y != 0 && touches(d, y->domain_m); y=y->left_m)
        p = y;
    } else {
      for (y=p->parent_m; y != 0 && p == y->right_m; y=y->parent_m)
        p = y;
      p = y;
    }
    return p;
  }
  Node_t *findLeftNode() {
    Node_t *p = this;
    while (p->left_m != 0)
      p = p->left_m;
    while (p != 0 && p->begin() == p->end())
      p = p->nextRightNode();
    return p;
  }
  Node_t *findLeftTouchNode(const Domain_t &d) {
    Node_t *y, *p = this;
    for (y=p->left_m; y != 0 && touches(d, y->domain_m); y=y->left_m)
      p = y;
    return p;
  }
private:
  Domain_t domain_m;
  Node_t *left_m, *right_m, *parent_m;
  List_t list_m;
};
template<class Dom, class T>
class DomainMapIterator
{
public:
  typedef Dom Domain_t;
  typedef DomainMapNode<Dom,T> Node_t;
  typedef typename Node_t::Data_t Value_t;
  typedef typename Node_t::iterator NodeIter_t;
  DomainMapIterator() : node_m(0) { }
  DomainMapIterator(Node_t *n, NodeIter_t i) : node_m(n), iter_m(i) { }
  ~DomainMapIterator() { }
  Node_t *getNode() const { return node_m; }
  NodeIter_t getIter() const { return iter_m; }
  bool operator==(const DomainMapIterator<Dom,T> &dmi) {
    return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
  }
  bool operator!=(const DomainMapIterator<Dom,T> &dmi) {
    return !(*this == dmi);
  }
  Value_t &operator*() {
    ;
    return (*iter_m).second;
  }
  Domain_t &domain() {
    ;
    return (*iter_m).first;
  }
  DomainMapIterator<Dom,T> &operator++() {
    ;
    if ((++iter_m) == node_m->end()) {
      do {
        node_m = node_m->nextRightNode();
      } while (node_m != 0 && (iter_m=node_m->begin()) == node_m->end());
    }
    return *this;
  }
private:
  Node_t *node_m;
  NodeIter_t iter_m;
};
template<class Dom, class T>
class DomainMapConstIterator
{
public:
  typedef Dom Domain_t;
  typedef DomainMapNode<Dom,T> Node_t;
  typedef typename Node_t::Data_t Value_t;
  typedef typename Node_t::iterator NodeIter_t;
  DomainMapConstIterator() : node_m(0) { }
  DomainMapConstIterator(Node_t *n, NodeIter_t i)
    : node_m(n), iter_m(i) { }
  DomainMapConstIterator(const DomainMapIterator<Dom,T> &dmi)
    : node_m(dmi.getNode()), iter_m(dmi.getIter()) { }
  ~DomainMapConstIterator() { }
  bool operator==(const DomainMapConstIterator<Dom,T> &dmi) {
    return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
  }
  bool operator!=(const DomainMapConstIterator<Dom,T> &dmi) {
    return !(*this == dmi);
  }
  Value_t operator*() {
    ;
    return (*iter_m).second;
  }
  Domain_t domain() {
    ;
    return (*iter_m).first;
  }
  DomainMapConstIterator<Dom,T> &operator++() {
    ;
    if ((++iter_m) == node_m->end()) {
      do {
        node_m = node_m->nextRightNode();
      } while (node_m != 0 && (iter_m=node_m->begin()) == node_m->end());
    }
    return *this;
  }
private:
  Node_t *node_m;
  NodeIter_t iter_m;
};
template<class Dom, class T>
class DomainMapTouchIterator
{
public:
  typedef Dom Domain_t;
  typedef DomainMapNode<Dom,T> Node_t;
  typedef typename Node_t::Data_t Value_t;
  typedef typename Node_t::iterator NodeIter_t;
  DomainMapTouchIterator() : node_m(0) { }
  DomainMapTouchIterator(Node_t *n, NodeIter_t i, const Domain_t &d)
    : node_m(n), iter_m(i), domain_m(d) { }
  ~DomainMapTouchIterator() { }
  bool operator==(const DomainMapTouchIterator<Dom,T> &dmi) {
    return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
  }
  bool operator!=(const DomainMapTouchIterator<Dom,T> &dmi) {
    return !(*this == dmi);
  }
  Value_t &operator*() {
    ;
    return (*iter_m).second;
  }
  Domain_t &domain() {
    ;
    return (*iter_m).first;
  }
  DomainMapTouchIterator<Dom,T> &operator++() {
    ;
    while ((++iter_m) != node_m->end()) {
      if (touches(domain_m, (*iter_m).first))
        return *this;
    }
    do {
      if ((node_m = node_m->nextRightTouchNode(domain_m)) != 0)
        for (iter_m = node_m->begin(); iter_m != node_m->end(); ++iter_m)
          if (touches(domain_m, (*iter_m).first))
            return *this;
    } while (node_m != 0);
    return *this;
  }
private:
  Node_t *node_m;
  NodeIter_t iter_m;
  Domain_t domain_m;
};
template<class Dom, class T>
class DomainMap
{
public:
  typedef Dom Domain_t;
  typedef Dom key_type;
  typedef T Data_t;
  typedef T mapped_type;
  typedef std::pair<Domain_t,Data_t> Value_t;
  typedef std::pair<Domain_t,Data_t> value_type;
  typedef DomainMapIterator<Domain_t,Data_t> iterator;
  typedef DomainMapConstIterator<Domain_t,Data_t> const_iterator;
  typedef DomainMapTouchIterator<Domain_t,Data_t> touch_iterator;
  typedef std::pair<touch_iterator,touch_iterator> Touch_t;
  typedef std::pair<touch_iterator,touch_iterator> touch_type;
  typedef long Size_t;
  typedef long size_type;
  DomainMap() : size_m(0), root_m(0) { }
  DomainMap(const Domain_t &d) : size_m(0), root_m(0) {
    initialize(d);
  }
  void initialize(const Domain_t &d) {
    ;
    root_m = new Node_t(d);
  }
  ~DomainMap() {
    if (root_m != 0)
      delete root_m;
  }
  iterator begin() { return left_m; }
  iterator end() { return iterator(); }
  const_iterator begin() const { return const_iterator(left_m); }
  const_iterator end() const { return const_iterator(); }
  Size_t size() const { return size_m; }
  Touch_t touch(const Domain_t &d) const {
    Node_t *p = root_m;
    if (p != 0)
    {
      p = p->findLeftTouchNode(d);
      do
      {
 for (NodeIter_t a = p->begin(); a != p->end(); ++a)
   if (touches(d, (*a).first))
     return Touch_t(touch_iterator(p, a, d), touch_iterator());
 p = p->nextRightTouchNode(d);
      } while (p != 0);
    }
    return Touch_t(touch_iterator(), touch_iterator());
  }
  void insert(const Value_t &v) {
    ;
    root_m->insert(v);
    size_m++;
  }
  void update() {
    Node_t *leftnode;
    if (root_m != 0 && size_m > 0 && (leftnode=root_m->findLeftNode()) != 0)
      left_m = iterator(leftnode, leftnode->begin());
    else
      left_m = iterator();
  }
  void clear() {
    if (root_m != 0) {
      Node_t *newroot = new Node_t(root_m->domain());
      delete root_m;
      root_m = newroot;
      size_m = 0;
      update();
    }
  }
  void zap() {
    if (root_m != 0)
      delete root_m;
    size_m = 0;
    root_m = 0;
  }
  template<class Out>
  void print(Out &o) const;
  void print() const;
private:
  typedef DomainMapNode<Domain_t,Data_t> Node_t;
  typedef typename Node_t::iterator NodeIter_t;
  Size_t size_m;
  Node_t *root_m;
  iterator left_m;
  DomainMap(const DomainMap<Domain_t,Data_t> &);
  DomainMap<Domain_t,Data_t> &operator=(const DomainMap<Domain_t,Data_t> &);
};
template<class Dom, class T>
template<class Out>
void DomainMap<Dom, T>::print(Out &o) const
{
  if (size() < 1 || root_m == 0)
    {
      o << "DomainMap: empty.";
    }
  else
    {
      o << "DomainMap: Total domain = " << root_m->domain();
      o << ", touching domains:\n";
      Touch_t touchiters = touch(root_m->domain());
      while (touchiters.first != touchiters.second)
 {
   o << "  " << touchiters.first.domain() << " ==> ";
   o << *(touchiters.first) << "\n";
   ++(touchiters.first);
 }
    }
}
template<class Dom, class T>
void DomainMap<Dom, T>::print() const
{
  if (size() < 1 || root_m == 0)
    {
      std::cout << "DomainMap: empty.";
    }
  else
    {
      std::cout << "DomainMap: Total domain = " << root_m->domain();
      std::cout << ", touching domains:\n";
      Touch_t touchiters = touch(root_m->domain());
      while (touchiters.first != touchiters.second)
 {
   std::cout << "  " << touchiters.first.domain() << " ==> ";
   std::cout << *(touchiters.first) << "\n";
   ++(touchiters.first);
 }
    }
}
template <class Dom, class T>
std::ostream &operator<<(std::ostream &o, const DomainMap<Dom, T> &dmap)
{
  dmap.print(o);
  return o;
}
template <class T>
class ConstDerefIterator;
template <class T>
class DerefIterator
{
public:
  typedef T Value_t;
  typedef std::vector<T*> List_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef std::random_access_iterator_tag iterator_category;
  typedef Value_t value_type;
  typedef ptrdiff_t difference_type;
  typedef Value_t* pointer;
  typedef Value_t& reference;
  friend class ConstDerefIterator<T>;
  friend iterator operator+ (const difference_type n, const iterator &iter)
  {
    return iterator(iter.p_m + n);
  }
protected:
  typename List_t::iterator p_m;
public:
  inline DerefIterator() { }
  inline DerefIterator(typename List_t::iterator x) : p_m(x) { }
  inline reference operator*() const {
    return **p_m;
  }
  inline pointer operator->() const {
    return *p_m;
  }
  inline iterator &operator++() {
    ++p_m;
    return *this;
  }
  inline iterator operator++(int) {
    iterator tmp = *this;
    ++p_m;
    return tmp;
  }
  inline iterator &operator--() {
    --p_m;
    return *this;
  }
  inline iterator operator--(int) {
    iterator tmp = *this;
    --p_m;
    return tmp;
  }
  inline iterator &operator+=(const difference_type i) {
    p_m += i;
    return *this;
  }
  inline iterator &operator-=(const difference_type i) {
    p_m -= i;
    return *this;
  }
  inline iterator operator+(const difference_type i) const {
    return iterator(p_m + i);
  }
  inline iterator operator-(const difference_type i) const {
    return iterator(p_m - i);
  }
  inline difference_type operator-(const iterator &x) const {
    return p_m - x.p_m;
  }
  inline difference_type operator-(const const_iterator &x) const {
    return p_m - x.p_m;
  }
  inline reference operator[](const difference_type i) const {
    return **(p_m + i);
  }
  inline bool operator==(const iterator &x) const {
    return p_m == x.p_m;
  }
  inline bool operator==(const const_iterator &x) const {
    return p_m == x.p_m;
  }
  inline bool operator<(const iterator &x) const {
    return p_m < x.p_m;
  }
  inline bool operator<(const const_iterator &x) const {
    return p_m < x.p_m;
  }
  inline bool operator!= (const iterator &y) const
  { return ! (*this == y); }
  inline bool operator> (const iterator &y) const
  { return (y < *this); }
  inline bool operator<= (const iterator &y) const
  { return ! (y < *this); }
  inline bool operator>= (const iterator &y) const
  { return ! (*this < y); }
  inline bool operator!= (const const_iterator &y) const
  { return ! (*this == y); }
  inline bool operator> (const const_iterator &y) const
  { return (y < *this); }
  inline bool operator<= (const const_iterator &y) const
  { return ! (y < *this); }
  inline bool operator>= (const const_iterator &y) const
  { return ! (*this < y); }
};
template <class T>
class ConstDerefIterator
{
public:
  typedef T Value_t;
  typedef std::vector<T*> List_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef std::random_access_iterator_tag iterator_category;
  typedef Value_t value_type;
  typedef ptrdiff_t difference_type;
  typedef const Value_t* pointer;
  typedef const Value_t& reference;
  friend class DerefIterator<T>;
  friend const_iterator operator+ (const difference_type n,
    const const_iterator &iter)
  {
    return const_iterator(iter.p_m + n);
  }
protected:
  typename List_t::const_iterator p_m;
public:
  inline ConstDerefIterator() { }
  inline ConstDerefIterator(const typename List_t::const_iterator &x) : p_m(x) { }
  inline ConstDerefIterator(const typename List_t::iterator &x) : p_m(x) { }
  inline ConstDerefIterator(const iterator &x) : p_m(x.p_m) { }
  inline ConstDerefIterator(const const_iterator &x) : p_m(x.p_m) { }
  inline reference operator*() const {
    return **p_m;
  }
  inline pointer operator->() const {
    return *p_m;
  }
  inline const_iterator &operator++() {
    ++p_m;
    return *this;
  }
  inline const_iterator operator++(int) {
    const_iterator tmp = *this;
    ++p_m;
    return tmp;
  }
  inline const_iterator &operator--() {
    --p_m;
    return *this;
  }
  inline const_iterator operator--(int) {
    const_iterator tmp = *this;
    --p_m;
    return tmp;
  }
  inline const_iterator &operator+=(const difference_type i) {
    p_m += i;
    return *this;
  }
  inline const_iterator &operator-=(const difference_type i) {
    p_m -= i;
    return *this;
  }
  inline const_iterator operator+(const difference_type i) const {
    return const_iterator(p_m + i);
  }
  inline const_iterator operator-(const difference_type i) const {
    return const_iterator(p_m - i);
  }
  inline difference_type operator-(const const_iterator &x) const {
    return p_m - x.p_m;
  }
  inline difference_type operator-(const iterator &x)
    const {
    return p_m - x.p_m;
  }
  inline reference operator[](const difference_type i) const {
    return **(p_m + i);
  }
  inline bool operator==(const const_iterator &x) const {
    return p_m == x.p_m;
  }
  inline bool operator==(const iterator &x) const {
    return p_m == x.p_m;
  }
  inline bool operator<(const const_iterator &x) const {
    return p_m < x.p_m;
  }
  inline bool operator<(const iterator &x) const {
    return p_m < x.p_m;
  }
  inline bool operator!= (const const_iterator &y) const
  { return ! (*this == y); }
  inline bool operator> (const const_iterator &y) const
  { return (y < *this); }
  inline bool operator<= (const const_iterator &y) const
  { return ! (y < *this); }
  inline bool operator>= (const const_iterator &y) const
  { return ! (*this < y); }
  inline bool operator!= (const iterator &y) const
  { return ! (*this == y); }
  inline bool operator> (const iterator &y) const
  { return (y < *this); }
  inline bool operator<= (const iterator &y) const
  { return ! (y < *this); }
  inline bool operator>= (const iterator &y) const
  { return ! (*this < y); }
};
template<int Dim, int Dim2>
class ViewIndexer
{
public:
  typedef ViewIndexer<Dim, Dim2> This_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim2> BaseDomain_t;
  typedef Loc<Dim2> Mask_t;
  ViewIndexer() { }
  template<class DT>
  ViewIndexer(const SliceDomain<DT> &dom)
  : domain_m(Pooma::NoInit()), baseDomain_m(dom.totalDomain())
  {
    PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
    PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
    int dt, d;
    const typename DT::TotalDomain_t &domain = dom.totalDomain();
    for (d = 0, dt = 0; dt < Dim2; ++dt)
      {
        if (!dom.ignorable(dt))
          {
            ;
            offset_m[d] = domain[dt].first();
            stride_m[d] = domain[dt].stride();
            domain_m[d] = Interval<1>(domain[dt].length());
            ind_m[d] = dt;
            ++d;
          }
        else
          {
            ;
            mask_m[dt] = domain[dt].first();
          }
      }
  }
  template<class DT>
  ViewIndexer(const ViewIndexer<Dim, Dim2> &orig,
    const Domain<Dim, DT> &dom)
  : domain_m(Pooma::NoInit()),
    baseDomain_m(Pooma::NoInit()),
    mask_m(orig.mask())
  {
    baseDomain_m = orig.baseDomain();
    const typename DT::Domain_t &domain = dom.unwrap();
    for (int d = 0; d < Dim; ++d)
      {
        offset_m[d] = orig.offset(d) + orig.stride(d) *
          domain[d].first();
        stride_m[d] = orig.stride(d) * domain[d].stride();
        domain_m[d] = Interval<1>(domain[d].length());
        ind_m[d] = orig.indirection(d);
      }
    localToBase(domain_m, baseDomain_m);
  }
  template<int OrigDim, class DT>
  ViewIndexer(const ViewIndexer<OrigDim, Dim2> &orig,
    const SliceDomain<DT> &dom)
  : domain_m(Pooma::NoInit()),
    baseDomain_m(orig.baseDomain()), mask_m(orig.mask())
  {
    PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
    int dt, d;
    const typename DT::TotalDomain_t &domain = dom.totalDomain();
    for (d = 0, dt = 0; dt < OrigDim; ++dt)
      {
        if (!dom.ignorable(dt))
          {
            ;
            offset_m[d] = orig.offset(dt) + orig.stride(dt) *
              domain[dt].first();
            stride_m[d] = orig.stride(dt) * domain[dt].stride();
            domain_m[d] = Interval<1>(domain[dt].length());
            ind_m[d] = orig.indirection(dt);
            baseDomain_m[ind_m[d]] = Range<1>(
              offset_m[d],
              offset_m[d] + stride_m[d] * domain_m[d].last(),
              stride_m[d]);
            ++d;
          }
        else
          {
            ;
            int m = orig.offset(dt) + orig.stride(dt) *
              domain[dt].first();
            mask_m[orig.indirection(dt)] = m;
            baseDomain_m[orig.indirection(dt)] =
              Range<1>(m, m, 1);
          }
      }
  }
  ViewIndexer(const This_t &model)
  : domain_m(model.domain()), baseDomain_m(model.baseDomain()),
    mask_m(model.mask())
  {
    for (int d = 0; d < Dim; d++)
      {
        ind_m[d] = model.indirection(d);
        offset_m[d] = model.offset(d);
        stride_m[d] = model.stride(d);
      }
  }
  This_t &operator=(const This_t &rhs)
  {
    domain_m = rhs.domain();
    baseDomain_m = rhs.baseDomain();
    mask_m = rhs.mask();
    for (int d = 0; d < Dim; d++)
      {
        ind_m[d] = rhs.indirection(d);
        offset_m[d] = rhs.offset(d);
        stride_m[d] = rhs.stride(d);
      }
    return *this;
  }
  const Domain_t &domain() const { return domain_m; }
  const Domain_t &innerDomain() const { return domain_m; }
  const BaseDomain_t &baseDomain() const { return baseDomain_m; }
  int indirection(int i) const { return ind_m[i]; }
  const Mask_t &mask() const { return mask_m; }
  int offset(int i) const { return offset_m[i]; }
  int stride(int i) const { return stride_m[i]; }
  void translate(const Loc<Dim> &loc, Loc<Dim2> &oloc) const
  {
    oloc = mask_m;
    for (int d = 0; d < Dim; d++)
      oloc[ind_m[d]] = Loc<1>(offset_m[d] + stride_m[d] * loc[d].first());
  }
  void translate(int i0, Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
  }
  void translate(int i0, int i1, Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
  }
  void translate(int i0, int i1, int i2,
    Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
    loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
  }
  void translate(int i0, int i1, int i2, int i3,
    Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
    loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
    loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
    loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
    loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
    loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, int i5, Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
    loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
    loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
    loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
    loc[ind_m[5]] = offset_m[5] + stride_m[5] * i5;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, int i5, int i6, Loc<Dim2> &loc) const
  {
    loc = mask_m;
    loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
    loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
    loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
    loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
    loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
    loc[ind_m[5]] = offset_m[5] + stride_m[5] * i5;
    loc[ind_m[6]] = offset_m[6] + stride_m[6] * i6;
  }
  template<class DT>
  BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
    BaseDomain_t &base) const
  {
    base = baseDomain_m;
    const typename DT::Domain_t &local = dlocal.unwrap();
    for (int d = 0; d < Dim; d++)
      {
        base[ind_m[d]] = Range<1>(
          offset_m[d] + stride_m[d] * local[d].first(),
          offset_m[d] + stride_m[d] * local[d].last(),
          stride_m[d] * local[d].stride());
      }
    return base;
  }
  template<class DT>
  SliceRange<Dim2, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
    SliceRange<Dim2, Dim> &base) const
  {
    base.totalDomain() = baseDomain_m;
    const typename DT::Domain_t &local = dlocal.unwrap();
    for (int d = 0; d < Dim; d++)
      {
        Range<1> r(
          offset_m[d] + stride_m[d] * local[d].first(),
          offset_m[d] + stride_m[d] * local[d].last(),
          stride_m[d] * local[d].stride());
        base.totalDomain()[ind_m[d]] = r;
        base.sliceDomain()[d] = r;
        base.cantIgnoreDomain(ind_m[d]);
      }
    return base;
  }
  Interval<Dim> &baseToLocal(const BaseDomain_t &base,
    Interval<Dim> &local) const
  {
    int j;
    for (int d = 0; d < Dim; d++)
      {
        j = ind_m[d];
        local[d] = Interval<1>(
          (base[j].first() - offset_m[d]) / stride_m[d],
          (base[j].last() - offset_m[d]) / stride_m[d]);
        ;
      }
    return local;
  }
  Range<Dim> &baseToLocal(const BaseDomain_t &base,
    Range<Dim> &local) const
  {
    int j;
    for (int d = 0; d < Dim; d++)
      {
        j = ind_m[d];
        local[d] = Range<1>(
          (base[j].first() - offset_m[d]) / stride_m[d],
          (base[j].last() - offset_m[d]) / stride_m[d],
          base[j].stride() / stride_m[d]);
      }
    return local;
  }
  Interval<Dim> &baseToLocalInterval(const Interval<Dim2> &base,
          Interval<Dim> &local) const
  {
    int j;
    for (int d = 0; d < Dim; d++)
    {
      j = ind_m[d];
      local[d] = Interval<1>((base[j].first() - offset_m[d]) / stride_m[d],
        (base[j].last() - offset_m[d]) / stride_m[d]);
      ;
      ;
    }
    return local;
  }
private:
  Domain_t domain_m;
  BaseDomain_t baseDomain_m;
  int stride_m[Dim], offset_m[Dim];
  int ind_m[Dim];
  Mask_t mask_m;
};
template<int Dim>
class ViewIndexer<Dim, Dim>
{
public:
  typedef ViewIndexer<Dim, Dim> This_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim> BaseDomain_t;
  typedef Loc<Dim> Mask_t;
  ViewIndexer() { }
  template<class DT>
  ViewIndexer(const Domain<Dim, DT> &dom)
  : domain_m(Pooma::NoInit()), baseDomain_m(dom.unwrap())
  {
    const typename DT::Domain_t &domain = dom.unwrap();
    for (int d = 0; d < Dim; ++d)
      {
        offset_m[d] = domain[d].first();
        stride_m[d] = domain[d].stride();
        domain_m[d] = Interval<1>(domain[d].length());
      }
  }
  template<class DT>
  ViewIndexer(const ViewIndexer<Dim, Dim> &orig,
    const Domain<Dim, DT> &dom)
  : domain_m(Pooma::NoInit()),
    baseDomain_m(dom.unwrap()),
    mask_m(orig.mask())
  {
    const typename DT::Domain_t &domain = dom.unwrap();
    for (int d = 0; d < Dim; ++d)
      {
        offset_m[d] = orig.offset(d) + orig.stride(d) *
          domain[d].first();
        stride_m[d] = orig.stride(d) * domain[d].stride();
        domain_m[d] = Interval<1>(domain[d].length());
      }
    localToBase(domain_m, baseDomain_m);
}
  ViewIndexer(const This_t &model)
  : domain_m(model.domain()), baseDomain_m(model.baseDomain()),
    mask_m(model.mask())
  {
    for (int d = 0; d < Dim; d++)
      {
        offset_m[d] = model.offset(d);
        stride_m[d] = model.stride(d);
      }
  }
  This_t &operator=(const This_t &rhs)
  {
    domain_m = rhs.domain();
    baseDomain_m = rhs.baseDomain();
    mask_m = rhs.mask();
    for (int d = 0; d < Dim; d++)
      {
        offset_m[d] = rhs.offset(d);
        stride_m[d] = rhs.stride(d);
      }
    return *this;
  }
  const Domain_t &domain() const { return domain_m; }
  const Domain_t &innerDomain() const { return domain_m; }
  const BaseDomain_t &baseDomain() const { return baseDomain_m; }
  int indirection(int i) const { return i; }
  const Mask_t &mask() const { return mask_m; }
  int offset(int i) const { return offset_m[i]; }
  int stride(int i) const { return stride_m[i]; }
  void translate(const Loc<Dim> &loc, Loc<Dim> &oloc) const
  {
    for (int d = 0; d < Dim; d++)
      oloc[d] = Loc<1>(offset_m[d] + stride_m[d] * loc[d].first());
  }
  void translate(int i0, Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
  }
  void translate(int i0, int i1, Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
  }
  void translate(int i0, int i1, int i2,
    Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
    loc[2] = offset_m[2] + stride_m[2] * i2;
  }
  void translate(int i0, int i1, int i2, int i3,
    Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
    loc[2] = offset_m[2] + stride_m[2] * i2;
    loc[3] = offset_m[3] + stride_m[3] * i3;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
    loc[2] = offset_m[2] + stride_m[2] * i2;
    loc[3] = offset_m[3] + stride_m[3] * i3;
    loc[4] = offset_m[4] + stride_m[4] * i4;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, int i5, Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
    loc[2] = offset_m[2] + stride_m[2] * i2;
    loc[3] = offset_m[3] + stride_m[3] * i3;
    loc[4] = offset_m[4] + stride_m[4] * i4;
    loc[5] = offset_m[5] + stride_m[5] * i5;
  }
  void translate(int i0, int i1, int i2, int i3,
    int i4, int i5, int i6, Loc<Dim> &loc) const
  {
    loc[0] = offset_m[0] + stride_m[0] * i0;
    loc[1] = offset_m[1] + stride_m[1] * i1;
    loc[2] = offset_m[2] + stride_m[2] * i2;
    loc[3] = offset_m[3] + stride_m[3] * i3;
    loc[4] = offset_m[4] + stride_m[4] * i4;
    loc[5] = offset_m[5] + stride_m[5] * i5;
    loc[6] = offset_m[6] + stride_m[6] * i6;
  }
  template<class DT>
  BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
    BaseDomain_t &base) const
  {
    const typename DT::Domain_t &local = dlocal.unwrap();
    for (int d = 0; d < Dim; d++)
      {
        base[d] = Range<1>(
          offset_m[d] + stride_m[d] * local[d].first(),
          offset_m[d] + stride_m[d] * local[d].last(),
          stride_m[d] * local[d].stride());
      }
    return base;
  }
  template<class DT>
  SliceRange<Dim, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
    SliceRange<Dim, Dim> &base) const
  {
    base.totalDomain() = baseDomain_m;
    const typename DT::Domain_t &local = dlocal.unwrap();
    for (int d = 0; d < Dim; d++)
      {
        Range<1> r(
          offset_m[d] + stride_m[d] * local[d].first(),
          offset_m[d] + stride_m[d] * local[d].last(),
          stride_m[d] * local[d].stride());
        base.totalDomain()[d] = r;
        base.sliceDomain()[d] = r;
        base.cantIgnoreDomain(d);
      }
    return base;
  }
  Interval<Dim> &baseToLocal(const BaseDomain_t &base,
    Interval<Dim> &local) const
  {
    for (int d = 0; d < Dim; d++)
      {
        local[d] = Interval<1>(
          (base[d].first() - offset_m[d]) / stride_m[d],
          (base[d].last() - offset_m[d]) / stride_m[d]);
        ;
      }
    return local;
  }
  Range<Dim> &baseToLocal(const BaseDomain_t &base,
    Range<Dim> &local) const
  {
    for (int d = 0; d < Dim; d++)
      {
        local[d] = Range<1>(
          (base[d].first() - offset_m[d]) / stride_m[d],
          (base[d].last() - offset_m[d]) / stride_m[d],
          base[d].stride() / stride_m[d]);
      }
    return local;
  }
  Interval<Dim> &baseToLocalInterval(const Interval<Dim> &base,
         Interval<Dim> &local) const
  {
    for (int d = 0; d < Dim; d++)
    {
      local[d] = Interval<1>((base[d].first() - offset_m[d]) / stride_m[d],
        (base[d].last() - offset_m[d]) / stride_m[d]);
      ;
      ;
    }
    return local;
  }
private:
  Domain_t domain_m;
  BaseDomain_t baseDomain_m;
  int stride_m[Dim], offset_m[Dim];
  Mask_t mask_m;
};
template<int Dim>
class ContiguousMapper
  : public ContextMapper<Dim>
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template<class Partitioner>
  ContiguousMapper(const Partitioner & gp,
     const Loc<Dim> &nblocks)
    : blocks_m(gp.blocks())
  {
  }
  template<class Partitioner>
  ContiguousMapper(const Partitioner & gp)
     : blocks_m(gp.blocks())
  {
  }
  ContiguousMapper(const Loc<Dim> & blocks)
     : blocks_m(blocks)
  {
  }
  void map(const List_t & templist) const;
  Loc<Dim> blocks_m;
};
template<int Dim>
void ContiguousMapper<Dim>::map(const List_t & templist) const
{
  int idx[Dim];
  for (int i = 0;i<Dim;++i)
    idx[i]=0;
  int strides[Dim];
  strides[Dim-1] = 1;
  for ( int i=Dim-2; i>=0; --i)
    strides[i] = strides[i+1]*blocks_m[i+1].last();
  int npatch = 1;
  for (int i=0; i<Dim; ++i)
    npatch *= blocks_m[i].first();
  int ncontexts = Pooma::contexts();
  int npc = npatch/ncontexts;
  int remainder = npatch - (npc*ncontexts);
  int pcontext = 0;
  int c = 0;
  int patchdone = 0;
  int patchleft = npatch;
  int incriment[Dim];
  for (int i =0 ; i<Dim; ++i) incriment[i] = 1;
  while ( true )
    {
      int allIdx = 0;
      for ( int i = 0 ; i < Dim ; ++i)
 allIdx += idx[i]*strides[i];
      (*templist[allIdx]).context() = pcontext;
      ++c;
      ++patchdone;
      --patchleft;
      if(c >= npc )
 {
   if (c == npc && remainder >0 &&
       ((idx[0]-1 >= 0 && idx[0]+1<=(blocks_m[0].first()-1)) ||
        (patchleft - ((npc+1)*(ncontexts-(pcontext+1))) >=0 )) )
     --remainder;
   else
     {
       c = 0;
       ++pcontext;
     }
 }
      bool t = true;
      for ( int i = 0 ; i < Dim ; ++i)
 {
   t = t && (
      idx[i] == (blocks_m[i]-1) && incriment[i] == 1
      ||
      idx[i] == 0 && incriment[i] == -1);
 }
      if (t)
 break;
      idx[0] += incriment[0];
      for ( int i = 0 ; i < Dim ; ++i)
 {
   if ( idx[i] > blocks_m[i].last()-1)
     {
       idx[i+1]+=incriment[i+1];
       idx[i]=blocks_m[i].last()-1;
       incriment[i] *= -1;
     }
   else if (idx[i]<0)
     {
       idx[i+1]+=incriment[i+1];
       idx[i]=0;
       incriment[i] *= -1;
     }
   else
     break;
 }
    }
  ContextMapper<Dim>::setAffinity(templist);
}
template <int Dim>
class BisectionMapper
  : public ContextMapper<Dim>
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template<class Partitioner>
  BisectionMapper(const Partitioner & gp,
     const Loc<Dim> &nblocks)
    : blocks_m(gp.blocks())
  {
  }
  template<class Partitioner>
  BisectionMapper(const Partitioner & gp)
     : blocks_m(gp.blocks())
  {
  }
  BisectionMapper(const Loc<Dim>& blocks)
     : blocks_m(blocks)
  {
  }
  void map(const List_t & templist) const;
  Loc<Dim> blocks_m;
};
template <int Dim>
void BisectionMapper<Dim>::map(const List_t & templist) const
{
  int ncontexts = Pooma::contexts();
  int npatch = 1;
  for (int i =0;i<Dim; ++i)
    npatch*=blocks_m[i].first();
  std::list<Domain_t> bvec;
  Domain_t allb;
  for (int i = 0; i<Dim; ++i)
    allb[i]=Interval<1>(0,blocks_m[i].first()-1);
  bvec.push_back(allb);
  while ( bvec.size() < ncontexts )
    {
      int s = 0;
      typename std::list<Domain_t>::iterator bstart = bvec.begin();
      typename std::list<Domain_t>::iterator bend = bvec.end();
      typename std::list<Domain_t>::iterator bpatch;
      for ( ; bstart != bend ; ++bstart)
 {
   if (s < (*bstart).size() )
     {
       bpatch = bstart;
       s = (*bstart).size();
     }
 }
      int d = 0;
      int sd = 0;
      for (int i = 0; i<Dim; ++i)
 {
   if ( sd < (*bpatch)[i].size() )
     {
       d = i;
       sd = (*bpatch)[i].size();
     }
 }
      Domain_t hi(*bpatch),lo(*bpatch);
      int lopoint = hi[d].first();
      int hipoint = hi[d].last();
      int mid = lopoint + ( (hipoint - lopoint)/2);
      if (lopoint<=mid)
 lo[d] = Interval<1>(lopoint,mid);
      else
 lo[d] = Interval<1>(lopoint,lopoint);
      if ( hipoint>=mid+1)
 hi[d] = Interval<1>(mid+1,hipoint);
      else
 hi[d] = Interval<1>(hipoint,hipoint);
      bvec.erase(bpatch++);
      bvec.insert(bpatch,lo);
      bvec.insert(bpatch,hi);
    }
  int strides[Dim];
  strides[0] = 1;
  for ( int i=1; i<Dim; ++i)
    strides[i] = strides[i-1]*blocks_m[i-1].first();
  typename std::list<Domain_t>::iterator start = bvec.begin();
  typename std::list<Domain_t>::iterator end = bvec.end();
  int pcontext = 0;
  for ( ; start != end ; ++start)
    {
      int idx[Dim],mi[Dim],mx[Dim];
      for ( int i = 0 ; i < Dim ; ++i)
 {
   idx[i] = mi[i] = (*start)[i].first();
   mx[i] = (*start)[i].last();
 }
      while ( idx[Dim-1] <= mx[Dim-1] )
 {
   int allIdx = 0;
   for ( int i = 0 ; i < Dim ; ++i)
     allIdx += idx[i]*strides[i];
   (*templist[allIdx]).context() = pcontext;
   ++idx[0];
   for ( int i = 0 ; i < Dim ; ++i)
     {
       if ( idx[i] > mx[i] )
  {
    if ( i!=(Dim-1) )
      {
        ++idx[i+1];
        idx[i]=mi[i];
      }
    else
      ++idx[i];
  }
       else
  break;
     }
 }
      ++pcontext;
    }
  this->setAffinity(templist);
}
class UniformMapper
  : public ContextMapper<1>
{
public:
  typedef Interval<1> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template <class Partitioner>
  inline
  UniformMapper(const Partitioner& gp)
    : blocks_m(gp.blocks())
  {
  }
  inline
  UniformMapper(const Loc<1>& blocks)
    : blocks_m(blocks)
  {
  }
  inline
  UniformMapper(int blocks = 1)
    : blocks_m(blocks)
  {
  }
  virtual ~UniformMapper(){}
  void map(const List_t&) const;
private:
  Loc<1> blocks_m;
};
template<int Dim>
class DistributedMapper
  : public ContextMapper<Dim>
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  template<class Partitioner>
  DistributedMapper(const Partitioner & gp)
    : blocks_m(gp.blocks())
  {
  }
  void map(const List_t & templist) const;
  void uniformMap(const Loc<1> &blocks,
    const List_t &templist,
    const WrappedInt<1>&) const
  {
    UniformMapper(blocks).map(templist);
  }
  template <int D>
  void uniformMap(const Loc<D> &,
    const List_t &,
    const WrappedInt<D>&) const
  {
    ;
  }
private:
  Loc<Dim> blocks_m;
};
template<int Dim>
void DistributedMapper<Dim>::map(const List_t & templist) const
{
  int ncontexts = Pooma::contexts();
  int npc = templist.size()/ncontexts;
  if(ncontexts> templist.size())
    {
      npc = 1;
      ncontexts = templist.size();
    }
  if (Dim == 1)
    {
      uniformMap(blocks_m,templist,WrappedInt<Dim>());
    }
  else if(npc<3)
    {
      ContiguousMapper<Dim>(blocks_m).map(templist);
    }
  else
    {
      BisectionMapper<Dim>(blocks_m).map(templist);
    }
  return;
}
template<int Dim>
class UniformGridPartition
{
public:
  typedef LocalMapper<Dim> DefaultMapper_t;
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  enum { uniform = true };
  enum { gridded = true };
  enum { tile = false };
  enum { general = false };
  enum { dimensions = Dim };
  UniformGridPartition();
  UniformGridPartition(const GuardLayers<Dim> &gcs);
  UniformGridPartition(const Loc<Dim> &a);
  UniformGridPartition(const Loc<Dim> &a,
                       const GuardLayers<Dim> &gcs );
  UniformGridPartition(const Loc<Dim> &a,
                       const GuardLayers<Dim> &igcs,
                       const GuardLayers<Dim> &egcs);
  UniformGridPartition(const UniformGridPartition<Dim> &b);
  ~UniformGridPartition() { }
  UniformGridPartition<Dim> &
  operator=(const UniformGridPartition<Dim> &g)
  {
    if (this != &g)
      {
 blocks_m = g.blocks();
 hasGuards_m = g.hasGuards_m;
 hasCustomEdgeGuards_m = g.hasCustomEdgeGuards_m;
 internalGuards_m = g.internalGuards_m;
 externalGuards_m = g.externalGuards_m;
 num_m = g.maxSize();
      }
    return *this;
  }
  int maxSize() const { return num_m; }
  const Loc<Dim> &blocks() const { return blocks_m; }
  bool hasGuards() const
  {
    ;
    return hasGuards_m;
  }
  bool hasInternalGuards() const
  {
    return hasGuards_m && internalGuards_m != 0;
  }
  bool hasExternalGuards() const
  {
    return hasGuards_m && externalGuards_m != 0;
  }
  const GuardLayers<Dim> &internalGuards() const
  {
    return internalGuards_m;
  }
  const GuardLayers<Dim> &externalGuards() const
  {
    return externalGuards_m;
  }
  template<class D>
  int partition(const D &domain,
  List_t & all,
  const ContextMapper<Dim>& cmapper) const;
  template<class D>
  int partition(const D &domain, List_t & list) const
  {
    return partition(domain,list,DefaultMapper_t(*this));
  }
protected:
  Loc<Dim> blocks_m;
  bool hasGuards_m;
  bool hasCustomEdgeGuards_m;
  GuardLayers<Dim> internalGuards_m;
  GuardLayers<Dim> externalGuards_m;
  int num_m;
  void calcNum()
  {
    num_m = blocks_m[0].first();
    for (int d = 1; d < Dim; ++d)
      {
 num_m *= blocks_m[d].first();
      }
  }
};
template<int Dim>
template<class D>
int UniformGridPartition<Dim>::partition(const D &domain,
      List_t & all,
      const ContextMapper<Dim>& cmapper) const
{
  typedef typename DomainTraits<Domain_t>::Element_t Element_t;
  PoomaCTAssert<(Dim == DomainTraits<D>::dimensions)>::test();
  PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
  PoomaCTAssert<(DomainTraits<D>::unitStride == 1)>::test();
  PoomaCTAssert<(DomainTraits<Domain_t>::unitStride == 1)>::test();
  ;
  Element_t origin[Dim];
  Element_t sizes[Dim];
  Interval<Dim> bdomain = Pooma::NoInit();
  int i;
  for (i = 0; i < Dim; ++i)
    {
      if (!domain.empty())
 {
   int gcwidth =
     (internalGuards_m.lower(i) > internalGuards_m.upper(i)) ?
     internalGuards_m.lower(i) : internalGuards_m.upper(i);
   if (__builtin_expect(!!((domain[i].length() % blocks()[i].first()) == 0), true)) {} else Pooma::toss_cookies("All the blocks in a grid must be the same size.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Partition/UniformGridPartition.h", 369);
   origin[i] = domain[i].first();
   sizes[i] = domain[i].length() / blocks()[i].first();
   if (__builtin_expect(!!(sizes[i] >= gcwidth), true)) {} else Pooma::toss_cookies("Block sizes too small for guard layer specification.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Partition/UniformGridPartition.h", 375);
 }
      bdomain[i] = Interval<1>(blocks()[i].first());
    }
  typename Interval<Dim>::const_iterator it = bdomain.begin();
  while (it != bdomain.end())
    {
      Domain_t owned;
      GuardLayers<Dim> iguards(0);
      GuardLayers<Dim> eguards(0);
      if (!domain.empty())
 {
   Loc<Dim> pos = *it;
   for (i = 0; i < Dim; ++i)
     {
       int position = pos[i].first();
       Element_t a = origin[i] + sizes[i]*position;
       Element_t b = a + sizes[i] - 1;
       typedef typename
  DomainTraits<Domain_t>::OneDomain_t OneDomain_t;
       owned[i] = OneDomain_t(a, b);
     }
   if (hasGuards_m)
     {
       iguards = internalGuards_m;
       for (int d = 0; d < Dim; ++d)
  {
    int position = pos[d].first();
    if ( position == bdomain[d].first() )
      {
        eguards.lower(d) = externalGuards_m.lower(d);
        iguards.lower(d) = 0;
      }
    if ( position == bdomain[d].last() )
      {
        eguards.upper(d) = externalGuards_m.upper(d);
        iguards.upper(d) = 0;
      }
  }
     }
 }
      typename Value_t::ID_t gid = all.size();
      typename Value_t::ID_t lid = (-1);
      GuardLayers<Dim>::addGuardLayers(owned,eguards);
      Domain_t allocated = owned;
      GuardLayers<Dim>::addGuardLayers(allocated,iguards);
      Value_t *node = new Value_t(owned, allocated, -1, gid, lid);
      all.push_back(node);
      ++it;
    }
  cmapper.map(all);
  return num_m;
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition()
: hasGuards_m(false),
  hasCustomEdgeGuards_m(false),
  num_m(1)
{
  blocks_m = 1;
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition(const GuardLayers<Dim> &gcs)
: hasGuards_m(gcs != 0),
  hasCustomEdgeGuards_m(gcs != 0),
  externalGuards_m(gcs),
  num_m(1)
{
  blocks_m = 1;
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition(const Loc<Dim> &a)
: blocks_m(a),
  hasGuards_m(false),
  hasCustomEdgeGuards_m(false)
{
  calcNum();
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition(const Loc<Dim> &a,
                     const GuardLayers<Dim> &gcs)
: blocks_m(a),
  hasGuards_m(gcs != 0),
  hasCustomEdgeGuards_m(false),
  internalGuards_m(gcs),
  externalGuards_m(gcs)
{
  calcNum();
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition(const Loc<Dim> &a,
                     const GuardLayers<Dim> &igcs,
                     const GuardLayers<Dim> &egcs)
: blocks_m(a),
  hasGuards_m(igcs != 0 || egcs != 0),
  hasCustomEdgeGuards_m(igcs != egcs),
  internalGuards_m(igcs),
  externalGuards_m(egcs)
{
  calcNum();
}
template <int Dim>
inline UniformGridPartition<Dim>::
UniformGridPartition(const UniformGridPartition<Dim> &b)
: blocks_m(b.blocks_m),
  hasGuards_m(b.hasGuards_m),
  hasCustomEdgeGuards_m(b.hasCustomEdgeGuards_m),
  internalGuards_m(b.internalGuards_m),
  externalGuards_m(b.externalGuards_m),
  num_m(b.num_m)
{ }
struct ReplicatedTag {};
struct DistributedTag {};
template <class LayoutTag, int Dim>
struct MultiPatchLayoutTraits {};
template <int Dim>
class LayoutBaseData
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Interval<Dim> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  struct GCFillInfo
  {
    GCFillInfo(const Domain_t &dom, int ownedID, int guardID, int face=-1)
    : domain_m(dom), ownedID_m(ownedID), guardID_m(guardID), face_m(face) { }
    GCFillInfo() { if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Shouldn't get here!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/LayoutBase.h", 126); }
    Domain_t domain_m;
    int ownedID_m;
    int guardID_m;
    int face_m;
    Domain_t & domain() { return domain_m;}
    int & ownedID() { return ownedID_m;}
    int & guardID() { return guardID_m;}
  };
  typedef GCFillInfo GCFillInfo_t;
  typedef typename std::vector<GCFillInfo>::const_iterator FillIterator_t;
  LayoutBaseData()
    :
    ID_m(Unique::get()),
    domain_m(Interval<Dim>()),
    innerdomain_m(Interval<Dim>()),
    hasInternalGuards_m(false),
    hasExternalGuards_m(false),
    internalGuards_m(0),
    externalGuards_m(0)
  {
  }
  LayoutBaseData(bool hasIG, bool hasEG,
   GuardLayers_t eg, GuardLayers_t ig,
   Domain_t d, Domain_t id)
    :
    ID_m(Unique::get()),
    domain_m(d),
    innerdomain_m(id),
    hasInternalGuards_m(hasIG),
    hasExternalGuards_m(hasEG),
    internalGuards_m(ig),
    externalGuards_m(eg)
  {
  }
  ~LayoutBaseData()
  {
  }
  inline const Domain_t & domain(int i) const
  {
    ;
    return all_m[i]->allocated();
  }
  inline const Domain_t & ownedDomain(int i) const
  {
    ;
    return all_m[i]->domain();
  }
  inline const Domain_t & allocatedDomain(int i) const
  {
    ;
    return all_m[i]->allocated();
  }
  inline const GuardLayers_t& internalGuards() const
  {
    return internalGuards_m;
  }
  inline const GuardLayers_t& externalGuards() const
  {
    return externalGuards_m;
  }
  inline List_t &nodeListGlobal()
  {
    return all_m;
  }
  inline List_t &nodeListLocal()
  {
    return local_m;
  }
  inline List_t &nodeListRemote()
  {
    return remote_m;
  }
  inline bool initialized() const { return all_m.size() > 0; }
  inline int first(int d) const { return firsti_m[d]; }
  inline int firsts(int d) const { return firste_m[d]; }
  inline const Loc<Dim>& blocks() const { return blocks_m; }
  FillIterator_t beginFillList() const
  {
    return gcFillList_m.begin();
  }
  FillIterator_t endFillList() const
  {
    return gcFillList_m.end();
  }
  ID_t ID_m;
  Domain_t domain_m;
  Domain_t innerdomain_m;
  List_t all_m;
  List_t local_m;
  List_t remote_m;
  bool hasInternalGuards_m;
  bool hasExternalGuards_m;
  GuardLayers_t internalGuards_m;
  GuardLayers_t externalGuards_m;
  std::vector<GCFillInfo> gcFillList_m;
  int firste_m[Dim];
  int firsti_m[Dim];
  Loc<Dim> blocks_m;
};
template <int Dim, class LBD>
class LayoutBase
{
public:
  typedef LayoutBaseData<Dim> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef LayoutBase<Dim,LBD> This_t;
  typedef Observable<This_t> Observable_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
  typedef typename
  std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  enum { supportsGuards = true };
  LayoutBase(LBD * Ldata)
    : pdata_m(Ldata)
  {
  }
   LayoutBase(RefCountedPtr<LBD> pdata)
    : pdata_m(pdata)
  {
  }
  ~LayoutBase()
  {
  }
  inline ID_t ID() const
  {
    return pdata_m->ID_m;
  }
  inline ID_t baseID() const
  {
    return pdata_m->ID_m;
  }
  inline bool initialized() const
  {
    return (sizeGlobal() > 0);
  }
  template <class DT>
  BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
    BaseDomain_t &base) const
  {
    return pdata_m->indexer_m.localToBase(dlocal,base);
  }
  inline const Domain_t &domain() const
  {
    return pdata_m->domain_m;
  }
  inline const Domain_t &innerDomain() const
  {
    return pdata_m->innerdomain_m;
  }
  inline const Domain_t &baseDomain() const
  {
    return pdata_m->domain_m;
  }
  inline const Domain_t &domain(int i) const
  {
    return pdata_m->domain(i);
  }
  inline const Domain_t &ownedDomain(int i) const
  {
    return pdata_m->ownedDomain(i);
  }
  inline const Domain_t &allocatedDomain(int i) const
  {
    return pdata_m->allocatedDomain(i);
  }
  inline const List_t & nodeListGlobal() const
  {
    return pdata_m->nodeListGlobal();
  }
  inline const List_t &nodeListLocal() const
  {
    return pdata_m->nodeListLocal();
  }
  inline const List_t &nodeListRemote() const
  {
    return pdata_m->nodeListRemote();
  }
  inline GuardLayers_t internalGuards() const
  {
    return pdata_m->internalGuards();
  }
  inline GuardLayers_t externalGuards() const
  {
    return pdata_m->externalGuards();
  }
  inline int first(int d) const { return pdata_m->first(d); }
  inline Loc<Dim> blocks() const { return pdata_m->blocks(); }
  inline const Domain_t patchDomain(int lid) const
  {
    return nodeListLocal()[lid]->domain();
  }
  inline int localToGlobalPatchID(int lid) const
  {
    return nodeListLocal()[lid]->globalID();
  }
  int globalID(const Loc<Dim> &loc) const
  { return pdata_m->globalID(loc); }
  int globalID(int i0) const
  { return pdata_m->globalID(i0); }
  int globalID(int i0, int i1) const
  { return pdata_m->globalID(i0,i1); }
  int globalID(int i0, int i1, int i2) const
  { return pdata_m->globalID(i0,i1,i2); }
  int globalID(int i0, int i1, int i2, int i3) const
  { return pdata_m->globalID(i0,i1,i2,i3); }
  int globalID(int i0, int i1, int i2, int i3, int i4) const
  { return pdata_m->globalID(i0,i1,i2,i3,i4); }
  int globalID(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return pdata_m->globalID(i0,i1,i2,i3,i4,i5); }
  int globalID(int i0, int i1, int i2,int i3, int i4, int i5, int i6) const
  { return pdata_m->globalID(i0,i1,i2,i3,i4,i5,i6); }
  template <class Partitioner>
  bool repartition(const Partitioner &gp,const ContextMapper<Dim> &cmap)
  {
    return pdata_m->repartition(gp,cmap);
  }
  template <class Partitioner>
  bool repartition(const Partitioner &gp)
  {
    typename Partitioner::DefaultMapper_t cmap(gp);
    return pdata_m->repartition(gp,cmap);
  }
  template <class L>
  inline bool operator==(const L &layout) const
  {
    return (baseID() == layout.baseID() &&
            baseDomain() == layout.baseDomain());
  }
  template <class L>
  inline bool operator!=(const L &layout) const
  {
    return !(*this == layout);
  }
  inline iterator beginGlobal()
  {
    return iterator(pdata_m->all_m.begin());
  }
  inline iterator endGlobal()
  {
    return iterator(pdata_m->all_m.end());
  }
  inline const_iterator beginGlobal() const
  {
    return const_iterator(pdata_m->all_m.begin());
  }
  inline const_iterator endGlobal() const
  {
    return const_iterator(pdata_m->all_m.end());
  }
  inline int sizeGlobal() const
  {
    return pdata_m->all_m.size();
  }
  inline iterator beginLocal()
  {
    return iterator(pdata_m->local_m.begin());
  }
  inline iterator endLocal()
  {
    return iterator(pdata_m->local_m.end());
  }
  inline const_iterator beginLocal() const
  {
    return const_iterator(pdata_m->local_m.begin());
  }
  inline const_iterator endLocal() const
  {
    return const_iterator(pdata_m->local_m.end());
  }
  inline int sizeLocal() const
  {
    return pdata_m->local_m.size();
  }
  inline iterator beginRemote()
  {
    return iterator(pdata_m->remote_m.begin());
  }
  inline iterator endRemote()
  {
    return iterator(pdata_m->remote_m.end());
  }
  inline const_iterator beginRemote() const
  {
    return const_iterator(pdata_m->remote_m.begin());
  }
  inline const_iterator endRemote() const
  {
    return const_iterator(pdata_m->remote_m.end());
  }
  inline int sizeRemote() const
  {
    return pdata_m->remote_m.size();
  }
  FillIterator_t beginFillList() const
  {
    return pdata_m->beginFillList();
  }
  FillIterator_t endFillList() const
  {
    return pdata_m->endFillList();
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o, const ConstructTag &ctag) const
  {
    return pdata_m->touches(d,o,ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAlloc(const OtherDomain &d, OutIter o,
                   const ConstructTag &ctag) const
  {
    return pdata_m->touchesAlloc(d, o, ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesLocal(const OtherDomain &d, OutIter o,
     const ConstructTag &ctag) const
  {
    return pdata_m->touchesLocal(d, o, ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesAllocLocal(const OtherDomain &d, OutIter o,
          const ConstructTag &ctag) const
  {
    return pdata_m->touchesAllocLocal(d, o, ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesRemote(const OtherDomain & d, OutIter o,
      const ConstructTag &ctag) const
  {
    return pdata_m->touchesRemote(d,o,ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesAllocRemote(const OtherDomain &d, OutIter o,
           const ConstructTag & ctag) const
  {
    return pdata_m->touchesAllocRemote(d,o,ctag);
  }
  template <class OtherDomain, class OutIter>
  inline int touches(const OtherDomain &d, OutIter o) const
  {
    return touches(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  inline int touchesLocal(const OtherDomain &d, OutIter o) const
  {
    return touchesLocal(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  inline int touchesRemote(const OtherDomain &d, OutIter o) const
  {
    return touchesRemote(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  int touchesAlloc(const OtherDomain &d, OutIter o) const
  {
    return touchesAlloc(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  int touchesAllocLocal(const OtherDomain &d, OutIter o) const
  {
    return touchesAllocLocal(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  int touchesAllocRemote(const OtherDomain &d, OutIter o) const
  {
    return touchesAllocRemote(d, o, TouchesConstructNodeObj());
  }
  template <int Dim1, int Dim2, class lbd>
  friend class LayoutBaseView;
  friend class LayoutBaseData<Dim>;
  RefCountedPtr<LBD> pdata_m;
};
template <int Dim, int Dim2, class L>
class LayoutBaseViewData
{
public:
  typedef L Layout_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim2> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef typename Layout_t::Domain_t AllocatedDomain_t;
  typedef ViewIndexer<Dim,Dim2> Indexer_t;
  typedef Node<Domain_t,AllocatedDomain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  LayoutBaseViewData()
   : id_m(Unique::get())
  { }
  template<class DT>
  LayoutBaseViewData(const L & layout, const Domain<Dim,DT> & dom)
    : id_m(Unique::get()), layout_m(layout),
      internalGuards_m(layout.internalGuards()),
      externalGuards_m(layout.externalGuards()),
      indexer_m(dom),
      subdomainsComputed_m(false)
  {
    PoomaCTAssert<(Dim == Dim2)>::test();
    ;
    ;
  }
  template <class DT>
  LayoutBaseViewData(const L &layout, const SliceDomain<DT> &dom)
  : id_m(Unique::get()), layout_m(layout), indexer_m(dom),
    subdomainsComputed_m(false)
  {
    PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
    PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
    ;
    ;
    int dt, d;
    for (d = 0, dt = 0; dt < Dim2; ++dt)
      {
        if (!dom.ignorable(dt))
          {
            internalGuards_m.lower(d) = layout_m.internalGuards().lower(dt);
            internalGuards_m.upper(d) = layout_m.internalGuards().upper(dt);
            externalGuards_m.lower(d) = layout_m.externalGuards().lower(dt);
            externalGuards_m.upper(d) = layout_m.externalGuards().upper(dt);
            ;
            ++d;
          }
      }
  }
   template <class DT,class LV>
   LayoutBaseViewData(const L &layout,
        const LV & viewLayout,
        const Indexer_t & indexer,
        const Domain<Dim, DT> &dom,
        GuardLayers_t ig,
        GuardLayers_t eg)
  :
    id_m(Unique::get()),
    layout_m(layout),
    internalGuards_m(ig),
    externalGuards_m(eg),
    indexer_m(indexer, dom),
    subdomainsComputed_m(false)
  {
    ;
    ;
  }
   template <class DT,class LV>
   LayoutBaseViewData(const L &layout,
        const LV &viewLayout,
        const Indexer_t indexer,
        const SliceDomain<DT> &dom)
     : id_m(Unique::get()), layout_m(layout),
     indexer_m(indexer),
     subdomainsComputed_m(false)
  {
    PoomaCTAssert<((int)DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<((int)DT::dimensions == LV::dimensions)>::test();
    ;
    ;
    int dt, d;
    for (d = 0, dt = 0; dt < LV::dimensions ; ++dt)
      {
        if (!dom.ignorable(dt))
          {
            internalGuards_m.lower(d) = viewLayout.internalGuards().lower(dt);
            internalGuards_m.upper(d) = viewLayout.internalGuards().upper(dt);
            externalGuards_m.lower(d) = viewLayout.externalGuards().lower(dt);
            externalGuards_m.upper(d) = viewLayout.externalGuards().upper(dt);
            ;
            ++d;
          }
      }
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o,
              const ConstructTag &ctag) const
  {
    BaseDomain_t bd = Pooma::NoInit();
    indexer_m.localToBase(d, bd);
    std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
    int count = layout_m.touches(bd, std::back_inserter(tnodes));
    Range<Dim> ld = Pooma::NoInit();
    for (int i = 0; i < count; i++)
      {
        *o++ =
          touchesConstruct(indexer_m.baseToLocal(tnodes[i].domain(), ld),
                           tnodes[i].allocated(),
                           tnodes[i].affinity(), tnodes[i].context(),
                           tnodes[i].globalID(), tnodes[i].localID(), ctag);
      }
    return count;
  }
  void computeSubdomains() const
  {
    if (subdomainsComputed_m)
      return;
    std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
    int count = layout_m.touches(indexer_m.baseDomain(),
                                 std::back_inserter(tnodes));
    Domain_t ld = Pooma::NoInit();
    for (int i = 0; i < count; ++i)
      {
        Value_t *pt =
          touchesConstruct(indexer_m.baseToLocal(tnodes[i].domain(), ld),
                           tnodes[i].allocated(),
                           tnodes[i].affinity(),tnodes[i].context(),
                           tnodes[i].globalID(),tnodes[i].localID(),
                           TouchesConstructNodePtr());
        all_m.push_back(pt);
        if (pt->context() == Pooma::context()
     ||pt->context() == -1 )
          local_m.push_back(pt);
        else
          remote_m.push_back(pt);
      }
    subdomainsComputed_m = true;
  }
  ID_t id_m;
  L layout_m;
  GuardLayers_t internalGuards_m;
  GuardLayers_t externalGuards_m;
  Indexer_t indexer_m;
  mutable List_t all_m;
  mutable List_t local_m;
  mutable List_t remote_m;
  mutable bool subdomainsComputed_m;
};
template <int Dim, int Dim2, class lvd>
class LayoutBaseView
{
public:
  enum { dimensions = Dim };
  typedef lvd LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Layout_t Layout_t;
  typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef typename LayoutData_t::Indexer_t Indexer_t;
  typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
  typedef LayoutBaseView<Dim, Dim2, lvd> This_t;
  typedef LayoutBaseView<Dim, Dim2, lvd> ViewLayout_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  LayoutBaseView(LayoutData_t * lvdp)
    : pdata_m(lvdp)
  {}
  LayoutBaseView(const RefCountedPtr<LayoutData_t> & pdata)
    : pdata_m(pdata)
  {}
  inline ID_t ID() const { return pdata_m->id_m; }
  inline ID_t baseID() const { return pdata_m->layout_m.baseID(); }
  inline bool initialized() const { return true; }
  inline const Domain_t &domain() const
  {
    return pdata_m->indexer_m.domain();
  }
  inline const Domain_t &innerDomain() const
  {
    return pdata_m->indexer_m.innerDomain();
  }
  inline const BaseDomain_t &baseDomain() const
  {
    return pdata_m->indexer_m.baseDomain();
  }
  inline const Layout_t &baseLayout() const
  {
    return pdata_m->layout_m;
  }
  template <class DT>
  BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
    BaseDomain_t &base) const
  {
    return pdata_m->indexer_m.localToBase(dlocal,base);
  }
  template <class DT>
  SliceRange<Dim2, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
    SliceRange<Dim2, Dim> &base) const
  {
    return pdata_m->indexer_m.localToBase(dlocal,base);
  }
  inline GuardLayers_t internalGuards() const
  {
    return pdata_m->internalGuards_m;
  }
  inline GuardLayers_t externalGuards() const
  {
    return pdata_m->externalGuards_m;
  }
  inline int first(int) const { return 0; }
  template <class L>
  inline bool operator==(const L &layout) const
  {
    return (baseID() == layout.baseID() &&
            baseDomain() == layout.baseDomain());
  }
  template <class L>
  inline bool operator!=(const L &layout) const
  {
    return !(*this == layout);
  }
  inline int
  globalID(const Loc<Dim> &loc, Loc<Dim2> &oloc) const
  {
    pdata_m->indexer_m.translate(loc,oloc);
    return pdata_m->layout_m.globalID(oloc);
  }
  inline int
  globalID(int i0, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, int i2, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,i2,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, int i2, int i3,
           Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,i2,i3,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, int i2, int i3,
           int i4, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, int i2, int i3,
           int i4, int i5, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,i5,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  inline int
  globalID(int i0, int i1, int i2, int i3,
           int i4, int i5, int i6, Loc<Dim2> &loc) const
  {
    pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,i5,i6,loc);
    return pdata_m->layout_m.globalID(loc);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o,
    const ConstructTag &ctag) const
  {
    return pdata_m->touches(d,o,ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesLocal(const OtherDomain &d, OutIter o,
    const ConstructTag &ctag) const {
    return pdata_m->touches(d, o, ctag);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesRemote(const OtherDomain &, OutIter,
    const ConstructTag &) const {
    return 0;
  }
  template <class OtherDomain, class OutIter>
  inline int touches(const OtherDomain &d, OutIter o) const {
    return touches(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  inline int touchesLocal(const OtherDomain &d, OutIter o) const {
    return touchesLocal(d, o, TouchesConstructNodeObj());
  }
  template <class OtherDomain, class OutIter>
  inline int touchesRemote(const OtherDomain &d, OutIter o) const {
    return touchesRemote(d, o, TouchesConstructNodeObj());
  }
  inline iterator beginGlobal() {
    computeSubdomains();
    return iterator(pdata_m->all_m.begin());
  }
  inline iterator endGlobal() {
    computeSubdomains();
    return iterator(pdata_m->all_m.end());
  }
  inline const_iterator beginGlobal() const {
    computeSubdomains();
    return const_iterator(pdata_m->all_m.begin());
  }
  inline const_iterator endGlobal() const {
    computeSubdomains();
    return const_iterator(pdata_m->all_m.end());
  }
  inline int sizeGlobal() const {
    computeSubdomains();
    return pdata_m->all_m.size();
  }
  inline iterator beginLocal() {
    computeSubdomains();
    return iterator(pdata_m->local_m.begin());
  }
  inline iterator endLocal() {
    computeSubdomains();
    return iterator(pdata_m->local_m.end());
  }
  inline const_iterator beginLocal() const {
    computeSubdomains();
    return const_iterator(pdata_m->local_m.begin());
  }
  inline const_iterator endLocal() const {
    computeSubdomains();
    return const_iterator(pdata_m->local_m.end());
  }
  inline int sizeLocal() const {
    computeSubdomains();
    return pdata_m->local_m.size();
  }
  inline iterator beginRemote() {
    computeSubdomains();
    return iterator(pdata_m->remote_m.begin());
  }
  inline iterator endRemote() {
    computeSubdomains();
    return iterator(pdata_m->remote_m.end());
  }
  inline const_iterator beginRemote() const {
    computeSubdomains();
    return const_iterator(pdata_m->remote_m.begin());
  }
  inline const_iterator endRemote() const {
    computeSubdomains();
    return const_iterator(pdata_m->remote_m.end());
  }
  inline int sizeRemote() const {
    computeSubdomains();
    return pdata_m->remote_m.size();
  }
  template <int OtherDim, int OtherDim2, class OtherLayoutData>
  friend class LayoutBaseView;
  template <int OtherDim, int OtherDim2, class OtherLayout>
  friend class LayoutBaseViewData;
  void computeSubdomains() const { pdata_m->computeSubdomains(); }
  RefCountedPtr<LayoutData_t> pdata_m;
};
template <int Dim> class SparseTileLayoutData;
template <int Dim> class SparseTileLayout;
template <int Dim, int Dim2> class SparseTileLayoutViewData;
template <int Dim, int Dim2> class SparseTileLayoutView;
struct SparseTileTag { };
template <int Dim>
struct MultiPatchLayoutTraits<SparseTileTag,Dim>
{
  typedef SparseTileLayout<Dim> Layout_t;
  template <int ViewDim>
  struct View
  {
    typedef SparseTileLayoutView<ViewDim,Dim> Layout_t;
  };
};
template<int Dim>
class SparseTileLayoutData
 : public LayoutBaseData<Dim>,
   public RefCounted,
   public Observable< SparseTileLayoutData<Dim> >
{
public:
  typedef SparseTileLayoutData<Dim> This_t;
  typedef Observable<This_t> Observable_t;
  typedef Interval<Dim> Domain_t;
  typedef Interval<Dim> BaseDomain_t;
  typedef Interval<Dim> AllocatedDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef Node<Domain_t,AllocatedDomain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef std::map<int,Value_t> Map_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef std::pair<int,int> pidx_t;
  typedef typename DynamicEvents::PatchID_t PatchID_t;
  typedef typename DynamicEvents::CreateSize_t CreateSize_t;
  typedef BaseDomain_t SubPatch_t;
  typedef std::vector<SubPatch_t> PatchList_t;
  typedef typename LayoutBaseData<Dim>::GCFillInfo_t GCFillInfo_t;
  typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  struct GCBorderFillInfo
  {
    GCBorderFillInfo(const Domain_t &dom, int patchID)
      : domain_m(dom), patchID_m(patchID)
      {
      }
    GCBorderFillInfo()
      {
 if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Shouldn't get here!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/SparseTileLayout.h", 173);
      }
    Domain_t domain_m;
    int patchID_m;
    inline const Domain_t& domain() const { return domain_m; }
    int patchID() const { return patchID_m;}
  };
  typedef GCBorderFillInfo GCBorderFillInfo_t;
  typedef typename std::vector<GCBorderFillInfo>::const_iterator
                                               BorderFillIterator_t;
  enum { dimensions = Dim };
  enum { repartitionEvent = 1 };
  enum { dynamic = false };
  SparseTileLayoutData();
  SparseTileLayoutData(const Domain_t &,
         const PatchList_t &,
         const ContextMapper<Dim> &);
  SparseTileLayoutData(const Domain_t &boundingbox,
         const GuardLayers_t & globalGL,
         const PatchList_t & PatchList,
         const ContextMapper<Dim> &);
  SparseTileLayoutData(const Domain_t &boundingbox,
         const GuardLayers_t & internalGL,
         const GuardLayers_t & externalGL,
         const PatchList_t & PatchList,
         const ContextMapper<Dim> &);
  SparseTileLayoutData(const Domain_t &boundingbox);
  SparseTileLayoutData(const Domain_t &boundingbox,
         const GuardLayers_t & globalGL);
  SparseTileLayoutData(const Domain_t &boundingbox,
         const GuardLayers_t & internalGL,
         const GuardLayers_t & externalGL);
template <class Partitioner>
SparseTileLayoutData(const Domain_t &bbox,
       const Partitioner & gpar,
       const ContextMapper<Dim> &cmap);
  ~SparseTileLayoutData() ;
  void initialize(const Domain_t &bbox);
  void initialize(const Domain_t &bbox,
    const GuardLayers_t & globalGL);
  void initialize(const Domain_t &bbox,
    const GuardLayers_t & internalGL,
    const GuardLayers_t & externalGL);
  void initialize(const Domain_t &bbox,
    const PatchList_t &plist,
    const ContextMapper<Dim> &cmap);
  void initialize(const Domain_t &bbox,
    const GuardLayers_t & globalGL,
    const PatchList_t &plist,
    const ContextMapper<Dim> &cmap);
  void initialize(const Domain_t &bbox,
    const GuardLayers_t & internalGL,
    const GuardLayers_t & externalGL,
    const PatchList_t &plist,
    const ContextMapper<Dim> &cmap);
  template <class Partitioner>
  void initialize(const Domain_t &bbox,
    const Partitioner &gpar,
    const ContextMapper<Dim> &cmap);
  void syncPatch();
  void calcMaps();
  void calcAllocMaps() ;
  BorderFillIterator_t beginBorderFillList() const
  {
    return gcBorderFillList_m.begin();
  }
  BorderFillIterator_t endBorderFillList() const
  {
    return gcBorderFillList_m.end();
  }
  int globalID(const Loc<Dim> &loc) const;
  int globalID(int) const;
  int globalID(int,int) const;
  int globalID(int,int,int) const;
  int globalID(int,int,int,int) const;
  int globalID(int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int,int) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d,
       OutIter o,
       const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAlloc(const OtherDomain &d,
     OutIter o,
     const ConstructTag &ctag) const;
  template<class Out>
  void print(Out & o) const;
private:
  void calcGCFillList();
  void calcDomains();
  void calcMaps() const;
  void calcAllocMaps() const;
  std::vector<GCBorderFillInfo> gcBorderFillList_m;
  mutable DomainMap<Interval<Dim>,pidx_t> map_m;
  mutable DomainMap<Interval<Dim>,pidx_t> mapAloc_m;
};
template <int Dim>
class SparseTileLayout : public LayoutBase<Dim,SparseTileLayoutData<Dim> >,
                         public Observable<SparseTileLayout<Dim> >,
                         public Observer<SparseTileLayoutData<Dim> >
{
public:
  enum { dimensions = Dim };
  enum { repartitionEvent = 1 };
  enum { dynamic = true };
  typedef SparseTileLayout<Dim> This_t;
  typedef Observable<This_t> Observable_t;
  typedef SparseTileLayoutData<Dim> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef typename LayoutData_t::SubPatch_t SubPatch_t;
  typedef typename LayoutData_t::PatchList_t PatchList_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
  typedef typename LayoutData_t::FillIterator_t FillIterator_t;
  typedef typename LayoutData_t::BorderFillIterator_t BorderFillIterator_t;
  SparseTileLayout();
  SparseTileLayout(const Domain_t &boundingbox);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL);
  SparseTileLayout(Domain_t & boundingbox,
     const PatchList_t &patchlist,
     const ReplicatedTag &);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL,
     const PatchList_t & PatchList,
     const ReplicatedTag &);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL,
     const PatchList_t & PatchList,
     const ReplicatedTag &);
  template<class Partitioner>
  SparseTileLayout(const Domain_t &bbox,
     const Partitioner &gpar,
     const ReplicatedTag &);
  SparseTileLayout(Domain_t & boundingbox,
     const PatchList_t &patchlist,
     const DistributedTag &);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL,
     const PatchList_t & PatchList,
     const DistributedTag &);
  SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL,
     const PatchList_t & PatchList,
     const DistributedTag &);
  template<class Partitioner>
  SparseTileLayout(const Domain_t &bbox,
     const Partitioner &gpar,
     const DistributedTag &);
  template<class Partitioner>
  SparseTileLayout(const Domain_t &bbox,
     const Partitioner &gpar,
     const ContextMapper<Dim> &cmap);
  SparseTileLayout(const This_t &);
  This_t &
  operator=(const This_t &model)
  {
    if (this != &model)
      {
 this->pdata_m->detach(*this);
 this->pdata_m = model.pdata_m;
 this->pdata_m->attach(*this);
      }
    return *this;
  }
  ~SparseTileLayout()
  {
    this->pdata_m->detach(*this);
  }
  void initialize(const Domain_t & a);
  void initialize(const Domain_t &,
              const GuardLayers_t &);
  void initialize(const Domain_t &,
              const GuardLayers_t &,
     const PatchList_t & );
  template<class Partitioner>
  void initialize(const Domain_t &bbox,
      const Partitioner &gpar);
  BorderFillIterator_t beginBorderFillList() const
    {
      return this->pdata_m->beginBorderFillList();
    }
  BorderFillIterator_t endBorderFillList() const
    {
      return this->pdata_m->endBorderFillList();
    }
  void syncPatch();
  virtual void notify(LayoutData_t &d, const ObserverEvent &event)
    {
      ;
      Observable_t::notify(event);
    }
  template <class Ostream>
  void print(Ostream &ostr) const {
    this->pdata_m->print(ostr);
  }
  template <int Dim1, int Dim2>
  friend class SparseTileLayoutView;
  friend class SparseTileLayoutData<Dim>;
};
template <int Dim, int Dim2>
class SparseTileLayoutViewData
: public LayoutBaseViewData<Dim, Dim2, SparseTileLayout<Dim2> >,
  public RefCounted
{
public:
  typedef SparseTileLayout<Dim2> Layout_t;
  typedef SparseTileLayoutView<Dim, Dim2> ViewLayout_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim2> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef typename Layout_t::Domain_t AllocatedDomain_t;
  typedef ViewIndexer<Dim,Dim2> Indexer_t;
  typedef Node<Domain_t,AllocatedDomain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef SparseTileLayoutViewData<Dim,Dim2> LayoutData_t;
  SparseTileLayoutViewData() { }
  template <class DT>
  inline SparseTileLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(layout,dom)
  {
    PoomaCTAssert<(Dim == Dim2)>::test();
    ;
    ;
  }
  template <class DT>
  inline SparseTileLayoutViewData(const Layout_t &layout, const SliceDomain<DT> &dom)
  :LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(layout,dom)
  {
    PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
    PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
    ;
    ;
    int dt, d;
    for (d = 0, dt = 0; dt < Dim2; ++dt)
      {
 if (!dom.ignorable(dt))
   {
     this->internalGuards_m.lower(d) = this->layout_m.internalGuards().lower(dt);
     this->internalGuards_m.upper(d) = this->layout_m.internalGuards().upper(dt);
     this->externalGuards_m.lower(d) = this->layout_m.externalGuards().lower(dt);
     this->externalGuards_m.upper(d) = this->layout_m.externalGuards().upper(dt);
     ;
     ++d;
   }
      }
  }
  template <class DT>
  SparseTileLayoutViewData(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(
           layout.pdata_m->layout_m,
           layout,
           layout.pdata_m->indexer_m,
           dom,
           layout.internalGuards(),
           layout.externalGuards())
  {
    ;
    ;
  }
  template <int OrigDim, class DT>
  SparseTileLayoutViewData(const SparseTileLayoutView<OrigDim, Dim2> &layout,
      const SliceDomain<DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(
        layout.pdata_m->layout_m,
        layout,
        Indexer_t(layout.pdata_m->indexer_m,dom),
        dom)
  {
    PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
    ;
    ;
    int dt, d;
    for (d = 0, dt = 0; dt < OrigDim; ++dt)
      {
 if (!dom.ignorable(dt))
   {
     this->internalGuards_m.lower(d) = layout.internalGuards().lower(dt);
     this->internalGuards_m.upper(d) = layout.internalGuards().upper(dt);
     this->externalGuards_m.lower(d) = layout.externalGuards().lower(dt);
     this->externalGuards_m.upper(d) = layout.externalGuards().upper(dt);
     ;
     ++d;
   }
      }
  }
  ~SparseTileLayoutViewData()
  {
    typename List_t::iterator a;
    for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
      delete (*a);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o,
       const ConstructTag &ctag) const
  {
    BaseDomain_t bd = Pooma::NoInit();
    this->indexer_m.localToBase(d, bd);
    std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
    int count = this->layout_m.touches(bd, std::back_inserter(tnodes));
    Range<Dim> ld = Pooma::NoInit();
    for (int i = 0; i < count; i++)
      {
 *o++ =
   touchesConstruct(this->indexer_m.baseToLocal(tnodes[i].domain(), ld),
      tnodes[i].allocated(),
      tnodes[i].affinity(),tnodes[i].context(),
      tnodes[i].globalID(), tnodes[i].localID(), ctag);
      }
    return count;
  }
  void computeSubdomains() const
  {
    if (this->subdomainsComputed_m)
      return;
    std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
    int count = this->layout_m.touches(this->indexer_m.baseDomain(),
           std::back_inserter(tnodes));
    Domain_t ld = Pooma::NoInit();
    for (int i = 0; i < count; i++)
      {
 Value_t *pt =
   touchesConstruct(this->indexer_m.baseToLocal(tnodes[i].domain(), ld),
      tnodes[i].allocated(),
      tnodes[i].affinity(),tnodes[i].context(),
      tnodes[i].globalID(),tnodes[i].localID(),
      TouchesConstructNodePtr());
 this->all_m.push_back(pt);
      }
    this->subdomainsComputed_m = true;
  }
};
template <int Dim, int Dim2>
class SparseTileLayoutView
: public LayoutBaseView<Dim, Dim2, SparseTileLayoutViewData<Dim,Dim2> >
{
public:
  enum { dimensions = Dim };
  typedef SparseTileLayoutViewData<Dim, Dim2> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Layout_t Layout_t;
  typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef typename LayoutData_t::Indexer_t Indexer_t;
  typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
  typedef SparseTileLayoutView<Dim, Dim2> This_t;
  typedef SparseTileLayoutView<Dim, Dim2> ViewLayout_t;
  typedef LayoutBaseView<Dim,Dim2,LayoutData_t> Base_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  SparseTileLayoutView()
  : Base_t(new LayoutData_t())
  { }
  template <class DT>
  SparseTileLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
  : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
    (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  SparseTileLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
  : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
    (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  SparseTileLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
    (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <int OldViewDim, class DT>
  SparseTileLayoutView(const SparseTileLayoutView<OldViewDim, Dim2> &layout,
                        const SliceDomain<DT> &dom)
  : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
    (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  inline SparseTileLayoutView(const This_t &model)
    : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
  (model.pdata_m)
  { }
  inline This_t &operator=(const This_t &model)
  {
    if (this != &model)
      {
        this->pdata_m = model.pdata_m;
      }
    return *this;
  }
  inline ~SparseTileLayoutView()
  { }
  template <class Ostream>
  void print(Ostream &ostr) const
  {
    ostr << "SparseTileLayoutView " << this->ID() << " on global domain "
      << this->domain() << ":" << '\n';
    ostr << "   Base ID:          " << this->baseID() << '\n';
    ostr << "   Base domain:      " << this->baseDomain() << '\n';
    ostr << "   Total subdomains: " << this->sizeGlobal() << '\n';
    ostr << "   Local subdomains: " << this->sizeLocal() << '\n';
    ostr << "  Remote subdomains: " << this->sizeRemote() << '\n';
    const_iterator a;
    for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
      ostr << "  Global subdomain = " << *a << '\n';
    for (a = this->beginLocal(); a != this->endLocal(); ++a)
      ostr << "   Local subdomain = " << *a << '\n';
    for (a = this->beginRemote(); a != this->endRemote(); ++a)
      ostr << "  Remote subdomain = " << *a << '\n';
  }
  template <int OtherDim, int OtherDim2>
  friend class SparseTileLayoutView;
  template <int OtherDim, int OtherDim2>
  friend class SparseTileLayoutViewData;
  void computeSubdomains() const { this->pdata_m->computeSubdomains(); }
};
template <int Dim>
struct NewDomain1<SparseTileLayout<Dim> >
{
  typedef SparseTileLayout<Dim> &Type_t;
  inline static Type_t combine(const SparseTileLayout<Dim> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim, int Dim2>
struct NewDomain1<SparseTileLayoutView<Dim, Dim2> >
{
  typedef SparseTileLayoutView<Dim, Dim2> &Type_t;
  inline static Type_t combine(const SparseTileLayoutView<Dim, Dim2> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim>
std::ostream &operator<<(std::ostream &ostr,
    const SparseTileLayout<Dim> &layout)
{
  layout.print(ostr);
  return ostr;
}
template <int Dim, int Dim2>
std::ostream &operator<<(std::ostream &ostr,
    const SparseTileLayoutView<Dim, Dim2> &layout)
{
  layout.print(ostr);
  return ostr;
}
template<int Dim> struct IsValid;
template<class LayoutTag, class PatchTag> struct MultiPatch;
template<class LayoutTag, class PatchTag, int Dim2> struct MultiPatchView;
template<class Expr> struct ExpressionTag;
template<class Eng, class Tag> struct EngineFunctor;
template<class Object,class Dom,class PatchTag>
inline bool isValidLocation(const Object & e,
       Dom & domain,
       MultiPatch<SparseTileTag,PatchTag> &)
{
  typedef typename Object::Domain_t domain_t;
  typedef Node<domain_t,domain_t> node_t;
  std::vector<node_t> v;
  int count = e.engine().layout().touches(domain,std::back_inserter(v));
  return (count!=0);
}
template<class Object,class Dom,class PatchTag,int Dim2>
inline bool isValidLocation(const Object & e,
       Dom & domain,
       MultiPatchView<SparseTileTag,
                      PatchTag,
                      Dim2> &)
{
  typedef typename Object::Domain_t domain_t;
  typedef Node<domain_t,domain_t> node_t;
  std::vector<node_t> v;
  int count = e.engine().layout().touches(domain,std::back_inserter(v));
  return (count!=0);
}
template<class Object,class Dom,class expr>
inline bool isValidLocation(const Object & e,
       Dom & domain,
       ExpressionTag<expr> &)
{
  typedef typename Object::Domain_t domain_t;
  typedef Node<domain_t,domain_t> node_t;
  std::vector<node_t> v;
  typedef typename Object::Engine_t Engine_t;
  IsValid<Engine_t::dimensions> l(domain);
  EngineFunctor<Engine_t, IsValid<Engine_t::dimensions> > ef;
  return ef.apply(e.engine(),l);
}
template <int Dim> class Loc;
template <> class Loc<1>;
template <int Dim> class Interval;
template <> class Interval<1>;
template <int Dim> class Grid;
template <> class Grid<1>;
template<int Dim>
struct DomainTraits< Grid<Dim> >
  : public DomainTraitsDomain<Grid<Dim>, int, Dim>
{
  typedef DomainTraitsDomain<Grid<Dim>, int, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef Grid<1> OneDomain_t;
  typedef Grid<1> PointDomain_t;
  typedef Interval<Dim> BlockDomain_t;
  typedef Loc<Dim> AskDomain_t;
  typedef Grid<Dim> AddResult_t;
  typedef Grid<Dim> MultResult_t;
  typedef OneDomain_t Storage_t[Dim];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = Dim };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  enum { wildcard = false };
  static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
  static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void initializeStorage(Storage_t &dom) { }
};
template<>
struct DomainTraits< Grid<1> >
  : public DomainTraitsDomain<Grid<1>, int, 1>
{
  typedef Grid<1> OneDomain_t;
  typedef Grid<1> PointDomain_t;
  typedef Interval<1> BlockDomain_t;
  typedef Loc<1> AskDomain_t;
  typedef Grid<1> AddResult_t;
  typedef Grid<1> MultResult_t;
  typedef IndirectionList<Element_t> Storage_t;
  enum { dimensions = 1,
         sliceDimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = false };
  enum { wildcard = false };
  static Element_t first(const Storage_t &d) { return d.first(); }
  static Element_t last(const Storage_t &d) { return d.last(); }
  static Element_t stride(const Storage_t &d) { return d.stride(); }
  static Element_t length(const Storage_t &d) { return d.length(); }
  static Element_t min(const Storage_t &d) { return d.min(); }
  static Element_t max(const Storage_t &d) { return d.max(); }
  static bool empty(const Storage_t &d) { return d.empty(); }
  static int loop(const Storage_t &) { return 0; }
  static Element_t elem(const Storage_t &d, int n) { return d(n); }
  static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
  static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void initializeStorage(Storage_t &) { }
  template<class T>
  static void setDomain(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    dom = Storage_t(DomainTraits<T>::getFirst(newdom),
      DomainTraits<T>::getStride(newdom),
      DomainTraits<T>::getLength(newdom));
  }
  template<int Dim>
  static void setDomain(Storage_t &dom, const Grid<Dim> &newdom) {
    PoomaCTAssert<(Dim == 1)>::test();
    dom = newdom.storage();
  }
  template<class T1, class T2>
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
    Element_t strideval = (endval < begval ? -1 : 1);
    dom = Storage_t(begval, strideval, (endval - begval)/strideval + 1);
  }
  template<class T1, class T2, class T3>
  static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval,
   const T3 &strideval) {
    PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T3>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<T3>::singleValued)>::test();
    dom = Storage_t(begval, strideval, (endval - begval)/strideval + 1);
  }
  static void setDomain(Storage_t &dom, const Storage_t &newdom) {
    dom = newdom;
  }
  static void setLoop(Storage_t &, int) { }
  template<class UT, class T>
  static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
    dom = Storage_t(newdom.first(u), newdom.stride(u), newdom.length(u));
  }
  template<class T>
  static bool isLessThan(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    ;
    return (dom.first() < DomainTraits<T>::getFirst(newdom) ||
     (dom.first() == DomainTraits<T>::getFirst(newdom) &&
      (dom.last() < DomainTraits<T>::getLast(newdom) ||
       (dom.last() == DomainTraits<T>::getLast(newdom) &&
        dom.length() < DomainTraits<T>::getLength(newdom)))));
  }
  template<class T>
  static bool isEqualTo(const Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
    return ((dom.empty() && DomainTraits<T>::getEmpty(newdom)) ||
     (dom.first() == DomainTraits<T>::getFirst(newdom) &&
      dom.last() == DomainTraits<T>::getLast(newdom) &&
      dom.length() == DomainTraits<T>::getLength(newdom)));
  }
  template<class T>
  static void addAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom += DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void subtractAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom -= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void multiplyAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom *= DomainTraits<T>::getFirst(newdom);
  }
  template<class T>
  static void divideAccum(Storage_t &dom, const T &newdom) {
    PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
    dom /= DomainTraits<T>::getFirst(newdom);
  }
};
template<int Dim1, int Dim2>
struct DomainChangeDim<Grid<Dim1>, Dim2>
{
  typedef Grid<Dim1> OldType_t;
  typedef Grid<Dim2> NewType_t;
  enum { oldDim = Dim1,
  newDim = Dim2 };
};
template<int Dim>
class Grid : public Domain<Dim, DomainTraits<Grid<Dim> > >
{
  typedef DomainTraits< Grid<Dim> > DT_t;
  typedef Domain<Dim, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Grid() { }
  Grid(const Grid<Dim> &a) {
    NewDomain1<Grid<Dim> >::fill(*this, a);
  }
  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);
  }
  ~Grid() { }
  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);
  }
  template<class Out>
  void print(Out &o) const;
protected:
private:
};
template<int Dim>
template<class Out>
void Grid<Dim>::print(Out &o) const
{
  iterator p = this->begin();
  iterator pend = this->end();
  o << "[";
  while (p != pend)
    {
      o << *p;
      ++p;
      if (p != pend)
 o << ",";
    }
  o << "]";
}
template<>
class Grid<1> : public Domain<1, DomainTraits<Grid<1> > >
{
  typedef DomainTraits< Grid<1> > DT_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Grid() { }
  Grid(const Grid<1> &a) {
    NewDomain1<Grid<1> >::fill(*this, a);
  }
  template<class T1>
  explicit Grid(const T1 &a) {
    NewDomain1<T1>::fill(*this, a);
  }
  Grid(char a) {
    ;
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
  }
  Grid(unsigned char a) {
    ;
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
  }
  Grid(short a) {
    ;
    short s = (a < 0 ? -1 : 1);
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
  }
  Grid(unsigned short a) {
    ;
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
  }
  Grid(int a) {
    ;
    int s = (a < 0 ? -1 : 1);
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
  }
  Grid(unsigned int a) {
    ;
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
  }
  Grid(long a) {
    ;
    long s = (a < 0 ? -1 : 1);
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
  }
  Grid(unsigned long a) {
    ;
    DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
  }
  template<class T1, class T2>
  Grid(const T1 &m, const T2 &n);
  template<class T1, class T2, class T3>
  Grid(const T1 &m, const T2 &n, const T3 &s);
  ~Grid() { }
  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);
  }
  template<class Out>
  void print(Out &o) const;
};
template <class T1, class T2>
inline
Grid<1>::Grid(const T1 &m, const T2 &n) {
  DomainTraits<Grid<1> >::setDomain(domain_m, m, n);
}
template <class T1, class T2, class T3>
inline
Grid<1>::Grid(const T1 &m, const T2 &n, const T3 &s) {
  DomainTraits<Grid<1> >::setDomain(domain_m, m, n, s);
}
template<class Out>
void Grid<1>::print(Out &o) const
{
  iterator p = begin();
  iterator pend = end();
  o << "[";
  while (p != pend)
    {
      o << *p;
      ++p;
      if (p != pend)
 o << ",";
    }
  o << "]";
}
template<int Dim>
std::ostream& operator<<(std::ostream &o, const Grid<Dim> &grid)
{
  grid.print(o);
  return o;
}
template <int Dim, class T> class Region;
template <class T> class Region<1,T>;
template<int Dim, class T>
struct DomainTraits< Region<Dim,T> >
  : public DomainTraitsDomain<Region<Dim,T>, T, Dim>
{
  typedef DomainTraitsDomain<Region<Dim,T>, T, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef Region<1,T> OneDomain_t;
  typedef Region<1,T> PointDomain_t;
  typedef Region<Dim,T> BlockDomain_t;
  typedef Region<Dim,T> AskDomain_t;
  typedef Region<Dim,T> AddResult_t;
  typedef Region<Dim,T> MultResult_t;
  typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = Dim };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = true };
  enum { wildcard = false };
  static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
  static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void initializeStorage(Storage_t &dom) {
    Dom1Initialize<Dim-1>::template apply<DomainTraits<Region<Dim, T> > >(dom);
  }
};
template<class T>
struct DomainTraits< Region<1,T> >
  : public DomainTraitsDomain<Region<1,T>, T, 1>
{
  typedef DomainTraitsDomain<Region<1,T>, T, 1> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef Region<1,T> OneDomain_t;
  typedef Region<1,T> BlockDomain_t;
  typedef Region<1,T> AskDomain_t;
  typedef Region<1,T> AddResult_t;
  typedef Region<1,T> MultResult_t;
  typedef Element_t Storage_t[2];
  typedef Element_t IteratorStorage_t[2];
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = 1 };
  enum { loopAware = false };
  enum { singleValued = false };
  enum { unitStride = true };
  enum { wildcard = false };
  static Element_t first(const Storage_t &d) { return d[0]; }
  static Element_t last(const Storage_t &d) { return d[0] + d[1]; }
  static Element_t stride(const Storage_t &d) { return d[1]; }
  static Element_t length(const Storage_t &d) { return d[1]; }
  static Element_t min(const Storage_t &d) {
    return (length(d) >= 0 ? first(d) : last(d));
  }
  static Element_t max(const Storage_t &d) {
    return (length(d) >= 0 ? last(d) : first(d));
  }
  static bool empty(const Storage_t &d) { return false; }
  static int loop(const Storage_t &) { return 0; }
  static Element_t elem(const Storage_t &d, int n) { return d[0] + n*d[1]; }
  static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
  static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
  static void initializeStorage(Storage_t &dom) {
    dom[0] = 0;
    dom[1] = 0;
  }
  template<class DT>
  static void setDomain(Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    dom[0] = DomainTraits<DT>::getFirst(newdom);
    dom[1] = DomainTraits<DT>::getLast(newdom) - dom[0];
  }
  static void setDomain(Storage_t &dom, Element_t begval, Element_t endval) {
    dom[0] = begval;
    dom[1] = (endval - begval);
  }
  static void setLoop(Storage_t &, int) { }
  template<class UT, class DT>
  static void setWildcardDomain(Storage_t &dom, const UT &u, const DT &newdom)
  {
    PoomaCTAssert<(DomainTraits<DT>::wildcard)>::test();
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
    dom[0] = newdom.first(u);
    dom[1] = newdom.last(u) - dom[0];
  }
  template<class DT>
  static bool isLessThan(const Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    return (dom[1] < DomainTraits<DT>::getLength(newdom) ||
     (dom[1] == DomainTraits<DT>::getLength(newdom) &&
      dom[0] < DomainTraits<DT>::getFirst(newdom)));
  }
  template<class DT>
  static bool isEqualTo(const Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    return (dom[0] == DomainTraits<DT>::getFirst(newdom) &&
     dom[1] == DomainTraits<DT>::getLength(newdom));
  }
  template<class DT>
  static void addAccum(Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    dom[0] += DomainTraits<DT>::getFirst(newdom);
  }
  template<class DT>
  static void subtractAccum(Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::singleValued)>::test();
    PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
    dom[0] -= DomainTraits<DT>::getFirst(newdom);
  }
  template<class DT>
  static void multiplyAccum(Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::singleValued && DomainTraits<DT>::dimensions == 1)>::test();
    dom[0] *= DomainTraits<DT>::getFirst(newdom);
    dom[1] *= DomainTraits<DT>::getFirst(newdom);
  }
  template<class DT>
  static void divideAccum(Storage_t &dom, const DT &newdom) {
    PoomaCTAssert<(DomainTraits<DT>::singleValued && DomainTraits<DT>::dimensions == 1)>::test();
    dom[0] /= DomainTraits<DT>::getFirst(newdom);
    dom[1] /= DomainTraits<DT>::getFirst(newdom);
  }
  static void initializeIterator(const Storage_t &d, IteratorStorage_t &i) {
    i[0] = d[0];
    i[1] = d[1];
  }
  static void initializeIterator(const Storage_t &d1, const Storage_t &d2,
     IteratorStorage_t &i) {
    i[0] = d1[0] + d2[1] + d2[1];
    i[1] = d2[1];
  }
  static void copyIterator(IteratorStorage_t d, IteratorStorage_t &i) {
    i[0] = d[0];
    i[1] = d[1];
  }
  static Element_t currentIterator(IteratorStorage_t i) { return i[0]; }
  static bool compareIterator(IteratorStorage_t a, IteratorStorage_t b) {
    return (a[0] == b[0] && a[1] == b[1]);
  }
  static void incrementIterator(IteratorStorage_t &i) { i[0] += i[1]; }
  static void decrementIterator(IteratorStorage_t &i) { i[0] -= i[1]; }
};
template<int Dim1, int Dim2, class T>
struct DomainChangeDim<Region<Dim1,T>, Dim2>
{
  typedef Region<Dim1,T> OldType_t;
  typedef Region<Dim2,T> NewType_t;
  enum { oldDim = Dim1,
  newDim = Dim2 };
};
template<int Dim, class T = double>
class Region : public Domain<Dim, DomainTraits<Region<Dim,T> > >
{
  typedef DomainTraits< Region<Dim,T> > DT_t;
  typedef Domain<Dim, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Region() { }
  Region(const Pooma::NoInit &e)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(e) {
  }
  Region(const Region<Dim,T> &a)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain1<Region<Dim,T> >::fill(*this, a);
  }
  template<class T1>
  explicit Region(const T1 &a)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain1<T1>::fill(*this, a);
  }
  template<class T1, class T2>
  Region(const T1 &a, const T2 &b)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain2<T1,T2>::fill(*this, a, b);
  }
  template<class T1, class T2, class T3>
  Region(const T1 &a, const T2 &b, const T3 &c)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
  }
  template<class T1, class T2, class T3, class T4>
  Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
  }
  template<class T1, class T2, class T3, class T4, class T5>
  Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(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>
  Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
 const T6 &f)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(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>
  Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
 const T6 &f, const T7 &g)
    : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
    NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
  }
  ~Region() { }
  template<class T1>
  Region<Dim,T> &operator=(const T1 &newdom) {
    return NewDomain1<T1>::fill(*this, newdom);
  }
  Region<Dim,T> &operator=(const Region<Dim,T> &newdom) {
    return NewDomain1<Region<Dim,T> >::fill(*this, newdom);
  }
protected:
private:
};
template<class T>
class Region<1,T> : public Domain<1, DomainTraits<Region<1,T> > >
{
  typedef DomainTraits< Region<1,T> > DT_t;
  typedef Domain<1, DT_t> Base_t;
public:
  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;
  enum { domain = DT_t::domain };
  enum { dimensions = DT_t::dimensions,
  sliceDimensions = DT_t::sliceDimensions };
  enum { loopAware = DT_t::loopAware };
  enum { singleValued = DT_t::singleValued };
  enum { unitStride = DT_t::unitStride };
  enum { wildcard = DT_t::wildcard };
  Region() { }
  Region(const Pooma::NoInit &e)
    : Domain<1, DomainTraits<Region<1,T> > >(e) {
  }
  Region(const Region<1,T> &a)
    : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
    NewDomain1<Region<1,T> >::fill(*this, a);
  }
  template<class T1>
  explicit Region(const T1 &a)
    : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
    NewDomain1<T1>::fill(*this, a);
  }
  Region(Element_t n)
    : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
    DomainTraits<Region<1,T> >::setDomain(this->domain_m, 0, n);
  }
  Region(Element_t m, Element_t n)
    : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
    DomainTraits<Region<1,T> >::setDomain(this->domain_m, m, n);
  }
  Region(Element_t m, Element_t n, Element_t)
    : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
    DomainTraits<Region<1,T> >::setDomain(this->domain_m, m, n);
  }
  template<class T1>
  Region<1,T> &operator=(const T1 &newdom) {
    return NewDomain1<T1>::fill(*this, newdom);
  }
  Region<1,T> &operator=(const Region<1,T> &newdom) {
    return NewDomain1<Region<1,T> >::fill(*this, newdom);
  }
  const OneDomain_t &operator[](int d) const { return *this; }
  OneDomain_t &operator[](int d) { return *this; }
};
template <int Dim, int C>
struct DomainDelta;
struct DomainDeltaStorage {};
template <int Dim, int C>
struct DomainTraits< DomainDelta<Dim, C> >
  : public DomainTraitsDomain<DomainDelta<Dim, C>, int, Dim>
{
  typedef DomainTraitsDomain<DomainDelta<Dim, C>, int, Dim> Base_t;
  typedef typename Base_t::Element_t Element_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef typename Base_t::NewDomain1_t NewDomain1_t;
  typedef DomainDelta<1, C> OneDomain_t;
  typedef DomainDelta<1, C> PointDomain_t;
  typedef DomainDelta<Dim, C> BlockDomain_t;
  typedef DomainDelta<Dim, C> AskDomain_t;
  typedef Loc<Dim> AddResult_t;
  typedef Loc<Dim> MultResult_t;
  typedef DomainDeltaStorage Storage_t;
  enum { domain = Base_t::domain };
  enum { dimensions = Base_t::dimensions,
  sliceDimensions = 0 };
  enum { loopAware = false };
  enum { singleValued = true };
  enum { unitStride = true };
  enum { wildcard = false };
  inline static void initializeStorage(Storage_t &dom) { }
  inline static OneDomain_t getDomain(const Domain_t &d, int) { return OneDomain_t(); }
  inline static PointDomain_t getPointDomain(const Domain_t &d, int) { return PointDomain_t(); }
};
template <int Dim, int C>
class DomainDelta : public Domain<Dim, DomainTraits<DomainDelta<Dim, C> > > {
 public:
  enum { component = C };
  inline DomainDelta()
    : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(Pooma::NoInit()) {}
  inline DomainDelta(const DomainDelta<Dim, C>&)
    : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(Pooma::NoInit()) {}
  inline DomainDelta(const Pooma::NoInit &a)
    : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(a) {}
  inline ~DomainDelta() {}
  inline DomainDelta<Dim, C> &operator=(const DomainDelta<Dim, C>&) { return *this; }
};
template<class T, int Dim, int C>
inline typename T::AddResult_t
operator+(const DomainBase<T> &d1, const DomainDelta<Dim, C> &d2) {
  typename T::AddResult_t retval(d1.unwrap());
  return (retval += d2);
}
template<class T, int Dim, int C>
inline typename T::AddResult_t
operator-(const DomainBase<T> &d1, const DomainDelta<Dim, C> &d2) {
  typename T::AddResult_t retval(d1.unwrap());
  return (retval -= d2);
}
template<int Dim>
class AllDomain
{
public:
  typedef AllDomain<Dim> Domain_t;
  typedef AllDomain<Dim> NewDomain1_t;
  typedef AllDomain<1> OneDomain_t;
  typedef int Element_t;
  enum { dimensions = Dim };
  AllDomain() {
    PoomaCTAssert<(Dim > 0)>::test();
  }
  AllDomain(const AllDomain<Dim> &) {
    PoomaCTAssert<(Dim > 0)>::test();
  }
  ~AllDomain() { }
  OneDomain_t operator[](int) const { return OneDomain_t(); }
  void setDomain(const AllDomain<Dim> &) { }
  template<class T>
  typename DomainTraits<T>::Element_t first(const T &u) const {
    return u.first();
  }
  int first(int u) const { return u; }
  template<class T>
  typename DomainTraits<T>::Element_t length(const T &u) const {
    return u.length();
  }
  int length(int) const { return 1; }
  template<class T>
  typename DomainTraits<T>::Element_t stride(const T &u) const {
    return u.stride();
  }
  int stride(int) const { return 1; }
  AllDomain<Dim> &operator=(const AllDomain<Dim> &) { return *this; }
protected:
private:
};
template<int Dim>
struct DomainTraits< AllDomain<Dim> >
{
  typedef AllDomain<Dim> Domain_t;
  typedef AllDomain<Dim> NewDomain1_t;
  typedef AllDomain<1> OneDomain_t;
  typedef AllDomain<1> PointDomain_t;
  typedef AllDomain<Dim> AskDomain_t;
  enum { domain = true };
  enum { dimensions = Dim,
  sliceDimensions = Dim };
  enum { wildcard = true };
  enum { singleValued = false };
  static OneDomain_t getDomain(const Domain_t &, int) {
    return OneDomain_t();
  }
  static PointDomain_t getPointDomain(const Domain_t &, int) {
    return PointDomain_t();
  }
};
template<int Dim>
class LeftDomain
{
public:
  typedef LeftDomain<Dim> Domain_t;
  typedef LeftDomain<1> OneDomain_t;
  typedef int Element_t;
  enum { dimensions = Dim };
  LeftDomain() : endpoints_m(Pooma::NoInit()) { PoomaCTAssert<(Dim > 0)>::test(); }
  LeftDomain(const LeftDomain<Dim> &d) : endpoints_m(d.endpoints_m) {
    PoomaCTAssert<(Dim > 0)>::test();
  }
  template<class T1>
  explicit LeftDomain(const T1 &a)
    : endpoints_m(a) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2>
  LeftDomain(const T1 &a, const T2 &b)
    : endpoints_m(a,b) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3>
  LeftDomain(const T1 &a, const T2 &b, const T3 &c)
    : endpoints_m(a,b,c) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4>
  LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
    : endpoints_m(a,b,c,d) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5>
  LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
    : endpoints_m(a,b,c,d,e) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6>
  LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f)
    : endpoints_m(a,b,c,d,e,f) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6, class T7>
  LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f, const T7 &g)
    : endpoints_m(a,b,c,d,e,f,g) { PoomaCTAssert<(Dim > 0)>::test(); }
  ~LeftDomain() { }
  OneDomain_t operator[](int n) const { return OneDomain_t(endpoints_m[n]); }
  void setDomain(const LeftDomain<Dim> &d) { endpoints_m = d.endpoints_m; }
  template<class T>
  typename DomainTraits<T>::Element_t first(const T &u) const {
    return u.first();
  }
  int first(int u) const { return u; }
  template<class T>
  typename DomainTraits<T>::Element_t length(const T &u) const {
    PoomaCTAssert<(Dim == 1)>::test();
    T dom(u.first(), endpoints_m[0].first(), u.stride());
    return dom.length();
  }
  int length(int u) const {
    PoomaCTAssert<(Dim == 1)>::test();
    Interval<1> dom(u, endpoints_m[0].first());
    return dom.length();
  }
  template<class T>
  typename DomainTraits<T>::Element_t stride(const T &u) const {
    return u.stride();
  }
  int stride(int) const { return 1; }
  LeftDomain<Dim> &operator=(const LeftDomain<Dim> &d) {
    endpoints_m = d.endpoints_m;
    return *this;
  }
protected:
private:
  Loc<Dim> endpoints_m;
};
template<int Dim>
struct DomainTraits< LeftDomain<Dim> >
{
  typedef LeftDomain<Dim> Domain_t;
  typedef LeftDomain<1> OneDomain_t;
  typedef LeftDomain<1> PointDomain_t;
  typedef LeftDomain<Dim> AskDomain_t;
  enum { domain = true };
  enum { dimensions = Dim,
  sliceDimensions = Dim };
  enum { wildcard = true };
  enum { singleValued = false };
  static OneDomain_t getDomain(const Domain_t &d, int n) {
    return d[n];
  }
  static PointDomain_t getPointDomain(const Domain_t &d, int n) {
    return d[n];
  }
};
template<int Dim>
class RightDomain
{
public:
  typedef RightDomain<Dim> Domain_t;
  typedef RightDomain<1> OneDomain_t;
  typedef int Element_t;
  enum { dimensions = Dim };
  RightDomain() : endpoints_m(Pooma::NoInit()) { PoomaCTAssert<(Dim > 0)>::test(); }
  RightDomain(const RightDomain<Dim> &d) : endpoints_m(d.endpoints_m) {
    PoomaCTAssert<(Dim > 0)>::test();
  }
  template<class T1>
  explicit RightDomain(const T1 &a)
    : endpoints_m(a) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2>
  RightDomain(const T1 &a, const T2 &b)
    : endpoints_m(a,b) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3>
  RightDomain(const T1 &a, const T2 &b, const T3 &c)
    : endpoints_m(a,b,c) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4>
  RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
    : endpoints_m(a,b,c,d) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5>
  RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
    : endpoints_m(a,b,c,d,e) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6>
  RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f)
    : endpoints_m(a,b,c,d,e,f) { PoomaCTAssert<(Dim > 0)>::test(); }
  template<class T1, class T2, class T3, class T4, class T5,
           class T6, class T7>
  RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
      const T6 &f, const T7 &g)
    : endpoints_m(a,b,c,d,e,f,g) { PoomaCTAssert<(Dim > 0)>::test(); }
  ~RightDomain() { }
  OneDomain_t operator[](int n) const { return OneDomain_t(endpoints_m[n]); }
  void setDomain(const RightDomain<Dim> &d) { endpoints_m = d.endpoints_m; }
  template<class T>
  typename DomainTraits<T>::Element_t first(const T &u) const {
    return endpoints_m[0].first();
  }
  int first(int u) const { return u; }
  template<class T>
  typename DomainTraits<T>::Element_t length(const T &u) const {
    PoomaCTAssert<(Dim == 1)>::test();
    T dom(endpoints_m[0].first(), u.last(), u.stride());
    return dom.length();
  }
  int length(int u) const {
    PoomaCTAssert<(Dim == 1)>::test();
    Interval<1> dom(endpoints_m[0].first(), u);
    return dom.length();
  }
  template<class T>
  typename DomainTraits<T>::Element_t stride(const T &u) const {
    return u.stride();
  }
  int stride(int) const { return 1; }
  RightDomain<Dim> &operator=(const RightDomain<Dim> &d) {
    endpoints_m = d.endpoints_m;
    return *this;
  }
protected:
private:
  Loc<Dim> endpoints_m;
};
template<int Dim>
struct DomainTraits< RightDomain<Dim> >
{
  typedef RightDomain<Dim> Domain_t;
  typedef RightDomain<1> OneDomain_t;
  typedef RightDomain<1> PointDomain_t;
  typedef RightDomain<Dim> AskDomain_t;
  enum { domain = true };
  enum { dimensions = Dim,
  sliceDimensions = Dim };
  enum { wildcard = true };
  enum { singleValued = false };
  static OneDomain_t getDomain(const Domain_t &d, int n) {
    return d[n];
  }
  static PointDomain_t getPointDomain(const Domain_t &d, int n) {
    return d[n];
  }
};
template<class T1, class T2, class T3, int Dim, bool strided>
struct EquivSubsetDomainSingle {
  static void equiv(const T1 &a, const T2 &b, T3 &d) {
    d[Dim-1] += (b.first() - a.first());
  }
};
template<class T1, class T2, class T3, int Dim>
struct EquivSubsetDomainSingle<T1,T2,T3,Dim,true> {
  static void equiv(const T1 &a, const T2 &b, T3 &d) {
    typedef typename DomainTraits<T3>::Element_t E3_t;
    E3_t m = b.stride() / a.stride();
    ;
    E3_t k = b.first() - m * a.first();
    d[Dim-1] *= m;
    d[Dim-1] += k;
  }
};
template<class T1, class T2, class T3, int Dim>
struct EquivSubsetDomain {
  enum { strided = !DomainTraits<T3>::unitStride };
  static void equiv(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    EquivSubsetDomainSingle<Dom1_t,Dom2_t,T3,Dim,strided>::equiv(
      DomainTraits<T1>::getDomain(a,Dim-1),
      DomainTraits<T2>::getDomain(b,Dim-1), c);
    EquivSubsetDomain<T1,T2,T3,Dim-1>::equiv(a,b,c);
  }
};
template<class T1, class T2, class T3>
struct EquivSubsetDomain<T1,T2,T3,1> {
  enum { strided = !DomainTraits<T3>::unitStride };
  static void equiv(const T1 &a, const T2 &b, T3 &c) {
    typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
    typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
    EquivSubsetDomainSingle<Dom1_t,Dom2_t,T3,1,strided>::equiv(
      DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0), c);
  }
};
template<class T1, class T2, class T3>
struct EquivSubsetReturnType {
  typedef typename NewDomain3<T1,T2,T3>::Type_t Combine_t;
  typedef typename
    DomainChangeDim<Combine_t,DomainTraits<T1>::dimensions>::NewType_t Type_t;
};
template<class T1, class T2, class T3>
inline typename EquivSubsetReturnType<T1,T2,T3>::Type_t
equivSubset(const T1 &a, const T2 &b, const T3 &c)
{
  typedef typename EquivSubsetReturnType<T1,T2,T3>::Type_t T4;
  PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
  PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T3>::dimensions)>::test();
  T4 d = c;
  EquivSubsetDomain<T1,T2,T4,DomainTraits<T1>::dimensions>::equiv(a, b, d);
  return d;
}
namespace Pooma {
class Tester
{
public:
  Tester();
  Tester(int argc, char **argv);
  ~Tester();
  inline Inform &out()
    {
      return inform_m;
    }
  inline bool ok() const
    {
      return ok_m;
    }
  inline int returnValue() const
    {
      return (ok() ? 0 : 1);
    }
  inline bool check(bool val)
    {
      ok_m = (ok_m && val);
      if (!ok_m && abort_m)
        {
          if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Check failed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/Tester.h", 163);
        }
      return val;
    }
  inline bool check(const char *str, bool val)
    {
      check(val);
      if (str != 0)
 out() << "Checking " << str;
      else
 out() << "Checking";
      out() << ": check = " << val << ", updated status = " << ok_m;
      out() << std::endl;
      return val;
    }
  template<class T>
  bool check(const char *str, const T &val, const T &correct)
    {
      bool res = check(val == correct);
      if (str != 0)
 out() << "Checking " << str;
      else
 out() << "Checking";
      out() << ": val = " << val << ", correct = " << correct
            << ", updated status = " << ok_m;
      out() << std::endl;
      return res;
    }
  template<class T>
  bool check(const char *str, const T &val, const T &correct,
    const T &tol)
    {
      bool res = check(std::abs(val - correct) < tol);
      if (str != 0)
 out() << "Checking " << str;
      else
 out() << "Checking";
      out() << ": val = " << val << ", correct = " << correct
            << ", updated status = " << ok_m;
      out() << std::endl;
      return res;
    }
  inline void set(bool val)
    {
      ok_m = val;
    }
  inline void setQuiet(bool quiet) {
    quiet_m = quiet;
    if (!verbose_m || quiet_m) {
      out().setOutputLevel(Inform::off);
    } else {
      out().setOutputLevel(Inform::on);
    }
  }
  inline void setVerbose(bool verbose) {
    verbose_m = verbose;
    if (!verbose_m || quiet_m) {
      out().setOutputLevel(Inform::off);
    } else {
      out().setOutputLevel(Inform::on);
    }
  }
  inline bool verbose() { return verbose_m; }
  inline void setPrefix(char *prefix) { out().setPrefix(prefix); }
  int results(const char *msg = 0) const;
  void exceptionHandler(const char *msg = 0);
  void exceptionHandler(const Assertion &asrt);
private:
  bool ok_m;
  bool quiet_m;
  Inform inform_m;
  bool verbose_m;
  bool abort_m;
  void parse(int argc, char **argv);
};
}
template <int Dim>
std::vector<Interval<Dim> >
DomainRemoveOverlap(const Interval<Dim> & s,const Interval<Dim> &r)
{
  typedef Interval<Dim> Domain_t;
  typedef std::vector<Domain_t> DomainList_t;
  DomainList_t result,temp;
  result.push_back(s);
  for (int i=0;i<Dim;++i)
    {
      typename DomainList_t::iterator start = result.begin();
      typename DomainList_t::iterator end = result.end();
      for ( ; start!=end; ++start)
 {
   if (touches( (*start)[i], Loc<1>(r[i].min())))
     {
       Domain_t lower=*start,upper=*start;
       if(r[i].min()-1>=lower[i].min())
  {
    lower[i] = Interval<1>(lower[i].min(),r[i].min()-1);
    temp.push_back(lower);
  } upper[i] = Interval<1>(r[i].min(),upper[i].max());
       temp.push_back(upper);
     }
   else
     temp.push_back(*start);
 }
      result = temp;
      temp.clear();
      start = result.begin();
      end = result.end();
      for ( ; start!=end; ++start)
 {
   if (touches( (*start)[i], Loc<1>(r[i].max())))
     {
       Domain_t lower=*start,upper=*start;
       lower[i] = Interval<1>(lower[i].min(),r[i].max());
       temp.push_back(lower);
       if( r[i].max()+1 <= upper[i].max())
  {
    upper[i] = Interval<1>(r[i].max()+1,upper[i].max());
    temp.push_back(upper);
  }
     }
   else
     temp.push_back(*start);
 }
      result=temp;
      temp.clear();
    }
  typename DomainList_t::iterator start = result.begin();
  typename DomainList_t::iterator end = result.end();
  for ( ; start!=end ; ++start)
    {
      if (!touches(*start,r ) )
 temp.push_back(*start);
    }
  return temp;
}
template <int Dim>
Grid<Dim> makeRGrid(const Interval<Dim> & gdom, const Loc<Dim> & blocks);
template<int Dim>
class UniformGridPartition;
template<int Dim>
class GridPartition
{
public:
  typedef LocalMapper<Dim> DefaultMapper_t;
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  enum { uniform = false };
  enum { gridded = true };
  enum { tile = false };
  enum { general = false };
  enum { dimensions = Dim };
  GridPartition(const Grid<Dim> &g)
    : hasInternalGuards_m(false),
      hasExternalGuards_m(false),
      internalGuards_m(0),
      externalGuards_m(0),
      grid_m(g)
  {
    num_m=1;
    for (int i=0;i<Dim;i++)
      {
 blocks_m[i] = Loc<1>(grid_m[i].size()-1);
 num_m*=blocks_m[i].first();
      }
  }
  GridPartition(const Grid<Dim> &g,
  const GuardLayers<Dim> &gcs)
    : hasInternalGuards_m(true),
      hasExternalGuards_m(true),
      internalGuards_m(gcs),
      externalGuards_m(gcs),
      grid_m(g)
  {
    num_m=1;
    for (int i=0;i<Dim;i++)
      {
 blocks_m[i] = Loc<1>(grid_m[i].size()-1);
 num_m*=blocks_m[i].first();
      }
  }
  GridPartition(const Grid<Dim> &g,
  const GuardLayers<Dim> &igcs,
  const GuardLayers<Dim> &egcs)
    : hasInternalGuards_m(true),
      hasExternalGuards_m(true),
      internalGuards_m(igcs),
      externalGuards_m(egcs),
      grid_m(g)
  {
    num_m=1;
    for (int i=0;i<Dim;i++)
      {
 blocks_m[i] = Loc<1>(grid_m[i].size()-1);
 num_m*=(grid_m[i].size()-1);
      }
  }
  GridPartition()
    : hasInternalGuards_m(false),
      hasExternalGuards_m(false),
      internalGuards_m(0),
      externalGuards_m(0),
      num_m(1)
  {
    for (int i=0;i<Dim;++i)
      blocks_m[i]=Loc<1>(1);
  }
  GridPartition(const Loc<Dim> &a)
    : blocks_m(a),
      hasInternalGuards_m(false),
      hasExternalGuards_m(false),
      internalGuards_m(0),
      externalGuards_m(0)
  {
    num_m = blocks_m[0].first();
    for (int d=1; d < Dim; ++d)
      num_m *= blocks_m[d].first();
  }
  GridPartition(const Loc<Dim> &a,
  const GuardLayers<Dim> &gcs)
    : blocks_m(a),
      hasInternalGuards_m(true),
      hasExternalGuards_m(true),
      internalGuards_m(gcs),
      externalGuards_m(gcs)
  {
    num_m = blocks_m[0].first();
    for (int d=1; d < Dim; ++d)
      num_m *= blocks_m[d].first();
  }
  GridPartition(const Loc<Dim> &a,
  const GuardLayers<Dim> &igcs,
  const GuardLayers<Dim> &egcs)
    : blocks_m(a),
      hasInternalGuards_m(true),
      hasExternalGuards_m(true),
      internalGuards_m(igcs),
      externalGuards_m(egcs)
  {
    num_m = blocks_m[0].first();
    for (int d=1; d < Dim; ++d)
      num_m *= blocks_m[d].first();
  }
  GridPartition(const GridPartition<Dim> & b)
    : blocks_m(b.blocks_m),
      hasInternalGuards_m(b.hasInternalGuards_m),
      hasExternalGuards_m(b.hasExternalGuards_m),
      internalGuards_m(b.internalGuards_m),
      externalGuards_m(b.externalGuards_m),
      num_m(b.num_m),
      grid_m(b.grid_m)
  {
  }
 GridPartition(const UniformGridPartition<Dim> & b)
   : blocks_m(b.blocks_m),
     hasInternalGuards_m(b.hasInternalGuards_m),
     hasExternalGuards_m(b.hasExternalGuards_m),
     internalGuards_m(b.internalGuards_m),
     externalGuards_m(b.externalGuards_m),
     num_m(b.num_m)
  {}
  ~GridPartition() { }
  GridPartition<Dim> &operator=(const GridPartition<Dim> &g)
  {
    if (this != &g)
      {
 hasInternalGuards_m = g.hasInternalGuards_m;
 hasExternalGuards_m = g.hasExternalGuards_m;
 internalGuards_m = g.internalGuards_m;
 externalGuards_m = g.externalGuards_m;
 blocks_m = g.blocks();
 num_m = g.maxSize();
 grid_m = g.grid();
 if (!hasInternalGuards_m)
   internalGuards_m = GuardLayers<Dim>(0);
 if (!hasExternalGuards_m)
   externalGuards_m = GuardLayers<Dim>(0);
      }
    return *this;
  }
  int maxSize() const { return num_m; }
  const Loc<Dim> &blocks() const { return blocks_m; }
  bool hasGuards() const { return hasInternalGuards_m||hasExternalGuards_m; }
  bool hasCustomEdgeGuards() const
  {
    if (hasInternalGuards_m&&!hasExternalGuards_m) return true;
    if (!hasInternalGuards_m&&hasExternalGuards_m) return true;
    if (hasInternalGuards_m&&hasExternalGuards_m
       &&(internalGuards_m!=externalGuards_m)) return true;
    return false;
  }
  bool hasInternalGuards() const { return hasInternalGuards_m; }
  bool hasExternalGuards() const { return hasExternalGuards_m;}
  const Grid<Dim> &grid() const { return grid_m;}
  const GuardLayers<Dim> &internalGuards() const
  {
    return internalGuards_m;
  }
  const GuardLayers<Dim> &externalGuards() const
  {
    return externalGuards_m;
  }
  template<class D>
  int partition(const D &domain,
  List_t & all,
  const ContextMapper<Dim> &cmapper ) const;
  template<class D>
  int partition(const D &domain,
  List_t & all) const
  {
    return partition(domain,all,DefaultMapper_t(*this));
  }
  template<class Out>
  void print(Out &o) const;
private:
  Loc<Dim> blocks_m;
  bool hasInternalGuards_m;
  bool hasExternalGuards_m;
  GuardLayers<Dim> internalGuards_m;
  GuardLayers<Dim> externalGuards_m;
  int num_m;
  Grid<Dim> grid_m;
};
template<int Dim>
template<class D>
int GridPartition<Dim>::partition(const D &domain,
      List_t & all,
      const ContextMapper<Dim> &cmapper ) const
{
  typedef typename DomainTraits<Domain_t>::Element_t Element_t;
  PoomaCTAssert<(Dim == DomainTraits<D>::dimensions)>::test();
  PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
  Grid<Dim> tgrid = grid();
  if (domain.empty())
    {
      int np = 1;
      for (int i=0;i<Dim;++i)
 np*=blocks()[i].first();
      int start=0;
      Domain_t o;
      Domain_t a;
      while (start<np)
 {
   int gid = all.size();
   int lid = -1;
   Value_t *node = new Value_t(o, a, -1, gid, lid);
   all.push_back(node);
   ++start;
 }
      cmapper.map(all);
      return maxSize();
    }
  if (tgrid.empty()&&!domain.empty() )
    {
      tgrid = makeRGrid(domain,blocks_m);
    }
  typename Grid<Dim>::blockIterator start = tgrid.beginBlock();
  typename Grid<Dim>::blockIterator end = tgrid.endBlock();
  while (start!=end)
    {
      Loc<Dim> idx = start.point();
      Domain_t o = Pooma::NoInit();
      o = * start;
      Domain_t a = Pooma::NoInit();
      a = * start;
      if (hasInternalGuards()||hasExternalGuards())
 {
   for (int i=0;i<Dim;i++)
     {
       if (idx[i]==0)
  {
    if (hasExternalGuards())
      {
        o[i]=Interval<1>(o[i].first()-externalGuards().lower(i),
           o[i].last());
        a[i]=Interval<1>(a[i].first()-externalGuards().lower(i),
           a[i].last());
      }
    if (hasInternalGuards() && idx[i]!=(blocks()[i].first()-1))
      a[i]=Interval<1>(a[i].first(),
         a[i].last()+internalGuards().upper(i));
  }
       if (idx[i]==blocks()[i].first()-1)
  {
    if (hasExternalGuards())
      {
        o[i]=Interval<1>(o[i].first(),
           o[i].last()+externalGuards().upper(i));
        a[i]=Interval<1>(a[i].first(),
           a[i].last()+externalGuards().upper(i));
      }
    if (hasInternalGuards()&&(idx[i]!=0))
      a[i]=Interval<1>(a[i].first()-internalGuards().lower(i),
         a[i].last());
  }
       if (idx[i]!=0&&
    idx[i]!=(blocks()[i].first()-1)&&
    hasInternalGuards())
  a[i]=Interval<1>(o[i].first()-internalGuards().lower(i),
     o[i].last()+internalGuards().upper(i));
     }
 }
      int gid = all.size();
      int lid = -1;
      Value_t *node = new Value_t(o, a, -1, gid, lid);
      all.push_back(node);
      ++start;
    }
  cmapper.map(all);
  return maxSize();
}
template<int Dim>
template<class Out>
void GridPartition<Dim>::print(Out &o) const
{
  int i;
  o << "GridPartition<" << Dim << ">:" << std::endl;
  o << "  blocks_m = " << blocks_m << std::endl;
  o << "  hasInternalGuards_m  hasExternalGuards_m = ";
  o << hasInternalGuards_m<< " "<<hasExternalGuards_m<< std::endl;
  o << "  internalGuards_m:" << std::endl;
  o << "      upper       ";
  for (i=0; i < Dim; ++i)
    o << internalGuards_m.upper(i) << " ";
  o << std::endl;
  o << "      lower       ";
  for (i=0; i < Dim; ++i)
    o << internalGuards_m.lower(i) << " ";
  o << std::endl;
  o << "  externalGuards_m:" << std::endl;
  o << "      upper       ";
  for (i=0; i < Dim; ++i)
    o << externalGuards_m.upper(i) << " ";
  o << std::endl;
  o << "      lower       ";
  for (i=0; i < Dim; ++i)
    o << externalGuards_m.lower(i) << " ";
  o << std::endl;
  o << "  num_m = " << num_m << std::endl;
  o << "  grid_m = ";
  if (grid_m.empty() )
    o << "(empty)" << std::endl;
  else
    o << grid_m << std::endl;
}
template <int Dim>
std::ostream &operator<<(std::ostream &o, const GridPartition<Dim> &gp)
{
  gp.print(o);
  return o;
}
template <int Dim>
Grid<Dim> makeRGrid(const Interval<Dim> &gdom, const Loc<Dim> &blocks)
{
  Grid<Dim> ret;
  for (int i=0;i<Dim;++i)
    {
      if (gdom[i].size()%blocks[i].first()==0&& !gdom[i].empty())
 {
   ret[i]=Grid<1>(Range<1>(gdom[i].first(),
      gdom[i].last()+1,
      (int) gdom[i].size()/blocks[i].first()));
 }
      else if (!gdom[i].empty() )
 {
   IndirectionList<int> rret(blocks[i].first()+1);
   rret(0) = gdom[i].first();
   for (int j = 1;j<blocks[i].first()+1;++j)
     {
       int temp = (int) gdom[i].size()/blocks[i].first();
       rret(j)= rret(j-1) + temp ;
       rret(j) += (j > (blocks[i].first() -
          (gdom[i].size()- temp*blocks[i].first()) ) );
     }
   ret[i]=Grid<1>(rret);
 }
      else
 {
 }
    }
  return ret;
}
template <typename T>
std::vector<T> makeRBlocksFactor(T number)
{
  std::vector<T> factors;
  for (T f=2; f<number; f++) {
    while (number % f == 0) {
      factors.push_back(f);
      number /= f;
    }
  }
  if (number != 1)
    factors.push_back(number);
  return factors;
}
template <int Dim>
Loc<Dim> makeRBlocks(const Interval<Dim>& domain, int nodes)
{
  typedef typename std::vector<int>::reverse_iterator riterator_t;
  std::vector<int> df[Dim];
  std::vector<int> nf;
  for (int i=0; i<Dim; i++)
    df[i] = makeRBlocksFactor<int>(domain[i].size());
  nf = makeRBlocksFactor<int>(nodes);
  int setup[Dim];
  for (int i=0; i<Dim; i++)
    setup[i] = 1;
  int sdi[Dim];
  for (int i=0; i<Dim; i++)
    sdi[i] = i;
  for (riterator_t ni = nf.rbegin(); ni < nf.rend(); ni++) {
    bool changed;
    do {
      changed = false;
      for (int i=0; i<Dim-1; i++)
 if (domain[sdi[i]].size()/setup[sdi[i]]
     < domain[sdi[i+1]].size()/setup[sdi[i+1]]) {
   std::swap(sdi[i+1], sdi[i]);
   changed = true;
 }
    } while (changed);
    int i = sdi[0];
    riterator_t di;
    for (di = df[i].rbegin(); di < df[i].rend(); di++) {
      if ((*di) == (*ni)) {
 setup[i] *= (*ni);
 break;
      }
    }
    if (di == df[i].rend())
      setup[i] *= (*ni);
  }
  Loc<Dim> result;
  for (int i=0; i<Dim; i++)
    result[i] = setup[i];
  return result;
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData()
  : Observable<SparseTileLayoutData>(*this)
{
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
      const PatchList_t & PatchList,
      const ContextMapper<Dim> &cmap)
 : LayoutBaseData<Dim>(false,false,
         GuardLayers_t(0),GuardLayers_t(0),
         boundingbox,boundingbox),
   Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  initialize(boundingbox,PatchList,cmap);
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
      const GuardLayers_t & globalGL,
      const PatchList_t & PatchList,
      const ContextMapper<Dim> &cmap)
  : LayoutBaseData<Dim>(true,true,
   globalGL,globalGL,
   boundingbox,boundingbox),
  Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  initialize(boundingbox,globalGL,PatchList,cmap);
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
      const GuardLayers_t & internalGL,
      const GuardLayers_t & externalGL,
      const PatchList_t & PatchList,
      const ContextMapper<Dim> &cmap)
 : LayoutBaseData<Dim>(true,true,
   internalGL,externalGL,
         boundingbox,boundingbox),
  Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  initialize(boundingbox,internalGL,externalGL,PatchList,cmap );
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox)
  : LayoutBaseData<Dim>(false, false,
   GuardLayers_t(),GuardLayers_t(),
   boundingbox,boundingbox),
  Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  initialize(boundingbox);
}
template<int Dim>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
      const GuardLayers_t & internalGL,
      const GuardLayers_t & externalGL)
  : LayoutBaseData<Dim>(true, true,
   internalGL,externalGL,
   boundingbox,boundingbox),
  Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  initialize(boundingbox,internalGL,externalGL);
}
template<int Dim>
template<class Partitioner>
SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &bbox,
      const Partitioner &gpar,
      const ContextMapper<Dim> &cmap)
   : LayoutBaseData<Dim>(false,false,
     GuardLayers_t(0),GuardLayers_t(0),
     bbox,bbox),
    Observable<SparseTileLayoutData>(*this)
{
  this->blocks_m = Loc<Dim>();
  if (gpar.hasInternalGuards() && gpar.maxSize() > 1)
    {
      this->hasInternalGuards_m = true;
      this->internalGuards_m = gpar.internalGuards();
    }
  if (gpar.hasExternalGuards())
    {
      this->hasExternalGuards_m = true;
      this->externalGuards_m = gpar.externalGuards();
      GuardLayers<Dim>::addGuardLayers(this->domain_m,this->externalGuards_m);
    }
  initialize(bbox, gpar,cmap);
}
template<int Dim>
SparseTileLayoutData<Dim>::~SparseTileLayoutData()
{
  for (typename List_t::iterator a = this->all_m.begin(); a != this->all_m.end(); ++a)
    delete (*a);
}
template<int Dim>
void SparseTileLayoutData<Dim>::syncPatch()
{
  typename List_t::iterator start = this->all_m.begin();
  typename List_t::iterator end = this->all_m.end();
  for ( ; start != end ; ++start)
    if ( (*start)->context() == Pooma::context()
  ||(*start)->context() == -1 )
      this->local_m.push_back(*start);
    else
      this->remote_m.push_back(*start);
   calcMaps();
   calcAllocMaps();
   calcGCFillList();
}
template<int Dim>
void SparseTileLayoutData<Dim>::calcMaps()
{
  if (!this->initialized())
    return;
  map_m.zap();
  map_m.initialize(this->domain_m);
  typename List_t::const_iterator start = this->all_m.begin();
  typename List_t::const_iterator end = this->all_m.end();
  int i=0;
  for ( ; start != end ; ++start, ++i )
    {
      pidx_t tmp((*start)->globalID(),i);
      typename DomainMap<Domain_t,pidx_t>::Value_t val((*start)->domain(),tmp);
      map_m.insert(val);
    }
  map_m.update();
}
template<int Dim>
void SparseTileLayoutData<Dim>::calcAllocMaps()
{
  if (!this->initialized())
    return;
  mapAloc_m.zap();
  mapAloc_m.initialize(this->domain_m);
  typename List_t::const_iterator start = this->all_m.begin();
  typename List_t::const_iterator end = this->all_m.end();
  int i=0;
  for ( ; start!=end ; ++start , ++i)
    {
      pidx_t tmp((*start)->globalID(),i);
      typename DomainMap<Domain_t,pidx_t>::Value_t val((*start)->allocated(),tmp);
      mapAloc_m.insert(val);
    }
  mapAloc_m.update();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom)
{
  this->blocks_m = Loc<Dim>();
  int i;
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  for(i=0;i<Dim;++i)
    this->firste_m[i] = this->firsti_m[i] = this->domain_m[i].first();
  this->domain_m = gdom;
  this->innerdomain_m = gdom;
  this->hasInternalGuards_m = this->hasExternalGuards_m = false;
  this->internalGuards_m = this->externalGuards_m = GuardLayers_t();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom,
        const GuardLayers_t & globalGL)
{
  this->blocks_m = Loc<Dim>();
  int i;
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  this->domain_m = gdom;
  this->innerdomain_m = gdom;
  for(i=0;i<Dim;++i)
    this->firsti_m[i] = this->domain_m[i].first();
  this->hasInternalGuards_m = this->hasExternalGuards_m=true;
  this->internalGuards_m = this->externalGuards_m = globalGL;
  GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
  for(i=0;i<Dim;++i)
    this->firste_m[i]=this->domain_m[i].first();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom,
         const GuardLayers_t & internalGL,
         const GuardLayers_t & externalGL)
{
  this->blocks_m = Loc<Dim>();
  int i;
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  this->domain_m = gdom;
  this->innerdomain_m = gdom;
  for(i=0;i<Dim;++i)
    this->firsti_m[i]=this->domain_m[i].first();
  this->hasInternalGuards_m = this->hasExternalGuards_m = true;
  this->internalGuards_m = internalGL;
  this->externalGuards_m = externalGL;
  GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
  for(i=0;i<Dim;++i)
    this->firste_m[i] = this->domain_m[i].first();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
        const PatchList_t &plist,
        const ContextMapper<Dim> &cmap)
{
  this->blocks_m = Loc<Dim>();
  initialize(bbox);
  TilePartition<Dim> gpar(plist);
  gpar.partition(bbox,this->all_m,cmap);
  syncPatch();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
        const GuardLayers_t & globalGL,
        const PatchList_t &plist,
        const ContextMapper<Dim> &cmap)
{
  this->blocks_m = Loc<Dim>();
  initialize(bbox,globalGL);
  TilePartition<Dim> gpar(bbox,plist,globalGL);
  gpar.partition(bbox,this->all_m,cmap);
  syncPatch();
}
template<int Dim>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
        const GuardLayers_t & internalGL,
        const GuardLayers_t & externalGL,
        const PatchList_t &plist,
        const ContextMapper<Dim> &cmap)
{
  this->blocks_m = Loc<Dim>();
  initialize(bbox,internalGL,externalGL);
  TilePartition<Dim> gpar(bbox,plist,internalGL,externalGL);
  gpar.partition(bbox,this->all_m,cmap);
  syncPatch();
}
template<int Dim>
template<class Partitioner>
void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
        const Partitioner &gpar,
        const ContextMapper<Dim> &cmap)
{
  this->blocks_m = Loc<Dim>();
  initialize(bbox,gpar.internalGuards(),gpar.externalGuards());
  gpar.partition(bbox,this->all_m,cmap);
  syncPatch();
}
template<int Dim>
void SparseTileLayoutData<Dim>::calcGCFillList()
{
  if(!this->initialized() || !this->hasInternalGuards_m)
    return;
  this->gcFillList_m.clear();
  gcBorderFillList_m.clear();
  typedef Node<Domain_t,AllocatedDomain_t> NNode_t;
  typedef std::vector<NNode_t> TouchList_t;
  TouchList_t tlist;
  typename List_t::iterator start = this->all_m.begin();
  typename List_t::iterator end = this->all_m.end();
  for ( ; start!=end; ++start)
    {
      touches((*start)->allocated(),
       std::back_inserter(tlist),
       TouchesConstructNodeObj());
      typename TouchList_t::iterator GCLstart = tlist.begin();
      typename TouchList_t::iterator GCLend = tlist.end();
      for( ; GCLstart != GCLend ;++GCLstart)
 {
   if(GCLstart->globalID() == (*start)->globalID())
     {
       tlist.erase(GCLstart);
       break;
     }
 }
      GCLstart = tlist.begin();
      GCLend = tlist.end();
      for ( ; GCLstart!=GCLend ; ++GCLstart )
 {
   this->gcFillList_m.push_back(GCFillInfo_t((*GCLstart).domain(),
          (*GCLstart).globalID(),
          (*start)->globalID()));
 }
      tlist.clear();
    }
  std::vector<GCBorderFillInfo> bfv;
  start = this->all_m.begin();
  for ( ; start!=this->all_m.end(); ++start)
    {
      for(int d=0;d<Dim;++d)
 {
   Domain_t gcdom( (*start)->allocated());
   int max = (*start)->allocated()[d].last();
   int min = max - this->internalGuards_m.upper(d) + 1;
   gcdom[d] = Interval<1>(min, max);
   gcdom = intersect(this->innerdomain_m,gcdom);
   if (gcdom.size()>0)
     {
       bfv.push_back(GCBorderFillInfo(gcdom, (*start)->globalID() ));
     }
   gcdom = (*start)->allocated();
   min = (*start)->allocated()[d].first();
   max = min + this->internalGuards_m.lower(d) -1;
    gcdom[d] = Interval<1>(min, max);
   gcdom = intersect(this->innerdomain_m,gcdom);
   if (gcdom.size() > 0)
   {
     bfv.push_back(GCBorderFillInfo(gcdom,(*start)->globalID()));
   }
 }
    }
  std::vector<Domain_t> temp2,temp3,temp4;
  std::vector<GCBorderFillInfo> temp;
  BorderFillIterator_t bst = bfv.begin();
  BorderFillIterator_t ben = bfv.end();
  for ( ; bst != ben ; ++bst)
    {
      FillIterator_t gst = this->beginFillList();
      FillIterator_t gen = this->endFillList();
      temp2.clear();
      temp2.push_back(bst->domain());
      for ( ; gst!=gen ; ++gst )
 {
   typename std::vector<Domain_t>::iterator ts = temp2.begin();
   for ( ; ts != temp2.end() ; ++ts )
     {
       temp3 = DomainRemoveOverlap(*ts,gst->domain_m);
       temp4.insert(temp4.end(),temp3.begin(),temp3.end());
     }
   temp2 = temp4;
   temp4.clear();
 }
      typename std::vector<Domain_t>::iterator ts = temp2.begin();
      for( ; ts != temp2.end(); ++ts)
 temp.push_back(GCBorderFillInfo(*ts, bst->patchID() ));
    }
  gcBorderFillList_m = temp;
}
template<int Dim>
int SparseTileLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
{
  ;
  DomainMapTouchIterator<Interval<Dim>,pidx_t> dmti =
 (map_m.touch(Interval<Dim>(loc))).first;
  DomainMapTouchIterator<Interval<Dim>,pidx_t> baditerator;
  if (__builtin_expect(!!(dmti!=baditerator), true)) {} else Pooma::toss_cookies("Bad location requested in SparseTileLayout", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/SparseTileLayout.cpp", 538);
  return (*dmti).first;
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4, int i5) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  loc[5] = i5;
  return globalID(loc);
}
template <int Dim>
int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4, int i5, int i6) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  loc[5] = i5;
  loc[6] = i6;
  return globalID(loc);
}
template<int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int SparseTileLayoutData<Dim>::touches(const OtherDomain &fulld,
           OutIter o,
           const ConstructTag &ctag) const
{
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t d = intersect(this->domain_m, fulld);
  if (d.empty())
    return 0;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename DomainMap<Interval<Dim>,pidx_t>::Touch_t dmti =
    map_m.touch(Interval<Dim>(d));
  typename DomainMap<Interval<Dim>,pidx_t>::touch_iterator a;
  int count = 0;
  for( a = dmti.first ;a != dmti.second; ++a)
    {
      int nodeListIndex = (*a).second;
      outDomain = intersect(a.domain(), fulld);
      ;
      *o = touchesConstruct(outDomain,
       this->all_m[nodeListIndex]->allocated(),
       this->all_m[nodeListIndex]->affinity(),
       this->all_m[nodeListIndex]->context(),
       this->all_m[nodeListIndex]->globalID(),
       this->all_m[nodeListIndex]->localID(),
       ctag);
      ++count;
    }
  return count;
}
template<int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int SparseTileLayoutData<Dim>::touchesAlloc(const OtherDomain &fulld,
         OutIter o,
         const ConstructTag &ctag) const
{
  int i;
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t d = intersect(this->domain_m, fulld);
  if (d.empty())
    return 0;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename DomainMap<Interval<Dim>,pidx_t>::Touch_t dmti = map_m.touch(d);
  typename DomainMap<Interval<Dim>,pidx_t>::touch_iterator a;
  int count = 0;
  for( a = dmti.first ;a != dmti.second; ++a)
    {
      int nodeListIndex = (*a).second;
      outDomain = intersect(a.domain(), fulld);
      ;
      *o = touchesConstruct(outDomain,
       this->all_m[nodeListIndex]->allocated(),
       this->all_m[nodeListIndex]->affinity(),
       this->all_m[nodeListIndex]->context(),
       this->all_m[nodeListIndex]->globalID(),
       this->all_m[nodeListIndex]->localID(),
       ctag);
      ++count;
    }
  return count;
}
template<int Dim>
template<class Out>
void SparseTileLayoutData<Dim>::print(Out & o) const
{
  int i;
  o<< " SparseTileLayoutData<"<<Dim<<">: "<<std::endl;
  o<< " ID_m " << this->ID_m << std::endl;
  o<< " domain_m " << this->domain_m <<std::endl;
  o<< " innerdomain_m " << this->innerdomain_m <<std::endl;
  o<< " all_m : " << std::endl;
  typename List_t::const_iterator start = this->all_m.begin();
  typename List_t::const_iterator end = this->all_m.end();
  for ( ; start!=end ; ++start)
    o<< (*start)->globalID()<<" "<<
      (*start)->domain()<<" "<<
      (*start)->allocated()<<" "
     <<std::endl;
  o<< " local_m : " << std::endl;
  start = this->local_m.begin();
  end = this->local_m.end();
  for ( ; start!=end ; ++start)
    o<< (*start)->globalID()<<" "<<
      (*start)->localID()<<" " <<
      (*start)->domain()<<" "<<
      (*start)->allocated()<<" "
     <<std::endl;
  o<< " firste_m[Dim] " ;
  for ( i=0;i<Dim;++i) o<< this->firste_m[i]<<" ";
  o<< std::endl;
  o<< " firsti_m[Dim] " ;
  for ( i=0;i<Dim;++i) o<< this->firsti_m[i]<<" ";
  o<< std::endl;
  o<< " hasInternalGuards_m, hasExternalGuards_m " <<
    this->hasInternalGuards_m <<" " << this->hasExternalGuards_m <<std::endl;
  o<< " internalGuards_m " ;
   for ( i=0;i<Dim;++i)
     o<< this->internalGuards_m.upper(i)<<"-"<<this->internalGuards_m.lower(i)<<" ";
   o<<std::endl;
  o<< " externalGuards_m " ;
   for ( i=0;i<Dim;++i)
     o<< this->externalGuards_m.upper(i)<<"-"<<this->externalGuards_m.lower(i)<<" ";
   o<<std::endl;
   FillIterator_t gstart = this->gcFillList_m.begin();
   FillIterator_t gend = this->gcFillList_m.end();
   o<< " gcFillList_m " <<std::endl;
   for( ; gstart!=gend ; ++gstart)
     o<<"       "
      <<gstart->domain_m<<" "
      <<gstart->ownedID_m<<" "
      <<gstart->guardID_m<<std::endl;
   BorderFillIterator_t bgstart = gcBorderFillList_m.begin();
   BorderFillIterator_t bgend = gcBorderFillList_m.end();
   o<< " gcBorderFillList_m " <<std::endl;
   for( ; bgstart!=bgend ; ++bgstart)
     o<<"       "
      <<bgstart->domain()<<" "
      <<bgstart->patchID()<<std::endl;
}
template<int Dim>
void SparseTileLayout<Dim>::syncPatch()
{
  this->pdata_m->syncPatch();
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout()
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >(new LayoutData_t()),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(Domain_t & boundingbox,
     const PatchList_t &patchlist,
     const ReplicatedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(boundingbox,patchlist,LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(Domain_t & boundingbox,
     const PatchList_t &patchlist,
     const DistributedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(boundingbox,patchlist,DistributedMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
  template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL,
     const PatchList_t & patchlist,
     const DistributedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
  (new LayoutData_t(boundingbox,globalGL,patchlist,DistributedMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL,
     const PatchList_t & patchlist,
     const ReplicatedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
  (new LayoutData_t(boundingbox,globalGL,patchlist,LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL,
     const PatchList_t & patchlist,
     const DistributedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
              (new LayoutData_t(boundingbox,
    internalGL,
    externalGL,
    patchlist,
    DistributedMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL,
     const PatchList_t & patchlist,
     const ReplicatedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
              (new LayoutData_t(boundingbox,
    internalGL,
    externalGL,
    patchlist,
    LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(boundingbox)),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
 template<int Dim>
SparseTileLayout<Dim>:: SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & globalGL)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(boundingbox,globalGL)),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
     const GuardLayers_t & internalGL,
     const GuardLayers_t & externalGL)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(boundingbox,internalGL,externalGL)),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &bbox,
     const Partitioner &gpar,
     const DistributedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(bbox, gpar,DistributedMapper<Dim>(gpar))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &bbox,
     const Partitioner &gpar,
     const ReplicatedTag &)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >
    (new LayoutData_t(bbox, gpar,LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template<int Dim>
SparseTileLayout<Dim>::SparseTileLayout(const This_t &model)
  : LayoutBase<Dim,SparseTileLayoutData<Dim> >(model.pdata_m),
  Observable<This_t>(*this)
{
   this->pdata_m->attach(*this);
}
template<int Dim >
struct IsValid
{
  IsValid(Loc<Dim> loc) : loc_m(loc) { }
  typedef AndCombine Combine_t;
  Loc<Dim> loc_m;
};
template<class T, int Dim>
struct EngineFunctorScalar<T, IsValid<Dim> >
{
  typedef bool Type_t;
  static inline
  Type_t apply(const T &, const IsValid<Dim> &)
  {
    return true;
  }
};
template<class Engine, int Dim>
struct EngineFunctorDefault<Engine, IsValid<Dim> >
{
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine &, const IsValid<Dim> &)
  {
    return true;
  }
};
template<int Dim,class T,class ptag>
struct EngineFunctor<Engine<Dim, T,MultiPatch<SparseTileTag,ptag> >, IsValid<Dim> >
{
  typedef Engine<Dim,T,MultiPatch<SparseTileTag,ptag> > Engine_t;
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine_t &e, const IsValid<Dim> &f)
  {
    typedef typename Engine_t::Domain_t domain_t;
    typedef Node<domain_t,domain_t> node_t;
    std::vector<node_t> v;
    int count = e.layout().touches(f.loc_m,std::back_inserter(v));
    return (count!=0);
  }
};
template<class Object,class Dom,class tag>
inline bool isValidLocation(const Object &,
       const Dom &,
       const tag &)
{
 return true;
}
#include <iomanip>
class PrintArray;
template<class S, class A, int Dim, class DomainType>
struct PerformPrintArray
{
  static void print(const PrintArray &, S &, const A &, const DomainType &);
};
template<class S, class A, class DomainType>
struct PerformPrintArray<S, A, 1, DomainType>
{
  static void print(const PrintArray &, S &, const A &, const DomainType &);
};
class PrintArray
{
public:
  PrintArray(int domainWidth = 3, int dataWidth = 10,
      int dataPrecision = 4, int carReturn = -1,
      bool scientific = false, int spacing = 1)
    : domainwidth_m(domainWidth), datawidth_m(dataWidth),
      dataprecision_m(dataPrecision), carreturn_m(carReturn),
      spacing_m(spacing), scientific_m(scientific)
    {
      ;
      ;
      ;
      ;
    }
  PrintArray(const PrintArray &a)
    : domainwidth_m(a.domainwidth_m), datawidth_m(a.datawidth_m),
      dataprecision_m(a.dataprecision_m), carreturn_m(a.carreturn_m),
      scientific_m(a.scientific_m)
    {
    }
  ~PrintArray()
    {
    }
  template<class S, class A, class DomainType>
  void print(S &s, const A &a, const DomainType &d) const
  {
    Pooma::blockAndEvaluate();
    PerformPrintArray<S,A,A::dimensions,DomainType>::print(*this, s, a, d);
  }
  template<class S, class A>
  void print(S &s, const A &a) const
  {
    Pooma::blockAndEvaluate();
    PerformPrintArray<S, A, A::dimensions, typename A::Domain_t>::
      print(*this, s, a, a.totalDomain());
  }
  int domainWidth() const
    {
      return domainwidth_m;
    }
  void setDomainWidth(int val)
    {
      domainwidth_m = val;
      ;
    }
  int dataWidth() const
    {
      return datawidth_m;
    }
  void setDataWidth(int val)
    {
      datawidth_m = val;
      ;
    }
  int dataPrecision() const
    {
      return dataprecision_m;
    }
  void setDataPrecision(int val)
    {
      dataprecision_m = val;
      ;
    }
  int carReturn() const
    {
      return carreturn_m;
    }
  void setCarReturn(int val)
    {
      carreturn_m = val;
    }
  bool scientific() const
    {
      return scientific_m;
    }
  void setScientific(bool val)
    {
      scientific_m = val;
    }
  int spacing() const
    {
      return spacing_m;
    }
  void setSpacing(int val)
    {
      spacing_m = val;
      ;
    }
  void setFormatParameters(PrintArray &pa) {
    domainwidth_m = pa.domainWidth();
    datawidth_m = pa.dataWidth();
    dataprecision_m = pa.dataPrecision();
    carreturn_m = pa.carReturn();
    spacing_m = pa.spacing();
    scientific_m = pa.scientific();
  }
private:
  int domainwidth_m;
  int datawidth_m;
  int dataprecision_m;
  int carreturn_m;
  int spacing_m;
  bool scientific_m;
};
template<class S, class A, class DomainType>
void
PerformPrintArray<S,A,1,DomainType>::print(const PrintArray &p, S &s,
                                           const A &a, const DomainType &d)
{
  PoomaCTAssert<(A::dimensions == 1)>::test();
  typedef DomainType Domain_t;
  typedef typename Domain_t::const_iterator Iterator_t;
  Domain_t domain(d);
  Iterator_t griditer = domain.begin();
  Iterator_t enditer = domain.end();
  if (domain.size() == 1) {
    s << "(";
    if (domain[0].first() < 0)
      s.fill(' ');
    else
      s.fill('0');
    s.width(p.domainWidth());
    s << domain[0].first();
    s << ")";
    s.fill(' ');
    s << " = ";
    if (p.scientific())
      s.setf(std::ios::scientific);
    s.precision(p.dataPrecision());
    s.width(p.dataWidth());
    s << a.read(*griditer);
    s << std::endl;
    return;
  }
  s << "(";
  if (domain[0].first() < 0)
    s.fill(' ');
  else
    s.fill('0');
  s.width(p.domainWidth());
  s << domain[0].first() << ":";
  if (domain[0].last() < 0)
    s.fill(' ');
  else
    s.fill('0');
  s.width(p.domainWidth());
  s << domain[0].last() << ":";
  if (domain[0].stride() < 0)
    s.fill(' ');
  else
    s.fill('0');
  s.width(p.domainWidth());
  s << domain[0].stride() << ") = ";
  s.fill(' ');
  int i, printed = 0;
  while (griditer != enditer)
    {
      int spacing = 0;
      if (printed > 0)
 {
   spacing = p.spacing();
   if (p.carReturn() >= 0 && printed >= p.carReturn())
     {
       s << std::endl;
       spacing = 3*p.domainWidth() + 7;
       printed = 0;
     }
 }
      for (i=0; i < spacing; ++i)
 s << " ";
      if (p.scientific())
 s.setf(std::ios::scientific);
      s.precision(p.dataPrecision());
      s.width(p.dataWidth());
      s << a.read(*griditer);
      ++griditer;
      ++printed;
    }
  s << std::endl;
}
template<class S, class A, int Dim, class DomainType>
void
PerformPrintArray<S,A,Dim,DomainType>::print(const PrintArray &p, S &s,
                                             const A &a, const DomainType &d)
{
  int i, j, k;
  PoomaCTAssert<(A::dimensions == Dim && Dim > 1)>::test();
  typedef DomainType Domain_t;
  typedef typename Domain_t::Element_t Element_t;
  typedef typename Domain_t::const_iterator Iterator_t;
  Domain_t domain(d);
  Iterator_t griditer = domain.begin();
  Iterator_t enditer = domain.end();
  if (domain.size() == 1) {
    s << "(";
    if (domain[0].first() < 0)
      s.fill(' ');
    else
      s.fill('0');
    s.width(p.domainWidth());
    s << domain[0].first();
    for (int d = 1; d < Dim; d++) {
      s << ",";
      if (domain[d].first() < 0)
        s.fill(' ');
      else
        s.fill('0');
      s.width(p.domainWidth());
      s << domain[d].first();
    }
    s << ")";
    s.fill(' ');
    s << " = ";
    if (p.scientific())
      s.setf(std::ios::scientific);
    s.precision(p.dataPrecision());
    s.width(p.dataWidth());
    s << a.read(*griditer);
    s << std::endl;
    return;
  }
  Element_t x0 = domain[0].first();
  Element_t x1 = domain[0].last();
  Element_t xs = domain[0].stride();
  Element_t y0 = domain[1].first();
  Element_t y1 = domain[1].last();
  Element_t ys = domain[1].stride();
  if (Dim > 2) {
    s << std::endl << "~~~~~~~~~~~~~~ ";
    s << "(" << domain[0].first() << ":" << domain[0].last()
      << ":" << domain[0].stride();
    for (int d = 1; d < Dim; d++) {
      s << "," << domain[d].first() << ":" << domain[d].last() << ":"
        << domain[d].stride();
    }
    s << ")" << " ~~~~~~~~~~~~~~" << std::endl;
  }
  while (griditer != enditer)
    {
      if (Dim > 2) {
        s << std::endl << "(" << domain[0].first() << ":" << domain[0].last()
          << ":" << domain[0].stride() << "," << domain[1].first() << ":"
          << domain[1].last() << ":" << domain[1].stride();
        for (i=2; i < Dim; ++i)
          s << "," << (*griditer)[i].first();
        s << "):" << std::endl;
        s << "----------------------------------------------------"
          << std::endl;
      }
      for (j=y0; j <= y1; j += ys)
 {
   s << "(";
          if (x0 < 0)
            s.fill(' ');
          else
            s.fill('0');
          s.width(p.domainWidth());
          s << x0 << ":";
          if (x1 < 0)
            s.fill(' ');
          else
            s.fill('0');
          s.width(p.domainWidth());
   s << x1 << ":";
          if (xs < 0)
            s.fill(' ');
          else
            s.fill('0');
          s.width(p.domainWidth());
   s << xs;
   for (i=1; i < Dim; ++i)
     {
              s.fill(' ');
              s << ",";
              if ((*griditer)[i].first() < 0)
                s.fill(' ');
              else
                s.fill('0');
              s.width(p.domainWidth());
       s << (*griditer)[i].first();
     }
          s << ")";
   s.fill(' ');
          s << " = ";
   int printed = 0;
   for (i=x0; i <= x1; i += xs)
     {
       int spacing = 0;
       if (printed > 0)
  {
    spacing = p.spacing();
    if (p.carReturn() >= 0 && printed >= p.carReturn())
      {
        s << std::endl;
        spacing = (Dim + 2)*p.domainWidth() + 2 + Dim + 4;
        printed = 0;
      }
  }
       for (k=0; k < spacing; ++k)
  s << ' ';
       if (p.scientific())
  s.setf(std::ios::scientific);
       s.precision(p.dataPrecision());
       s.width(p.dataWidth());
       typedef typename A::Engine_t::Tag_t Etag_t;
       Etag_t tag;
        if(isValidLocation(a,*griditer,tag))
  s << a.read(*griditer);
        else
   s<< ".";
       ++griditer;
       ++printed;
     }
   s << std::endl;
 }
    }
}
template<class NewDomain, bool sv>
struct CombineDomainOpt;
template<class NewDomain>
struct CombineDomainOpt<NewDomain, true>
{
  typedef typename NewDomain::SliceType_t Type_t;
  template<class Array, class Sub1>
  inline static
  Type_t make(const Array &, const Sub1 &s1)
  {
    return Type_t(s1);
  }
  template<class Array, class Sub1, class Sub2>
  inline static
  Type_t make(const Array &, const Sub1 &s1, const Sub2 &s2)
  {
    return Type_t(s1, s2);
  }
  template<class Array, class Sub1, class Sub2, class Sub3>
  inline static
  Type_t make(const Array &,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
  {
    return Type_t(s1, s2, s3);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4>
  inline static
  Type_t make(const Array &,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4)
  {
    return Type_t(s1, s2, s3, s4);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5>
  inline static
  Type_t make(const Array &,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5)
  {
    return Type_t(s1, s2, s3, s4, s5);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5, class Sub6>
  inline static
  Type_t make(const Array &,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
  {
    return Type_t(s1, s2, s3, s4, s5, s6);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5, class Sub6, class Sub7>
  inline static
  Type_t make(const Array &,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
       const Sub7 &s7)
  {
    return Type_t(s1, s2, s3, s4, s5, s6, s7);
  }
};
template<class NewDomain>
struct CombineDomainOpt<NewDomain, false>
{
  typedef typename NewDomain::SliceType_t Type_t;
  template<class Array, class Sub1>
  inline static
  Type_t make(const Array &a, const Sub1 &s1)
  {
    return NewDomain::combineSlice(a.totalDomain(), s1);
  }
  template<class Array, class Sub1, class Sub2>
  inline static
  Type_t make(const Array &a, const Sub1 &s1, const Sub2 &s2)
  {
    return NewDomain::combineSlice(a.totalDomain(), s1, s2);
  }
  template<class Array, class Sub1, class Sub2, class Sub3>
  inline static
  Type_t make(const Array &a,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
  {
    return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4>
  inline static
  Type_t make(const Array &a,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4)
  {
    return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3, s4);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5>
  inline static
  Type_t make(const Array &a,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5)
  {
    return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3, s4, s5);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5, class Sub6>
  inline static
  Type_t make(const Array &a,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
  {
    return NewDomain::combineSlice(a.totalDomain(),
      s1, s2, s3, s4, s5, s6);
  }
  template<class Array, class Sub1, class Sub2, class Sub3,
    class Sub4, class Sub5, class Sub6, class Sub7>
  inline static
  Type_t make(const Array &a,
       const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
       const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
       const Sub7 &s7)
  {
    return NewDomain::combineSlice(a.totalDomain(),
      s1, s2, s3, s4, s5, s6, s7);
  }
};
template <class Tag>
struct Remote;
template<bool Block>
struct DataObjectApply
{ };
template<>
struct DataObjectApply<false>
{
  template<class Engine,class Functor>
  inline static
  typename Functor::Type_t
  apply(const Engine&, const Functor& functor)
  {
    return functor.defaultValue();
  }
};
template<>
struct DataObjectApply<true>
{
  template<class Engine, class Functor>
  inline static
  typename Functor::Type_t
  apply(const Engine& engine, const Functor& functor)
  {
    return functor(engine.dataObject());
  }
  template<int Dim, class T, class Tag, class Functor>
  inline static
  typename Functor::Type_t
  apply(const Engine<Dim, T, Remote<Tag> >& engine, const Functor& functor)
  {
    if (engine.engineIsLocal())
      return functor(engine.localEngine().dataObject());
    else
      return functor.defaultValue();
  }
};
template<class RequestType>
class DataObjectRequest
{};
template<class Eng, class RequestType>
struct EngineFunctorDefault<Eng, DataObjectRequest<RequestType> >
{
  enum { hasDataObject = Eng::hasDataObject };
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  static inline
  Type_t apply(const Eng &e, const DataObjectRequest<RequestType> &request)
  {
    return DataObjectApply<hasDataObject>::apply(e, request);
  }
};
template<class RequestType,class T>
struct EngineFunctorScalar<T, DataObjectRequest<RequestType> >
{
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  inline static
  Type_t apply(const T &, const DataObjectRequest<RequestType> &tag)
  {
    return tag.defaultValue();
  }
};
struct BlockAffinity { };
struct AffinityCombine
{
  AffinityCombine() { }
  AffinityCombine(const AffinityCombine &) { }
};
template<class Op>
struct Combine2<int, int, Op, AffinityCombine>
{
  typedef int Type_t;
  inline static
  Type_t combine(int a, int b, AffinityCombine)
  {
    return a;
  }
};
template<>
class DataObjectRequest<BlockAffinity>
{
public:
  typedef int Type_t;
  typedef AffinityCombine Combine_t;
  DataObjectRequest() { }
  inline Type_t operator()(Pooma::DataObject_t* obj) const
  {
    return obj->affinity();
  }
  inline Type_t defaultValue() const
  {
    return (-1);
  }
};
template<int TotalDim, int SliceDim> class SliceInterval;
template<int TotalDim, int SliceDim>
struct DomainTraits< SliceInterval<TotalDim,SliceDim> >
{
  enum { domain = true };
  enum { dimensions = TotalDim,
  sliceDimensions = SliceDim };
  enum { unitStride = true };
  enum { singleValued = false };
  enum { wildcard = false };
  typedef SliceInterval<TotalDim,SliceDim> Domain_t;
  typedef SliceInterval<TotalDim,SliceDim> NewDomain1_t;
  typedef Interval<SliceDim> SliceDomain_t;
  typedef Interval<TotalDim> TotalDomain_t;
  typedef Interval<1> OneDomain_t;
  typedef Interval<1> PointDomain_t;
  static OneDomain_t &getDomain(Domain_t &d, int n) {
    return d.totalDomain()[n];
  }
  static const OneDomain_t &getDomain(const Domain_t &d,int n) {
    return d.totalDomain()[n];
  }
  static OneDomain_t &getSliceDomain(Domain_t &d, int n) {
    return d.sliceDomain()[n];
  }
  static const OneDomain_t &getSliceDomain(const Domain_t &d, int n) {
    return d.sliceDomain()[n];
  }
  static PointDomain_t &getPointDomain(Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
    return getDomain(d, n);
  }
  static void cantIgnoreDomain(Domain_t &d, int n) {
    d.cantIgnoreDomain(n);
  }
  static bool getIgnorable(const Domain_t &d, int n) {
    return d.ignorable(n);
  }
  static void setIgnorable(Domain_t &d, int n, bool i) {
    d.ignorable(n) = i;
  }
};
template<int Dim, int SliceDim>
class SliceInterval
  : public SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >
{
public:
  SliceInterval() { }
  SliceInterval(const Pooma::NoInit &d)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >(d) { }
  SliceInterval(const SliceInterval<Dim,SliceDim> &nd)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >(nd) {
  }
  template <class Base, class D1, class D2>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain2<D1,D2> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2);
  }
  template <class Base, class D1, class D2, class D3>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
                const D3 &d3)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain3<D1,D2,D3> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3);
  }
  template <class Base, class D1, class D2, class D3,
            class D4>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
                const D3 &d3, const D4 &d4)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain4<D1,D2,D3,D4> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
                const D3 &d3, const D4 &d4, const D5 &d5)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain5<D1,D2,D3,D4,D5> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5, class D6>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
                const D3 &d3, const D4 &d4, const D5 &d5, const D6 &d6)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain6<D1,D2,D3,D4,D5,D6> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6);
  }
  template <class Base, class D1, class D2, class D3,
            class D4, class D5, class D6, class D7>
  SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
                const D3 &d3, const D4 &d4, const D5 &d5, const D6 &d6,
                const D7 &d7)
    : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
        Pooma::NoInit())
  {
      typedef NewDomain7<D1,D2,D3,D4,D5,D6,D7> NewDomain_t;
      typedef typename NewDomain_t::SliceType_t SliceType_t;
      PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
      PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
      NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6, d7);
  }
  ~SliceInterval() { }
  SliceInterval<Dim,SliceDim> &
    operator=(const SliceInterval<Dim,SliceDim> &nd) {
      SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >::operator=(nd);
      return *this;
  }
protected:
private:
};
struct DomainTag { };
template<int Dim>
class DomainLayout
{
public:
  typedef DomainLayout<Dim> This_t;
  typedef Interval<Dim> Domain_t;
  typedef Node<Domain_t> Value_t;
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef Value_t *iterator;
  typedef const Value_t *const_iterator;
  enum { dimensions = Dim };
  enum { dynamic = false };
  inline DomainLayout()
    {
    }
  explicit DomainLayout(const Domain_t &dom)
    : node_m(0, dom, Pooma::context(), 0, 0)
    {
    }
  DomainLayout(const Domain_t &dom, const GuardLayers_t &g)
    : node_m(0, dom, grow(dom, g), Pooma::context(), 0, 0)
    {
    }
  explicit DomainLayout(const Value_t &node)
    : node_m(node)
    {
    }
  DomainLayout(const This_t &layout)
    : node_m(layout.node_m)
    {
    }
  void initialize(const Domain_t &dom)
    {
      node_m = Value_t(0, dom, Pooma::context(), 0, 0);
    }
  void initialize(const Domain_t &dom, const GuardLayers_t &g)
    {
      node_m = Value_t(0, dom, grow(dom, g), Pooma::context(), 0, 0);
    }
  void initialize(const This_t &layout)
  {
    node_m = layout.node_m;
  }
  inline ~DomainLayout()
    {
    }
  inline bool initialized() const
    {
      return domain().initialized();
    }
  inline int first(int d) const { return innerDomain()[d].first(); }
  inline Value_t &node()
    {
      return node_m;
    }
  inline const Value_t &node() const
    {
      return node_m;
    }
  inline Loc<Dim> blocks() const { return Loc<Dim>(1); }
  inline const Domain_t &domain() const
    {
      return node_m.allocated();
    }
  inline const Domain_t &innerDomain() const
  {
    return node_m.domain();
  }
  inline const Domain_t &allocated() const
    {
      return node_m.allocated();
    }
  inline GuardLayers_t internalGuards() const
  {
    return GuardLayers_t(0);
  }
  inline GuardLayers_t externalGuards() const
  {
    GuardLayers_t gl;
    for (int i = 0; i < Dim; i++)
      {
        gl.lower(i) = node_m.domain()[i].min() - node_m.allocated()[i].min();
        gl.upper(i) = node_m.allocated()[i].max() - node_m.domain()[i].max();
      }
    return gl;
  }
  inline const Domain_t &domain(int i) const
  {
    ;
    return node_m.allocated();
  }
 inline const Domain_t &ownedDomain(int i) const
  {
    ;
    return node_m.domain();
  }
  inline const Domain_t &allocatedDomain(int i) const
    {
      ;
      return node_m.allocated();
    }
  template<class L>
  inline bool operator==(const L &layout) const
    {
      return (domain() == layout.domain());
    }
  template<class L>
  inline bool operator!=(const L &layout) const
    {
      return !(*this == layout);
    }
  inline iterator begin()
    {
      return &node_m;
    }
  inline iterator end()
    {
      return &node_m + 1;
    }
  inline const_iterator begin() const
    {
      return &node_m;
    }
  inline const_iterator end() const
    {
      return &node_m + 1;
    }
  inline long size() const
    {
      return 1;
    }
  inline iterator beginLocal()
    {
      return begin();
    }
  inline iterator endLocal()
    {
      return end();
    }
  inline const_iterator beginLocal() const
    {
      return begin();
    }
  inline const_iterator endLocal() const
    {
      return end();
    }
  inline long sizeLocal() const
    {
      return size();
    }
  inline iterator beginGlobal()
    {
      return begin();
    }
  inline iterator endGlobal()
    {
      return end();
    }
  inline const_iterator beginGlobal() const
    {
      return begin();
    }
  inline const_iterator endGlobal() const
    {
      return end();
    }
  inline long sizeGlobal() const
    {
      return size();
    }
  inline iterator beginRemote()
    {
      return iterator(0);
    }
  inline iterator endRemote()
    {
      return iterator(0);
    }
  inline const_iterator beginRemote() const
    {
      return const_iterator(0);
    }
  inline const_iterator endRemote() const
    {
      return const_iterator(0);
    }
  inline long sizeRemote() const
    {
      return 0;
    }
  inline int globalID(const Loc<Dim> &loc) const
    {
      ;
      return 0;
    }
  inline int globalID(int i1) const
    {
      return globalID(Loc<1>(i1));
    }
  inline int globalID(int i1, int i2) const
    {
      return globalID(Loc<2>(i1, i2));
    }
  inline int globalID(int i1, int i2, int i3) const
    {
      return globalID(Loc<3>(i1, i2, i3));
    }
  inline int globalID(int i1, int i2, int i3, int i4) const
    {
      return globalID(Loc<4>(i1, i2, i3, i4));
    }
  inline int globalID(int i1, int i2, int i3, int i4, int i5) const
    {
      return globalID(Loc<5>(i1, i2, i3, i4, i5));
    }
  inline int globalID(int i1, int i2, int i3, int i4, int i5,
        int i6) const
    {
      return globalID(Loc<6>(i1, i2, i3, i4, i5, i6));
    }
  inline int globalID(int i1, int i2, int i3, int i4, int i5,
        int i6, int i7) const
    {
      return globalID(Loc<7>(i1, i2, i3, i4, i5, i6, i7));
    }
  template<class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o, ConstructTag ctag) const;
  template<class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesLocal(const OtherDomain &d, OutIter o,
                          const ConstructTag &ctag) const
    {
      return touches(d, o, ctag);
    }
  template<class OtherDomain, class OutIter, class ConstructTag>
  inline int touchesRemote(const OtherDomain &, OutIter,
      const ConstructTag &) const
    {
      return 0;
    }
  template<class OtherDomain, class OutIter>
  inline int touches(const OtherDomain &d, OutIter o) const
    {
      return touches(d, o, TouchesConstructNodeObj());
    }
  template<class OtherDomain, class OutIter>
  inline int touchesLocal(const OtherDomain &d, OutIter o) const
    {
      return touchesLocal(d, o, TouchesConstructNodeObj());
    }
  template<class OtherDomain, class OutIter>
  inline int touchesRemote(const OtherDomain &d, OutIter o) const
    {
      return touchesRemote(d, o, TouchesConstructNodeObj());
    }
  template<class Out>
  void print(Out &o) const
    {
      o << "DomainLayout: Node = " << node_m;
    }
private:
  Value_t node_m;
};
template<int Dim>
template<class OtherDomain, class OutIter, class ConstructTag>
int DomainLayout<Dim>::touches(const OtherDomain &d, OutIter o,
          ConstructTag ctag) const
{
  int i, count = 0;
  typedef typename IntersectReturnType<Domain_t,OtherDomain>::Type_t
    OutDomain_t;
  typedef Node<OutDomain_t> OutNode_t;
  OutDomain_t outDomain = intersect(d, domain());
  if (!outDomain.empty())
    {
      ++count;
      *o = touchesConstruct(outDomain,
       node().affinity(),
       node().context(),
       node().globalID(),
       node().localID(),
       ctag);
    }
  return count;
}
template <int Dim>
std::ostream &operator<<(std::ostream &o, const DomainLayout<Dim> &layout)
{
  layout.print(o);
  return o;
}
template<int Dim>
struct NewDomain1< DomainLayout<Dim> >
{
  typedef DomainLayout<Dim> &Type_t;
  inline static Type_t combine(const DomainLayout<Dim> &a)
    {
      return const_cast<Type_t>(a);
    }
};
namespace Pooma {
template <int Dim> class BrickViewBase;
template <int pos, int max>
struct OffsetCalc
{
 template <class Dom>
 static inline int apply(const Dom& dom, const int *strides_m)
 {
  return dom[pos].first()*strides_m[pos]
   + OffsetCalc<pos+1,max>::apply(dom, strides_m);
 }
};
template <int end>
struct OffsetCalc<end, end>
{
 template <class Dom>
 static inline int apply(const Dom& dom, const int *strides_m)
 {
  return dom[end].first()*strides_m[end];
 }
};
template <>
struct OffsetCalc<1, 0>
{
 template <class Dom>
 static inline int apply(const Dom& dom, const int *strides_m)
 {
  return 0;
 }
};
template <int Dim>
class BrickBase
{
public:
  typedef Interval<Dim> Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef BrickBase<Dim> This_t;
  enum { dimensions = Dim };
  enum { brick = true };
  enum { zeroBased = false };
  explicit BrickBase(bool compressible = false)
    : compressibleBase_m(compressible)
  { }
  explicit BrickBase(const Domain_t &dom, bool compressible = false)
    : layout_m(dom), compressibleBase_m(compressible)
  {
    init();
  }
  explicit BrickBase(const Node<Domain_t> &node, bool compressible = false)
    : layout_m(node), compressibleBase_m(compressible)
  {
    init();
  }
  explicit BrickBase(const Layout_t &layout, bool compressible = false)
    : layout_m(layout), compressibleBase_m(compressible)
  {
    init();
  }
  ~BrickBase() {}
  inline const Domain_t &domain() const { return layout_m.domain(); }
  inline const Layout_t &layout() const { return layout_m; }
  inline const int *strides() const { return &strides_m[0]; }
  inline const int *originalStrides() const { return &ostrides_m[0]; }
  int first(int i) const { return layout_m.domain()[i].first(); }
  bool compressibleBase() const { return compressibleBase_m; }
  template <class Domain>
  inline int offset(const Domain &dom) const
  { return off_m + offset0(dom); }
  template <class Domain>
  inline int offset0(const Domain &dom) const
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
    return dom[0].first() + OffsetCalc<1, Dim-1>::apply(dom, strides_m);
  }
  template <class Domain>
  inline int offsetC(const Domain &dom) const
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
    return OffsetCalc<0, Dim-1>::apply(dom, strides_m);
  }
  inline int offset() const
  { return off_m; }
  inline int baseOffset() const
  { return off_m; }
  inline int offset(int i0) const
  { return off_m + i0; }
  inline int offset(int i0, int i1) const
  { return off_m + i0 + i1*strides_m[1]; }
  inline int offset(int i0, int i1, int i2) const
  { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2]; }
  inline int offset(int i0, int i1, int i2, int i3) const
  { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4) const
  { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
                      + i4*strides_m[4]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
                      + i4*strides_m[4] + i5*strides_m[5]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
  const
  { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
                      + i4*strides_m[4] + i5*strides_m[5] + i6*strides_m[6]; }
  inline int offset0(int i0) const
  { return i0; }
  inline int offset0(int i0, int i1) const
  { return i0 + i1*strides_m[1]; }
  inline int offset0(int i0, int i1, int i2) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]; }
  inline int offset0(int i0, int i1, int i2, int i3) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]; }
  inline int offset0(int i0, int i1, int i2, int i3, int i4) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
              + i4*strides_m[4]; }
  inline int offset0(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
              + i4*strides_m[4] + i5*strides_m[5]; }
  inline int offset0(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
  const
  { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
              + i4*strides_m[4] + i5*strides_m[5] + i6*strides_m[6]; }
  inline int offsetC(int i0) const
  { return i0*strides_m[0]; }
  inline int offsetC(int i0, int i1) const
  { return i0*strides_m[0] + i1*strides_m[1]; }
  inline int offsetC(int i0, int i1, int i2) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]; }
  inline int offsetC(int i0, int i1, int i2, int i3) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3]; }
  inline int offsetC(int i0, int i1, int i2, int i3, int i4) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4]; }
  inline int offsetC(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
  inline int offsetC(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
  const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
         + i6*strides_m[6]; }
protected:
  void init()
  {
    strides_m[0] = 1;
    ostrides_m[0] = 1;
    off_m = -domain()[0].first();
    for (int d = 1; d < Dim; ++d) {
      strides_m[d] = strides_m[d-1]*domain()[d-1].length();
      ostrides_m[d] = strides_m[d];
      off_m -= domain()[d].first()*strides_m[d];
    }
  }
  void zeroStrides()
  { for (int d = 0; d < Dim; ++d) strides_m[d] = 0; }
  void restoreStrides()
  { for (int d = 0; d < Dim; ++d) strides_m[d] = ostrides_m[d]; }
  Layout_t layout_m;
  int strides_m[Dim];
  int ostrides_m[Dim];
  int off_m;
  bool compressibleBase_m;
};
template <int Dim>
class BrickViewBase
{
public:
  enum { dimensions = Dim };
  enum { zeroBased = true };
  typedef Interval<Dim> Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  BrickViewBase() {}
  typedef BrickViewBase<Dim> This_t;
  BrickViewBase(const This_t &bvbase, bool compressible)
  {
    *this = bvbase;
    compressibleBase_m = compressible;
    if (!compressible) restoreStrides();
  }
  BrickViewBase(const BrickBase<Dim> &base, bool compressible)
  {
    *this = BrickViewBase<Dim>(base, base.domain());
    compressibleBase_m = compressible;
    if (!compressible) restoreStrides();
  }
  BrickViewBase(const BrickBase<Dim> &bbase, const Interval<Dim> &dom)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bbase.offset()),
      compressibleBase_m(bbase.compressibleBase())
  {
    viewInit(bbase, dom);
  }
  BrickViewBase(const BrickBase<Dim> &bbase, const Range<Dim> &dom)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bbase.offset()),
      compressibleBase_m(bbase.compressibleBase())
  {
    viewInit(bbase, dom);
  }
  BrickViewBase(const This_t &bvbase, const Interval<Dim> &domain)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bvbase.baseOffset()),
      compressibleBase_m(bvbase.compressibleBase())
  {
    viewInit(bvbase, domain);
  }
  BrickViewBase(const This_t &bvbase, const Range<Dim> &domain)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bvbase.baseOffset()),
      compressibleBase_m(bvbase.compressibleBase())
  {
    viewInit(bvbase, domain);
  }
  template<int BaseDim>
  BrickViewBase(const BrickBase<BaseDim> &bbase,
  const SliceRange<BaseDim,Dim> &dom)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bbase.offset()),
      compressibleBase_m(bbase.compressibleBase())
  {
    sliceInit(bbase.originalStrides(), dom);
  }
  template<int BaseDim>
  BrickViewBase(const BrickBase<BaseDim> &bbase,
  const SliceInterval<BaseDim,Dim> &dom)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bbase.offset()),
      compressibleBase_m(bbase.compressibleBase())
  {
    sliceInit(bbase.originalStrides(), SliceRange<BaseDim,Dim>(dom));
  }
  template<int SliceDim>
  BrickViewBase(const BrickBase<SliceDim> &bbase,
  const SliceInterval<Dim,SliceDim> &dom,
  const Interval<Dim> &totalDomain)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bbase.offset()),
      compressibleBase_m(bbase.compressibleBase())
  {
    sliceInit(bbase.originalStrides(), dom, totalDomain);
  }
  template<int SliceDim>
  BrickViewBase(const BrickViewBase<SliceDim> &bvbase,
  const SliceInterval<Dim,SliceDim> &dom,
  const Interval<Dim> &totalDomain)
    : domain_m(Pooma::NoInit()),
      baseOffset_m(bvbase.baseOffset())
  {
    sliceInit(bvbase, dom, totalDomain);
  }
  template <int BaseDim>
  BrickViewBase(const BrickViewBase<BaseDim> &bvbase,
                const SliceRange<BaseDim,Dim> &dom)
  : domain_m(Pooma::NoInit()),
    baseOffset_m(bvbase.baseOffset())
  {
    sliceInit(bvbase, dom);
  }
  template <int BaseDim>
  BrickViewBase(const BrickViewBase<BaseDim> &bvbase,
                const SliceInterval<BaseDim,Dim> &dom)
  : domain_m(Pooma::NoInit()),
    baseOffset_m(bvbase.baseOffset())
  {
    sliceInit(bvbase, SliceRange<BaseDim,Dim>(dom));
  }
  ~BrickViewBase() {}
  inline const Domain_t &domain() const { return domain_m; }
  inline Layout_t layout() const { return Layout_t(domain_m); }
  inline const int *strides() const { return &strides_m[0]; }
  inline const int *originalStrides() const { return &ostrides_m[0]; }
  inline int first(int) const { return 0; }
  bool compressibleBase() const { return compressibleBase_m; }
  int baseOffset() const { return baseOffset_m; }
  template <class Domain>
  inline int offset(const Domain &dom) const
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
    return OffsetCalc<0, Dim-1>::apply(dom, strides_m);
  }
  inline int offset(int i0) const
  { return i0*strides_m[0]; }
  inline int offset(int i0, int i1) const
  { return i0*strides_m[0] + i1*strides_m[1]; }
  inline int offset(int i0, int i1, int i2) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]; }
  inline int offset(int i0, int i1, int i2, int i3) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
  inline int offset(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
    const
  { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
         + i6*strides_m[6]; }
  template <class Domain>
  inline int offsetU(const Domain &dom) const
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
    return dom[0].first() + OffsetCalc<1, Dim-1>::apply(dom, strides_m);
  }
  inline int offsetU(int i0) const
  { return i0; }
  inline int offsetU(int i0, int i1) const
  { return i0 + i1*strides_m[1]; }
  inline int offsetU(int i0, int i1, int i2) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]; }
  inline int offsetU(int i0, int i1, int i2, int i3) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3]; }
  inline int offsetU(int i0, int i1, int i2, int i3, int i4) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4]; }
  inline int offsetU(int i0, int i1, int i2, int i3, int i4, int i5) const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
  inline int offsetU(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
    const
  { return i0 + i1*strides_m[1] + i2*strides_m[2]
         + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
         + i6*strides_m[6]; }
protected:
  void zeroStrides()
  { for (int d = 0; d < Dim; ++d) strides_m[d] = 0; }
  void restoreStrides()
  { for (int d = 0; d < Dim; ++d) strides_m[d] = ostrides_m[d]; }
  template<int BaseDim>
  void sliceInit(const int *baseStrides,
   const SliceRange<BaseDim,Dim> &dom);
  template<int SliceDim>
  void sliceInit(const int *baseStrides,
   const SliceInterval<Dim,SliceDim> &dom,
   const Interval<Dim> &totalDomain);
  template<int BaseDim>
  void sliceInit(const BrickViewBase<BaseDim>&, const SliceRange<BaseDim, Dim>&);
  template<int SliceDim>
  void sliceInit(const BrickViewBase<SliceDim>&, const SliceInterval<Dim, SliceDim>&,
   const Interval<Dim> &totalDomain);
  void viewInit(const This_t &, const Range<Dim> &domain);
  void viewInit(const BrickBase<Dim> &bbase, const Range<Dim> &domain);
  void viewInit(const This_t &bvbase, const Interval<Dim> &domain)
  {
    for (int d = 0; d < Dim; ++d)
    {
      domain_m[d] = Interval<1>(domain[d].length());
      strides_m[d] = bvbase.ostrides_m[d];
      ostrides_m[d] = strides_m[d];
      baseOffset_m += domain[d].first() * bvbase.ostrides_m[d];
    }
  }
  void viewInit(const BrickBase<Dim> &bbase, const Interval<Dim> &domain)
  {
    for (int d = 0; d < Dim; ++d)
    {
      domain_m[d] = Interval<1>(domain[d].length());
      strides_m[d] = bbase.originalStrides()[d];
      ostrides_m[d] = strides_m[d];
      baseOffset_m += domain[d].first() * bbase.originalStrides()[d];
    }
  }
  Domain_t domain_m;
  int strides_m[Dim];
  int ostrides_m[Dim];
  int baseOffset_m;
  bool compressibleBase_m;
};
template <int Dim>
void
BrickViewBase<Dim>::
viewInit(const This_t &bvbase, const Range<Dim> &domain)
{
  for (int d = 0; d < Dim; ++d)
    {
      domain_m[d] = Interval<1>(domain[d].length());
      strides_m[d] = bvbase.ostrides_m[d] * domain[d].stride();
      baseOffset_m += domain[d].first() * bvbase.ostrides_m[d];
    }
  for (int d = 0; d < Dim; ++d)
    ostrides_m[d] = strides_m[d];
}
template <int Dim>
void
BrickViewBase<Dim>::
viewInit(const BrickBase<Dim> &bbase, const Range<Dim> &domain)
{
  for (int d = 0; d < Dim; ++d)
  {
    domain_m[d] = Interval<1>(domain[d].length());
    strides_m[d] = bbase.originalStrides()[d] * domain[d].stride();
    ostrides_m[d] = strides_m[d];
    baseOffset_m += domain[d].first() * bbase.originalStrides()[d];
  }
}
template <int Dim>
template<int BaseDim>
void
BrickViewBase<Dim>::
sliceInit(const int *baseStrides,
   const SliceRange<BaseDim,Dim> &dom)
{
  typedef typename SliceRange<BaseDim,Dim>::TotalDomain_t TotalDomain_t;
  const TotalDomain_t &domain = dom.totalDomain();
  int d = 0;
  for (int dt = 0; dt < BaseDim; ++dt)
  {
    if (!dom.ignorable(dt))
    {
      ;
      domain_m[d] = Interval<1>(domain[dt].length());
      strides_m[d] = baseStrides[dt] * domain[dt].stride();
      ++d;
    }
    baseOffset_m += domain[dt].first() * baseStrides[dt];
  }
  ;
  for (int d = 0; d < Dim; ++d)
    ostrides_m[d] = strides_m[d];
}
template <int Dim>
template<int SliceDim>
void
BrickViewBase<Dim>::
sliceInit(const int *baseStrides,
   const SliceInterval<Dim,SliceDim> &dom,
   const Interval<Dim> &domain)
{
  int dt = 0;
  for (int d = 0; d < Dim; ++d)
  {
    domain_m[d] = Interval<1>(domain[d].length());
    if (!dom.ignorable(d))
    {
      ;
      strides_m[d] = baseStrides[dt];
      baseOffset_m += domain[dt].first() * baseStrides[dt];
      ++dt;
    } else {
      strides_m[d] = 0;
    }
  }
  ;
  for (int d = 0; d < Dim; ++d)
    ostrides_m[d] = strides_m[d];
}
template <int Dim>
template<int SliceDim>
void
BrickViewBase<Dim>::
sliceInit(const BrickViewBase<SliceDim>& bvbase,
   const SliceInterval<Dim,SliceDim> &dom,
   const Interval<Dim> &domain)
{
  int dt = 0;
  for (int d = 0; d < Dim; ++d)
  {
    domain_m[d] = Interval<1>(domain[d].length());
    if (!dom.ignorable(d))
    {
      ;
      strides_m[d] = bvbase.originalStrides()[dt];
      baseOffset_m += domain[dt].first() * bvbase.originalStrides()[dt];
      ++dt;
    } else {
      strides_m[d] = 0;
    }
  }
  ;
  for (int d = 0; d < Dim; ++d)
    ostrides_m[d] = strides_m[d];
}
template <int Dim>
template<int BaseDim>
void
BrickViewBase<Dim>::
sliceInit(const BrickViewBase<BaseDim>& bvbase, const SliceRange<BaseDim, Dim>& dom)
{
  typedef typename SliceRange<BaseDim,Dim>::TotalDomain_t TotalDomain_t;
  const TotalDomain_t &totDomain = dom.totalDomain();
  int d, dt;
  for (dt = 0, d = 0; dt < BaseDim; ++dt)
    {
      if (!dom.ignorable(dt))
        {
          ;
          domain_m[d] = Interval<1>(totDomain[dt].length());
          strides_m[d] = bvbase.originalStrides()[dt] * totDomain[dt].stride();
          ++d;
        }
      baseOffset_m += totDomain[dt].first() * bvbase.originalStrides()[dt];
    }
  ;
  for (int d = 0; d < Dim; ++d)
    ostrides_m[d] = strides_m[d];
}
}
class Inform;
namespace Pooma {
class StatisticsData
{
  friend class Statistics;
public:
  const std::string &description() const { return data_m.first; }
  long value() const { return data_m.second; }
  void increment(long val = 1) { data_m.second += val; }
private:
  StatisticsData(const char *description, long initialValue = 0)
  : data_m(description, initialValue)
  { }
  ~StatisticsData() { }
  std::pair<std::string, long> data_m;
};
class Statistics {
private:
  static long defaultFilter(long val);
public:
  Statistics();
  ~Statistics();
  void print(Inform &, long (*filter)(long) = defaultFilter);
  StatisticsData *add(const char *description, long initval = 0)
  {
    StatisticsData *sd = new StatisticsData(description, initval);
    statList_m.push_back(sd);
    return sd;
  }
private:
  std::vector<StatisticsData *> statList_m;
};
}
template <class T> class SingleObserver;
template <class T>
class CompressibleBlock
{
public:
  typedef CompressibleBlock<T> This_t;
  typedef T Element_t;
  typedef Pooma::DataObject_t DataObject_t;
  enum Notifier
  {
    notifyDestruct = 0,
    notifyUncompress = 1,
    notifyCompress = 2
  };
  CompressibleBlock()
    : controller_m(0)
  { }
  explicit CompressibleBlock(int size)
    : controller_m(new CompressibleBlockController(size))
  { }
  CompressibleBlock(int size, int affinity)
    : controller_m(new CompressibleBlockController(size,affinity))
  { }
  CompressibleBlock(int size, int affinity, const T& model)
    : controller_m(new CompressibleBlockController(size,affinity,model))
  { }
  CompressibleBlock(const CompressibleBlock &block)
    : controller_m(block.controller_m)
  { }
  ~CompressibleBlock()
  {
    ;
  }
  inline int size() const
  {
    return controller_m.size();
  }
  inline int capacity() const
  {
    return controller_m.capacity();
  }
  inline bool resize(int newsize,
       const typename DataBlockPtr<T>::NoInitTag &)
  {
    return controller_m->resize(newsize,DataBlockPtr<T>::NoInitTag());
  }
  inline void setSize(int newsize)
  {
    controller_m->setSize(newsize);
  }
  inline DataObject_t* dataObject() const
  {
    ;
    return controller_m->dataObject();
  }
  inline int affinity() const
  {
    ;
    return controller_m->dataObject()->affinity();
  }
  inline bool compressed() const
  {
    ;
    return controller_m->compressed();
  }
  inline T* data()
  {
    ;
    return controller_m->data();
  }
  inline void uncompress() const
  {
    ;
    controller_m->uncompress();
  }
  void tryCompress()
  {
    ;
    controller_m->tryCompress();
  }
  inline DataBlockPtr<T> view() const
  {
    ;
    return controller_m->view();
  };
  DataBlockPtr<T> dataBlock() const
  {
    ;
    return controller_m->dataBlock();
  }
  void makeOwnCopy()
  {
    controller_m.makeOwnCopy();
  }
  void invalidate()
  {
    controller_m.invalidate();
  }
  inline bool isControllerPtrValid() const
  {
    return controller_m.isValid();
  }
  inline bool isControllerValid() const
  {
    return controller_m.isValid() && controller_m->isValid();
  }
  inline bool isControllerValidUnlocked() const
  {
    return controller_m.isValid() && controller_m->isValidUnlocked();
  }
  inline bool isShared() const
  {
    return controller_m.isShared();
  }
  bool operator!=(const This_t& a) const
  {
    return controller_m != a.controller_m;
  }
  bool operator==(const This_t& a) const
  {
    return controller_m == a.controller_m;
  }
  void attach(Observer<T*> *o)
  {
    ;
    controller_m->attach(o);
  }
  void detach(Observer<T*> *o)
  {
    ;
    controller_m->detach(o);
  }
  void lock() const
  {
    controller_m->lock();
  }
  void unlock() const
  {
    controller_m->unlock();
  }
  static int randomTries() { return CompressibleBlockController::randomTries(); }
private:
  class CompressibleBlockController
    : public SingleObserver<int>,
      public Observable<T*>,
      public RefCounted
  {
  public:
    typedef CompressibleBlockController This_t;
    typedef T Element_t;
    typedef Pooma::DataObject_t DataObject_t;
    CompressibleBlockController()
      : Observable<T*>(ptr_m),
        size_m(0),
 compressible_m(true),
 ptr_m(0),
 dataObject_m(-1),
 ucOffset_m(-1),
 viewcount_m(0),
 countUncompressed_m(0)
    {
      ElementProperties<T>::construct(&compressedData_m);
      if (Pooma::neverCompress())
        {
          compressible_m = false;
        }
    }
    explicit
    CompressibleBlockController(int size)
      : Observable<T*>(ptr_m),
        compressible_m(true),
        countUncompressed_m(0),
 viewcount_m(0),
 dataObject_m(-1),
        size_m(size),
 ptr_m(&compressedData_m),
 ucOffset_m(-1)
    {
      ElementProperties<T>::construct(&compressedData_m);
      if (Pooma::neverCompress())
        {
          viewcount_m = 1;
          compressible_m = false;
          countUncompressed_m = 1;
          block_m = DataBlockPtr<T>(size_m,dataObject_m);
          ptr_m = block_m.currentPointer();
          block_m.attach(this);
        }
    }
    CompressibleBlockController(int size, int affinity)
      : Observable<T*>(ptr_m),
 compressible_m(true),
        countUncompressed_m(0),
 viewcount_m(0),
 dataObject_m(affinity),
        size_m(size),
 ptr_m(&compressedData_m),
 ucOffset_m(-1)
    {
      ElementProperties<T>::construct(&compressedData_m);
      if (Pooma::neverCompress())
        {
          viewcount_m = 1;
          compressible_m = false;
          countUncompressed_m = 1;
          block_m = DataBlockPtr<T>(size_m,dataObject_m);
          ptr_m = block_m.currentPointer();
          block_m.attach(this);
        }
    }
    CompressibleBlockController(int size, int affinity, const T& value)
      : Observable<T*>(ptr_m),
 compressible_m(true),
        countUncompressed_m(0),
 viewcount_m(0),
 dataObject_m(affinity),
        size_m(size),
 ptr_m(&compressedData_m),
 ucOffset_m(-1)
    {
      ElementProperties<T>::construct(&compressedData_m,value);
      if (Pooma::neverCompress())
        {
          viewcount_m = 1;
          compressible_m = false;
          countUncompressed_m = 1;
          block_m = DataBlockPtr<T>(size_m,value,dataObject_m);
          ptr_m = block_m.currentPointer();
          block_m.attach(this);
        }
    }
    CompressibleBlockController(const CompressibleBlockController& model)
      : Observable<T*>(ptr_m),
        compressible_m(!Pooma::neverCompress()),
 viewcount_m(0),
        dataObject_m(model.dataObject_m.affinity()),
        size_m(model.size_m),
 ucOffset_m(model.ucOffset_m)
    {
      model.lock();
      bool modelCompressed = model.compressed();
      compressedData_m = model.compressedData_m;
      block_m = model.block_m;
      if (!modelCompressed)
 {
   --model.viewcount_m;
 }
      model.unlock();
      if (modelCompressed)
 {
          ;
   ptr_m = &compressedData_m;
   countUncompressed_m = 0;
 }
      else
 {
   block_m.makeOwnCopy();
   ptr_m = block_m.currentPointer();
   block_m.dataObject(&dataObject_m);
   countUncompressed_m = 1;
   ++viewcount_m;
   block_m.attach(this);
 }
      ;
    }
    ~CompressibleBlockController()
    {
      ;
      ;
      ;
      if (!compressed())
 {
   block_m.detach();
 }
    }
    inline size_t size() const
    {
      return block_m.size();
    }
    inline size_t capacity() const
    {
      return block_m.capacity();
    }
    inline void setSize(size_t size)
    {
      size_m = size;
    }
    inline bool resize(size_t newsize,
         const typename DataBlockPtr<T>::NoInitTag &)
    {
      ;
      if (block_m.capacity() >= newsize)
 {
   block_m.resize(newsize, DataBlockPtr<T>::NoInitTag());
   size_m = block_m.size();
 }
      else
 {
   size_t nsize = newsize * sizeof(T);
   size_t n_ext = nsize/sizeof(T);
   DataBlockPtr<T> newdata(n_ext,dataObject_m);
   newdata.resize(newsize, DataBlockPtr<T>::NoInitTag());
          T * pOld = block_m.beginPointer();
          T * pNew = newdata.beginPointer();
          const T * const pEnd = pNew + block_m.size();
          while (pNew != pEnd)
            {
       ElementProperties<T>::construct(pNew++,*pOld++);
            }
   block_m = newdata;
          ptr_m = block_m.currentPointer();
   size_m = newsize;
 }
      return true;
    }
    inline void uncompress()
    {
      lock();
      uncompressUnlocked();
      unlock();
    }
    void uncompressUnlocked()
    {
      if (compressed())
        {
          ;
          ;
   ++countUncompressed_m;
          block_m = DataBlockPtr<T>(size_m,dataObject_m);
   ++viewcount_m;
   ;
          ptr_m = block_m.currentPointer();
          block_m.attach(this);
          T *ptr = block_m.beginPointer();
          const T *const end = block_m.endPointer();
          while (ptr != end)
        {
       ElementProperties<T>::construct(ptr++,compressedData_m);
     }
          Observable<T*>::notify(notifyUncompress);
          ;
        }
    }
    inline void tryCompress()
    {
      if (!Pooma::neverCompress())
        {
          lock();
          tryCompressUnlocked();
          unlock();
        }
    }
    void tryCompressUnlocked()
    {
      if (!compressed() && compressible_m && !Pooma::neverCompress())
        {
          ;
          int size = block_m.size();
          bool failed = false;
          ;
          if (ucOffset_m > -1 && ucOffset_m < size)
            {
              if (block_m[ucOffset_m] != block_m[0]) failed = true;
            }
          if (!failed)
            {
              for (int i = 0; i < randomTries(); ++i)
                {
                  int elem = rand() % size;
                  if (block_m[elem] != block_m[0])
                    {
                      failed = true;
                      ucOffset_m = elem;
                      break;
                    }
                }
            }
          if (!failed)
            {
              const T *const begin = block_m.beginPointer();
              const T *const end = block_m.endPointer();
              const T * ptr;
              for (ptr = begin; ptr != end; ++ptr)
         {
           if (*ptr != *begin) break;
         }
              if (ptr == end)
         {
           block_m.detach();
           block_m.invalidate();
           --viewcount_m;
           ;
           compressedData_m = *begin;
           ptr_m = &compressedData_m;
           Observable<T*>::notify(notifyCompress);
           ;
           return;
         }
       else
         {
           ucOffset_m = ptr - begin;
         }
            }
          ;
        }
    }
    DataBlockPtr<T> view()
    {
      lock();
      if (compressed())
 {
   uncompressUnlocked();
 }
      compressible_m = false;
      unlock();
      return block_m;
    }
    DataBlockPtr<T> dataBlock()
    {
      return block_m;
    }
    inline T* data()
    {
      return ptr_m;
    }
    bool compressed() const
    {
      return ptr_m == &compressedData_m;
    }
    DataObject_t* dataObject()
    {
      return &dataObject_m;
    }
    void lock() const
    {
      mutex_m.lock();
    }
    void unlock() const
    {
      mutex_m.unlock();
    }
    bool isValidUnlocked()
    {
      return compressed() || block_m.isValid();
    }
    bool isValid()
    {
      lock();
      bool valid = isValidUnlocked();
      unlock();
      return valid;
    }
  static int randomTries() { return randomTries_s; }
  private:
    virtual void notify(const int& , const ObserverEvent &event)
    {
      switch (event.event())
      {
        case DataBlockController<T>::addViewEvent:
   viewmutex_m.lock();
   ++viewcount_m;
   viewmutex_m.unlock();
   break;
        case DataBlockController<T>::removeViewEvent:
   viewmutex_m.lock();
   --viewcount_m;
   if (viewcount_m == 1 && !Pooma::neverCompress())
     {
       lock();
       compressible_m = true;
       tryCompressUnlocked();
       unlock();
            }
   viewmutex_m.unlock();
          break;
        default:
          if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Invalid event code sent to CompressibleBlockController::notify()", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/CompressibleBlock.h", 954);
      }
    }
    bool compressible_m;
    int countUncompressed_m;
    DataBlockPtr<T> block_m;
    mutable int viewcount_m;
    mutable Pooma::Mutex_t viewmutex_m;
    DataObject_t dataObject_m;
    int size_m;
    T compressedData_m;
    T *ptr_m;
    int ucOffset_m;
    mutable Pooma::Mutex_t mutex_m;
    enum { randomTries_s = 20 };
  };
  RefCountedPtr<CompressibleBlockController> controller_m;
};
struct CompressibleBrick { };
struct CompressibleBrickView { };
template <int Dim, class T>
class Engine<Dim, T, CompressibleBrickView>;
template <int D1, int D2> class SliceInterval;
template <int D1, int D2> class SliceRange;
template <int Dim, class T>
class Engine<Dim, T, CompressibleBrick>
  : public Pooma::BrickBase<Dim>, public Observer<T*>
{
public:
  typedef Engine<Dim,T,CompressibleBrick> This_t;
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef Pooma::BrickBase<Dim> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef T& ElementRef_t;
  typedef CompressibleBrick Tag_t;
  enum { brick = true };
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = false };
  Engine() : data0_m(0) { }
  explicit Engine(const Domain_t &domain);
  Engine(const Domain_t &domain, const T &elementModel);
  explicit Engine(const Layout_t &layout);
  explicit Engine(const Node<Domain_t> &node);
  Engine(const Engine_t &model);
  ~Engine();
  Engine_t &operator=(const Engine_t &model);
  ElementRef_t operator()(int) const;
  ElementRef_t operator()(int, int) const;
  ElementRef_t operator()(int, int, int) const;
  ElementRef_t operator()(int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int, int) const;
  Element_t read(int) const;
  Element_t read(int, int) const;
  Element_t read(int, int, int) const;
  Element_t read(int, int, int, int) const;
  Element_t read(int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int, int) const;
  ElementRef_t operator()(const Loc<Dim> &) const;
  Element_t read(const Loc<Dim> &) const;
  inline const Domain_t &domain() const
  {
    return this->layout_m.domain();
  }
  Engine_t &makeOwnCopy();
  Pooma::DataObject_t *dataObject() const { return cblock_m.dataObject(); }
  DataBlockPtr<T> dataBlock() const { return cblock_m.view(); }
  CompressibleBlock<T> cblock() const { return cblock_m; }
  bool compressed() const;
  long elementsCompressed() const;
  void tryCompress() { cblock_m.tryCompress(); }
  void uncompress() { cblock_m.uncompress(); }
  T compressedRead() const;
  T& compressedReadWrite() const;
  bool compressedBrickIsWholeView() const { return true; }
private:
  CompressibleBlock<T> cblock_m;
  T *data0_m;
  mutable Pooma::Mutex_t mutex_m;
  inline void lock() const { mutex_m.lock(); }
  inline void unlock() const { mutex_m.unlock(); }
  virtual void notify(T* &data, const ObserverEvent &event);
  void resetDataAndStrides();
  void init();
};
template <int Dim, class T>
class Engine<Dim,T,CompressibleBrickView>
  : public Pooma::BrickViewBase<Dim>, public Observer<T*>
{
public:
  typedef Engine<Dim,T,CompressibleBrickView> This_t;
  typedef Engine<Dim,T,CompressibleBrickView> Engine_t;
  typedef Pooma::BrickViewBase<Dim> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef T& ElementRef_t;
  typedef CompressibleBrickView Tag_t;
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = true };
  enum { multiPatch = false };
  Engine() : data0_m(0) { }
  Engine(const Engine_t &model);
  Engine(const Engine_t &model, const EngineConstructTag &);
  template <class DT>
  Engine(const Engine<Dim,T,CompressibleBrick> &e, const Domain<Dim, DT> &dom)
  : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
    entire_m(e.domain() == dom.unwrap())
  {
    init();
  }
  template <class Domain>
  Engine(const Engine<Dim,T,CompressibleBrick> &e, const Node<Domain> &node)
    : Base_t(e, node.domain()), cblock_m(e.cblock()),
      entire_m(e.domain() == node.domain())
  {
    init();
  }
  Engine(const Engine<Dim,T,CompressibleBrick> &e, const INode<Dim> &inode)
  : Base_t(e, inode.domain()), cblock_m(e.cblock()),
    entire_m(e.domain() == inode.domain())
  {
    init();
  }
  template <class DT, int Dim2>
  Engine(const Engine<Dim2,T,CompressibleBrick> &e, const SliceDomain<DT> &dom)
  : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
    entire_m(e.domain() == dom.totalDomain())
  {
    init();
  }
  template <class DT>
  Engine(const This_t &e, const Domain<Dim, DT> &dom)
  : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
    entire_m(e.entire_m && e.domain() == dom.unwrap())
  {
    init();
  }
  Engine(const This_t &e, const INode<Dim> &inode)
  : Base_t(e, inode.domain()), cblock_m(e.cblock()),
    entire_m(e.entire_m && e.domain() == inode.domain())
  {
    init();
  }
  template <int OrigDim, class DT>
  Engine(const Engine<OrigDim,T,CompressibleBrickView> &e,
  const SliceDomain<DT> &dom)
  : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
    entire_m(e.entire_m && e.domain() == dom.totalDomain())
  {
    init();
  }
  ~Engine();
  Engine_t &operator=(const Engine_t &model);
  ElementRef_t operator()(int) const;
  ElementRef_t operator()(int, int) const;
  ElementRef_t operator()(int, int, int) const;
  ElementRef_t operator()(int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int, int) const;
  Element_t read(int) const;
  Element_t read(int, int) const;
  Element_t read(int, int, int) const;
  Element_t read(int, int, int, int) const;
  Element_t read(int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int, int) const;
  ElementRef_t operator()(const Loc<Dim> &) const;
  Element_t read(const Loc<Dim> &) const;
  inline const Domain_t &domain() const
  {
    return this->domain_m;
  }
  DataBlockPtr<T> dataBlock() const { return cblock_m.view(); }
  inline
  Pooma::DataObject_t *dataObject() const { return cblock_m.dataObject(); }
  CompressibleBlock<T> cblock() const { return cblock_m; }
  bool compressed() const { return cblock_m.compressed(); }
  T compressedRead() const;
  T& compressedReadWrite() const;
  bool compressedBrickIsWholeView() const { return entire_m; }
  long elementsCompressed() const;
private:
  void lock() const { mutex_m.lock(); }
  void unlock() const { mutex_m.unlock(); }
  virtual void notify(T* &data, const ObserverEvent &event)
  {
    switch (event.event())
      {
      default:
      case CompressibleBlock<T>::notifyDestruct:
 ;
 break;
      case CompressibleBlock<T>::notifyUncompress:
        lock();
        this->restoreStrides();
 data0_m = data + this->baseOffset();
 unlock();
 break;
      case CompressibleBlock<T>::notifyCompress:
        lock();
        this->zeroStrides();
 data0_m = data;
 unlock();
 break;
      }
  }
  void init()
  {
    cblock_m.lock();
    resetDataAndStrides();
    ;
    cblock_m.attach(this);
    cblock_m.unlock();
  }
  void resetDataAndStrides()
  {
    if (cblock_m.compressed())
      {
        this->zeroStrides();
 data0_m = cblock_m.data();
      }
    else
      {
        this->restoreStrides();
 data0_m = cblock_m.data() + this->baseOffset();
      }
  }
  CompressibleBlock<T> cblock_m;
  T *data0_m;
  bool entire_m;
  mutable Pooma::Mutex_t mutex_m;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrick>, Interval<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrick>, Range<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrick>,Node<Interval<Dim> > >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrick>,INode<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>, Interval<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>, Range<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
                 Node<Interval<Dim> > >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>,INode<Dim> >
{
  typedef Engine<Dim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,CompressibleBrick>,SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,CompressibleBrick>,SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
                 SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
                 SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
};
template <int Dim, class T>
struct ElementProperties<Engine<Dim, T, CompressibleBrick> >
  : public MakeOwnCopyProperties<Engine<Dim, T, CompressibleBrick> >
{ };
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(const Loc<Dim> &loc) const
{
  return data0_m[this->offsetC(loc)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1) const
{
  ;
  return data0_m[this->offsetC(i1)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2) const
{
  ;
  return data0_m[this->offsetC(i1,i2)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2, int i3) const
{
  ;
  return data0_m[this->offsetC(i1,i2,i3)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2, int i3, int i4) const
{
  ;
  return data0_m[this->offsetC(i1,i2,i3,i4)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  return data0_m[this->offsetC(i1,i2,i3,i4,i5)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrick>::
read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6,i7)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(const Loc<Dim> &loc) const
{
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(loc)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2, int i3) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2,i3)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2, int i3, int i4) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2,i3,i4)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2,i3,i4,i5)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrick>::
operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6,i7)];
}
template <int Dim, class T>
inline bool
Engine<Dim,T,CompressibleBrick>::
compressed() const
{
  ;
  return cblock_m.compressed();
}
template <int Dim, class T>
inline T
Engine<Dim,T,CompressibleBrick>::
compressedRead() const
{
  ;
  ;
  return *data0_m;
}
template <int Dim, class T>
inline T&
Engine<Dim,T,CompressibleBrick>::
compressedReadWrite() const
{
  ;
  ;
  return *data0_m;
}
template <int Dim, class T>
inline bool compressed(const Engine<Dim, T, CompressibleBrick> &e)
{
  return e.compressed();
}
template <int Dim, class T>
inline long elementsCompressed(const Engine<Dim, T, CompressibleBrick> &e)
{
  return e.elementsCompressed();
}
template <int Dim, class T>
inline void compress(Engine<Dim, T, CompressibleBrick> &e)
{
  e.tryCompress();
}
template <int Dim, class T>
inline void uncompress(Engine<Dim, T, CompressibleBrick> &e)
{
  e.uncompress();
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(const Loc<Dim> &loc) const
{
  return data0_m[this->offset(loc)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1) const
{
  ;
  return data0_m[this->offset(i1)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2) const
{
  ;
  return data0_m[this->offset(i1,i2)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2, int i3) const
{
  ;
  return data0_m[this->offset(i1,i2,i3)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2, int i3, int i4) const
{
  ;
  return data0_m[this->offset(i1,i2,i3,i4)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  return data0_m[this->offset(i1,i2,i3,i4,i5)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  return data0_m[this->offset(i1,i2,i3,i4,i5,i6)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  return data0_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(const Loc<Dim> &loc) const
{
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(loc)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2, int i3) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2,i3)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2, int i3, int i4) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2,i3,i4)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2,i3,i4,i5)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2,i3,i4,i5,i6)];
}
template <int Dim, class T>
inline T & Engine<Dim,T,CompressibleBrickView>::
operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  if (cblock_m.compressed()) cblock_m.uncompress();
  return data0_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
}
template <int Dim, class T>
inline T Engine<Dim,T,CompressibleBrickView>::
compressedRead() const
{
  ;
  return *data0_m;
}
template <int Dim, class T>
inline T& Engine<Dim,T,CompressibleBrickView>::
compressedReadWrite() const
{
  ;
  return *data0_m;
}
template <int Dim, class T>
inline
bool compressed(const Engine<Dim,T,CompressibleBrickView> &e)
{
  return e.compressed();
}
template <int Dim, class T>
inline
long elementsCompressed(const Engine<Dim,T,CompressibleBrickView> &e)
{
  return e.elementsCompressed();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::Engine(const Domain_t &domain)
  : Base_t(domain), cblock_m(domain.size())
{
  init();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::Engine(const Node<Domain_t> &node)
  : Base_t(node.allocated()),
    cblock_m(node.allocated().size(), node.affinity())
{
  init();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::Engine(const Layout_t &layout)
  : Base_t(layout.domain()), cblock_m(layout.domain().size())
{
  init();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::Engine(const Domain_t &domain, const T& model)
  : Base_t(domain), cblock_m(domain.size(),-1,model)
{
  init();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::
Engine(const Engine<Dim,T,CompressibleBrick> &modelEngine)
  : cblock_m(modelEngine.cblock_m)
{
  cblock_m.lock();
  data0_m = modelEngine.data0_m;
  Base_t::operator=(modelEngine);
  if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
  cblock_m.unlock();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick> &
Engine<Dim,T,CompressibleBrick>::
operator=(const Engine<Dim,T,CompressibleBrick> &modelEngine)
{
  if (this != &modelEngine)
    {
      ;
      modelEngine.cblock_m.lock();
      if (cblock_m.isControllerPtrValid())
        {
          cblock_m.lock();
          if (cblock_m.isControllerValidUnlocked())
            {
              cblock_m.detach(this);
            }
          cblock_m.unlock();
        }
      cblock_m = modelEngine.cblock_m;
      lock();
      data0_m = modelEngine.data0_m;
      Base_t::operator=(modelEngine);
      unlock();
      if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
      cblock_m.unlock();
    }
  return *this;
}
template <int Dim, class T>
void Engine<Dim,T,CompressibleBrick>::init()
{
  resetDataAndStrides();
  ;
  cblock_m.attach(this);
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick>::~Engine()
{
  if (data0_m)
    {
      cblock_m.lock();
      if (cblock_m.isControllerValidUnlocked())
        {
          cblock_m.detach(this);
        }
      cblock_m.unlock();
    }
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrick> &Engine<Dim,T,CompressibleBrick>::makeOwnCopy()
{
  if (cblock_m.isControllerValidUnlocked() && cblock_m.isShared())
    {
      cblock_m.detach(this);
      cblock_m.makeOwnCopy();
      cblock_m.attach(this);
      data0_m = cblock_m.data() + (cblock_m.compressed() ? 0 : this->baseOffset());
    }
  return *this;
}
template <int Dim, class T>
void Engine<Dim,T,CompressibleBrick>::
notify(T* &data, const ObserverEvent &event)
{
  switch (event.event())
    {
    default:
    case CompressibleBlock<T>::notifyDestruct:
      ;
      break;
    case CompressibleBlock<T>::notifyUncompress:
      lock();
      this->restoreStrides();
      data0_m = data + this->baseOffset();
      unlock();
      break;
    case CompressibleBlock<T>::notifyCompress:
      lock();
      this->zeroStrides();
      data0_m = data;
      unlock();
      break;
    }
}
template <int Dim, class T>
void Engine<Dim,T,CompressibleBrick>::resetDataAndStrides()
{
  if (cblock_m.compressed())
    {
      this->zeroStrides();
      data0_m = cblock_m.data();
    }
  else
    {
      this->restoreStrides();
      data0_m = cblock_m.data() + this->baseOffset();
    }
}
template <int Dim, class T>
long Engine<Dim,T,CompressibleBrick>::
elementsCompressed() const
{
  if (compressed())
    return domain().size();
  else
    return 0L;
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrickView>::
~Engine()
{
  cblock_m.lock();
  if (cblock_m.isControllerValidUnlocked())
    {
      cblock_m.detach(this);
    }
  cblock_m.unlock();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrickView> &
Engine<Dim,T,CompressibleBrickView>::
operator=(const Engine<Dim,T,CompressibleBrickView> &modelEngine)
{
  if (this != &modelEngine)
    {
      ;
      modelEngine.cblock_m.lock();
      if (cblock_m.isControllerPtrValid())
        {
          cblock_m.lock();
          if (cblock_m.isControllerValidUnlocked())
            {
              cblock_m.detach(this);
            }
          cblock_m.unlock();
        }
      cblock_m = modelEngine.cblock_m;
      entire_m = modelEngine.entire_m;
      lock();
      data0_m = modelEngine.data0_m;
      Base_t::operator=(modelEngine);
      unlock();
      if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
      cblock_m.unlock();
    }
  return *this;
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrickView>::
Engine(const Engine<Dim,T,CompressibleBrickView> &modelEngine)
  : cblock_m(modelEngine.cblock_m),
    entire_m(modelEngine.entire_m)
{
  cblock_m.lock();
  data0_m = modelEngine.data0_m;
  Base_t::operator=(modelEngine);
  if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
  cblock_m.unlock();
}
template <int Dim, class T>
Engine<Dim,T,CompressibleBrickView>::
Engine(const Engine<Dim,T,CompressibleBrickView> &modelEngine,
       const EngineConstructTag &)
  : cblock_m(modelEngine.cblock_m),
    entire_m(modelEngine.entire_m)
{
  cblock_m.lock();
  data0_m = modelEngine.data0_m;
  Base_t::operator=(modelEngine);
  if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
  cblock_m.unlock();
}
template <int Dim, class T>
long Engine<Dim,T,CompressibleBrickView>::
elementsCompressed() const
{
  if (compressed())
    return domain().size();
  else
    return 0L;
}
template <int Dim> class Range;
struct Brick {};
struct BrickView {};
struct BrickViewU {};
template <int Dim, class T>
class Engine<Dim,T,BrickView>;
template <int Dim, class T>
class Engine<Dim,T,Brick> : public Pooma::BrickBase<Dim>
{
public:
  typedef Engine<Dim,T,Brick> This_t;
  typedef Engine<Dim,T,Brick> Engine_t;
  typedef Pooma::BrickBase<Dim> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef T& ElementRef_t;
  typedef Brick Tag_t;
  enum { brick = true };
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = false };
  Engine() { }
  explicit Engine(const Domain_t &domain);
  Engine(const Domain_t &domain, const T &elementModel);
  explicit Engine(const Layout_t &layout);
  explicit Engine(const Node<Domain_t> &node);
  Engine(T * foreignData, const Domain_t &domain);
  Engine(const This_t &model)
    : Base_t(model), dataBlock_m(model.dataBlock_m),
      data_m(model.data_m)
  {}
  ~Engine() {}
  This_t &operator=(const This_t &model)
  {
    if (this == &model)
      return *this;
    Base_t::operator=(model);
    dataBlock_m = model.dataBlock_m;
    data_m = model.data_m;
    ;
    return *this;
  }
  Element_t read(const Loc<Dim> &loc) const
  {
    return data_m[this->offset(loc)];
  }
  ElementRef_t operator()(const Loc<Dim> &loc) const
  {
    return data_m[this->offset(loc)];
  }
  Element_t read(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offset(i1)];
  }
  Element_t read(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offset(i1,i2)];
  }
  Element_t read(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offset(i1,i2,i3)];
  }
  Element_t read(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offset(i1,i2,i3,i4)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
  }
  ElementRef_t operator()(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offset(i1)];
  }
  ElementRef_t operator()(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offset(i1,i2)];
  }
  ElementRef_t operator()(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offset(i1,i2,i3)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offset(i1,i2,i3,i4)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
  }
  Engine_t &makeOwnCopy();
  inline
  Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
  DataBlockPtr<T> dataBlock() { return dataBlock_m; }
  const DataBlockPtr<T> & dataBlock() const { return dataBlock_m; }
  bool isShared() const { return dataBlock_m.isValid() && dataBlock_m.count() > 1; }
private:
  DataBlockPtr<T> dataBlock_m;
  T *data_m;
};
template <int Dim, class T>
Engine<Dim,T,Brick>::Engine(const Domain_t &dom)
  : Base_t(dom), dataBlock_m(dom.size()), data_m(dataBlock_m.currentPointer())
{ }
template <int Dim, class T>
Engine<Dim,T,Brick>::Engine(const Node<Domain_t> &node)
  : Base_t(node),
    dataBlock_m(node.allocated().size(), node.affinity(),
           typename DataBlockPtr<T>::WithAffinity_t()),
    data_m(dataBlock_m.currentPointer())
{ }
template <int Dim, class T>
Engine<Dim,T,Brick>::Engine(const Layout_t &layout)
  : Base_t(layout), dataBlock_m(layout.domain().size()),
    data_m(dataBlock_m.currentPointer())
{ }
template <int Dim, class T>
Engine<Dim,T,Brick>::Engine(const Domain_t &dom, const T& model)
  : Base_t(dom), dataBlock_m(dom.size(), model),
    data_m(dataBlock_m.currentPointer())
{ }
template <int Dim, class T>
Engine<Dim,T,Brick>::Engine(T * foreignData, const Domain_t &dom)
  : Base_t(dom), dataBlock_m(foreignData, dom.size()),
    data_m(dataBlock_m.currentPointer())
{ }
template <int Dim, class T>
Engine<Dim,T,Brick> &Engine<Dim,T,Brick>::makeOwnCopy()
{
  if (dataBlock_m.isValid() && dataBlock_m.count() > 1)
    {
      ;
      dataBlock_m.makeOwnCopy();
      data_m = dataBlock_m.currentPointer();
    }
  return *this;
}
template <int Dim, class T>
class Engine<Dim,T,BrickView>
 : public Pooma::BrickViewBase<Dim>
{
public:
  typedef Engine<Dim,T,BrickView> This_t;
  typedef Engine<Dim,T,BrickView> Engine_t;
  typedef Pooma::BrickViewBase<Dim> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef T& ElementRef_t;
  typedef BrickView Tag_t;
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = true };
  enum { multiPatch = false };
  Engine()
    : Base_t(), dataBlock_m(), data_m(0)
  {}
  Engine(const This_t &model)
    : Base_t(model), dataBlock_m(model.dataBlock_m),
      data_m(dataBlock_m.currentPointer())
  {}
  Engine(const This_t &model, const EngineConstructTag &)
    : Base_t(model), dataBlock_m(model.dataBlock_m),
      data_m(dataBlock_m.currentPointer())
  {}
  template <class DT>
  Engine(const Engine<Dim,T,Brick> &e, const Domain<Dim, DT> &dom)
  : Base_t(e, dom.unwrap()), dataBlock_m(e.dataBlock(), e.offset(dom.unwrap())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template<int Dim2>
  Engine(const Engine<Dim2,T,Brick> &e, const SliceRange<Dim2,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template<int Dim2>
  Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim2,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template <int Dim2>
  Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim,Dim2> &dom,
  const Interval<Dim> &totalDomain)
    : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
      data_m(dataBlock_m.currentPointer())
  {
  }
  template <int Dim2>
  Engine(const Engine<Dim2,T,BrickView> &e, const SliceInterval<Dim,Dim2> &dom,
  const Interval<Dim> &totalDomain)
    : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
      data_m(dataBlock_m.currentPointer())
  {
  }
  template <int Dim2>
  Engine(const Engine<Dim2,T,BrickViewU> &e, const SliceInterval<Dim,Dim2> &dom,
  const Interval<Dim> &totalDomain)
    : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
      data_m(dataBlock_m.currentPointer())
  {
  }
  template <class DT>
  Engine(const This_t &e, const Domain<Dim, DT> &d)
    : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <class DT>
  Engine(const Engine<Dim,T,BrickViewU> &e, const Domain<Dim, DT> &d)
    : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
    data_m(dataBlock_m.currentPointer())
  { }
  Engine(const This_t &e, const INode<Dim> &inode)
    : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
    data_m(dataBlock_m.currentPointer())
  { }
  Engine(const Engine<Dim,T,BrickViewU> &e, const INode<Dim> &inode)
    : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickView> &e,
         const SliceRange<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickViewU> &e,
         const SliceRange<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickView> &e,
  const SliceInterval<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickViewU> &e,
    const SliceInterval<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  explicit Engine(const Engine<Dim,T,CompressibleBrick> &);
  explicit Engine(const Engine<Dim,T,CompressibleBrickView> &);
  ~Engine() {}
  This_t &operator=(const This_t &model)
  {
    if (this == &model)
      return *this;
    Base_t::operator=(model);
    dataBlock_m = model.dataBlock_m;
    data_m = model.data_m;
    return *this;
  }
  Element_t read(const Loc<Dim> &loc) const
  {
    return data_m[this->offset(loc)];
  }
  ElementRef_t operator()(const Loc<Dim> &loc) const
  {
    return data_m[this->offset(loc)];
  }
  Element_t read(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offset(i1)];
  }
  Element_t read(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offset(i1,i2)];
  }
  Element_t read(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offset(i1,i2,i3)];
  }
  Element_t read(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offset(i1,i2,i3,i4)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
  }
  ElementRef_t operator()(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offset(i1)];
  }
  ElementRef_t operator()(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offset(i1,i2)];
  }
  ElementRef_t operator()(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offset(i1,i2,i3)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offset(i1,i2,i3,i4)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
  }
  DataBlockPtr<T> dataBlock() { return dataBlock_m; }
  const DataBlockPtr<T> &dataBlock() const { return dataBlock_m; }
  inline
  Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
private:
  DataBlockPtr<T> dataBlock_m;
  T *data_m;
};
template <int Dim, class T>
Engine<Dim,T,BrickView>::
Engine(const Engine<Dim,T,CompressibleBrick> &model)
  : Base_t(model, false)
{
  dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
  data_m = dataBlock_m.currentPointer();
}
template <int Dim, class T>
Engine<Dim,T,BrickView>::
Engine(const Engine<Dim,T,CompressibleBrickView> &model)
  : Base_t(model, false)
{
  dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
  data_m = dataBlock_m.currentPointer();
}
template <int Dim, class T>
class Engine<Dim,T,BrickViewU>
 : public Pooma::BrickViewBase<Dim>
{
public:
  typedef Engine<Dim,T,BrickViewU> This_t;
  typedef Engine<Dim,T,BrickViewU> Engine_t;
  typedef Pooma::BrickViewBase<Dim> Base_t;
  typedef typename Base_t::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef T& ElementRef_t;
  typedef BrickViewU Tag_t;
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = true };
  enum { multiPatch = false };
  Engine()
    : Base_t(), dataBlock_m(), data_m(0)
  {}
  Engine(const This_t &model)
    : Base_t(model), dataBlock_m(model.dataBlock_m),
      data_m(dataBlock_m.currentPointer())
  {}
  Engine(const This_t &model, const EngineConstructTag &)
    : Base_t(model), dataBlock_m(model.dataBlock_m),
      data_m(dataBlock_m.currentPointer())
  {}
  template <class ETag, class DT>
  Engine(const Engine<Dim,T,ETag> &e, const Domain<Dim, DT> &dom)
  : Base_t(e, dom.unwrap()), dataBlock_m(e.dataBlock(), e.offset(dom.unwrap())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template<int Dim2>
  Engine(const Engine<Dim2,T,Brick> &e, const SliceRange<Dim2,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template<int Dim2>
  Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim2,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  {
    ;
  }
  template <class DT>
  Engine(const This_t &e, const Domain<Dim, DT> &d)
    : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
    data_m(dataBlock_m.currentPointer())
  { }
  Engine(const This_t &e, const INode<Dim> &inode)
    : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickView> &e,
         const SliceRange<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  template <int ODim>
  Engine(const Engine<ODim,T,BrickViewU> &e,
    const SliceInterval<ODim,Dim> &dom)
    : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
    data_m(dataBlock_m.currentPointer())
  { }
  explicit Engine(const Engine<Dim,T,CompressibleBrick> &);
  explicit Engine(const Engine<Dim,T,CompressibleBrickView> &);
  ~Engine() {}
  This_t &operator=(const This_t &model)
  {
    if (this == &model)
      return *this;
    Base_t::operator=(model);
    dataBlock_m = model.dataBlock_m;
    data_m = model.data_m;
    return *this;
  }
  Element_t read(const Loc<Dim> &loc) const
  {
    return data_m[this->offsetU(loc)];
  }
  ElementRef_t operator()(const Loc<Dim> &loc) const
  {
    return data_m[this->offsetU(loc)];
  }
  Element_t read(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offsetU(i1)];
  }
  Element_t read(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offsetU(i1,i2)];
  }
  Element_t read(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offsetU(i1,i2,i3)];
  }
  Element_t read(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5,i6)];
  }
  Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5,i6,i7)];
  }
  ElementRef_t operator()(int i1) const
  {
    PoomaCTAssert<(Dim == 1)>::test();
    return data_m[this->offsetU(i1)];
  }
  ElementRef_t operator()(int i1, int i2) const
  {
    PoomaCTAssert<(Dim == 2)>::test();
    return data_m[this->offsetU(i1,i2)];
  }
  ElementRef_t operator()(int i1, int i2, int i3) const
  {
    PoomaCTAssert<(Dim == 3)>::test();
    return data_m[this->offsetU(i1,i2,i3)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4) const
  {
    PoomaCTAssert<(Dim == 4)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
  {
    PoomaCTAssert<(Dim == 5)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
  {
    PoomaCTAssert<(Dim == 6)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5,i6)];
  }
  ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
  {
    PoomaCTAssert<(Dim == 7)>::test();
    return data_m[this->offsetU(i1,i2,i3,i4,i5,i6,i7)];
  }
  DataBlockPtr<T> dataBlock() { return dataBlock_m; }
  const DataBlockPtr<T> &dataBlock() const { return dataBlock_m; }
  inline
  Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
private:
  DataBlockPtr<T> dataBlock_m;
  T *data_m;
};
template <int Dim, class T>
Engine<Dim,T,BrickViewU>::
Engine(const Engine<Dim,T,CompressibleBrick> &model)
  : Base_t(model, false)
{
  dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
  data_m = dataBlock_m.currentPointer();
}
template <int Dim, class T>
Engine<Dim,T,BrickViewU>::
Engine(const Engine<Dim,T,CompressibleBrickView> &model)
  : Base_t(model, false)
{
  dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
  data_m = dataBlock_m.currentPointer();
}
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,Brick>, Interval<Dim> >
{
  typedef Engine<Dim,T,BrickViewU> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,Brick>, Range<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,Brick>, Node<Interval<Dim> > >
{
  typedef Engine<Dim,T,BrickViewU> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,Brick>, INode<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,Brick>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,Brick>, SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<SliceDim,T,Brick>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<SliceDim,T,BrickView>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<SliceDim,T,BrickViewU>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickView>, Interval<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickView>, Range<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickView>, Node<Interval<Dim> > >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickView>, INode<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,BrickView>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,BrickView>, SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickViewU>, Interval<Dim> >
{
  typedef Engine<Dim,T,BrickViewU> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickViewU>, Range<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickViewU>, Node<Interval<Dim> > >
{
  typedef Engine<Dim,T,BrickViewU> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim,T,BrickViewU>, INode<Dim> >
{
  typedef Engine<Dim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,BrickViewU>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,BrickViewU>, SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,BrickView> Type_t;
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,Brick>, Node<Interval<Dim> > >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,Brick> &,
   const Node<Interval<Dim> > &node)
  {
    return node.domain();
  }
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,Brick>, INode<Dim> >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,Brick> &,
   const INode<Dim> &inode)
  {
    return inode.domain();
  }
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,BrickView>, Node<Interval<Dim> > >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,BrickView> &,
   const Node<Interval<Dim> > &node)
  {
    return node.domain();
  }
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,BrickView>, INode<Dim> >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,BrickView> &,
   const INode<Dim> &inode)
  {
    return inode.domain();
  }
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,BrickViewU>, Node<Interval<Dim> > >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,BrickViewU> &,
   const Node<Interval<Dim> > &node)
  {
    return node.domain();
  }
};
template <int Dim, class T>
struct NewEngineDomain<Engine<Dim,T,BrickViewU>, INode<Dim> >
{
  typedef Interval<Dim> Type_t;
  typedef const Interval<Dim> &Return_t;
  static inline
  Return_t apply(const Engine<Dim,T,BrickViewU> &,
   const INode<Dim> &inode)
  {
    return inode.domain();
  }
};
template <int Dim, class T>
struct ElementProperties<Engine<Dim, T, Brick> >
  : public MakeOwnCopyProperties<Engine<Dim, T, Brick> >
{ };
template <class Expr>
inline bool compressed(const Expr &expr)
{
  return false;
}
template <class Expr>
double compressedFraction(const Expr &expr)
{
  return static_cast<double>(elementsCompressed(expr)) / expr.domain().size();
}
template <class Expr>
inline long elementsCompressed(const Expr &expr)
{
  return 0L;
}
template <class Expr>
inline void compress(Expr &)
{ }
template <class Expr>
inline void uncompress(Expr &)
{ }
struct ConstantFunction
{ };
template<int Dim, class T>
class Engine<Dim, T, ConstantFunction>
{
public:
  typedef ConstantFunction Tag_t;
  typedef Engine<Dim, T, ConstantFunction> This_t;
  typedef This_t Engine_t;
  typedef Interval<Dim> Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  enum { dimensions = Dim };
  enum { hasDataObject = false };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = false };
  Engine() { }
  explicit Engine(const Domain_t &domain, T val = T())
  : val_m(val), domain_m(domain)
  {
    for (int d = 0; d < Dim; ++d)
      firsts_m[d] = domain[d].first();
  }
  template<class Layout>
  explicit Engine(const Layout &layout, T val = T())
  : val_m(val), domain_m(layout.domain())
  {
    for (int d = 0; d < Dim; ++d)
      firsts_m[d] = domain_m[d].first();
  }
  Engine(const Engine<Dim, T, ConstantFunction> &model)
  : val_m(model.constant()), domain_m(model.domain())
  {
    for (int d = 0; d < Dim; ++d)
      {
        firsts_m[d] = model.firsts_m[d];
      }
  }
  template<class DT>
  Engine(const Engine<Dim, T, ConstantFunction> &e, const Domain<Dim, DT> &dom)
  : val_m(e.constant()), domain_m(Pooma::NoInit())
  {
    const typename DT::Domain_t &domain = dom.unwrap();
    for (int d = 0; d < Dim; ++d)
      {
        domain_m[d] = Interval<1>(domain[d].length());
        firsts_m[d] = 0;
      }
  }
  template<int Dim2, class DT>
  Engine(const Engine<Dim2, T, ConstantFunction> &e,
    const SliceDomain<DT> &dom)
  : val_m(e.constant()), domain_m(Pooma::NoInit())
  {
    PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<(DT::dimensions == Dim2)>::test();
    const typename DT::SliceDomain_t &domain = dom.sliceDomain();
    for (int d = 0; d < Dim; ++d)
      {
        domain_m[d] = Interval<1>(domain[d].length());
        firsts_m[d] = 0;
      }
  }
  template<class Domain>
  Engine(const Engine<Dim, T, ConstantFunction> &e, const Node<Domain> &node)
  : val_m(e.constant()), domain_m(Pooma::NoInit())
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
    const Domain &domain = node.domain();
    for (int d = 0; d < Dim; ++d)
      {
        domain_m[d] = Interval<1>(domain[d].length());
        firsts_m[d] = 0;
      }
  }
  Engine(const Engine<Dim, T, ConstantFunction> &e, const INode<Dim> &inode)
  : val_m(e.constant()), domain_m(Pooma::NoInit())
  {
    const typename INode<Dim>::Domain_t &domain = inode.domain();
    for (int d = 0; d < Dim; ++d)
      {
        domain_m[d] = Interval<1>(domain[d].length());
        firsts_m[d] = 0;
      }
  }
  inline Element_t read(int) const
    {
      return val_m;
    }
  inline Element_t read(int, int) const
    {
      return val_m;
    }
  inline Element_t read(int, int, int) const
    {
      return val_m;
    }
  inline Element_t read(int, int, int, int) const
    {
      return val_m;
    }
  inline Element_t read(int, int, int, int, int) const
    {
      return val_m;
    }
  inline Element_t read(int, int, int, int, int, int) const
    {
      return val_m;
    }
  inline Element_t read(int, int, int, int, int, int, int) const
    {
      return val_m;
    }
  inline Element_t read(const Loc<Dim> &) const
    {
      return val_m;
    }
  const Domain_t &domain() const { return domain_m; }
  inline Layout_t layout() const { return Layout_t(domain_m); }
  inline int first(int i) const
  {
    ;
    return firsts_m[i];
  }
  T constant() const { return val_m; }
  void setConstant(T val) { val_m = val; }
private:
  T val_m;
  Domain_t domain_m;
  int firsts_m[Dim];
};
template <int Dim, class T>
struct NewEngine<Engine<Dim, T, ConstantFunction>, Interval<Dim> >
{
  typedef Engine<Dim, T, ConstantFunction> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim, T, ConstantFunction>, Range<Dim> >
{
  typedef Engine<Dim, T, ConstantFunction> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,ConstantFunction>, SliceInterval<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,ConstantFunction> Type_t;
};
template <int Dim, class T, int SliceDim>
struct NewEngine<Engine<Dim,T,ConstantFunction>, SliceRange<Dim,SliceDim> >
{
  typedef Engine<SliceDim,T,ConstantFunction> Type_t;
};
template <int Dim, class T, class Domain>
struct NewEngine<Engine<Dim, T, ConstantFunction>, Node<Domain> >
{
  typedef Engine<Dim, T, ConstantFunction> Type_t;
};
template <int Dim, class T>
struct NewEngine<Engine<Dim, T, ConstantFunction>, INode<Dim> >
{
  typedef Engine<Dim, T, ConstantFunction> Type_t;
};
struct ErrorDomain
{
};
struct NullDomain
{
};
template<class D>
bool contains(const NullDomain &, const D &)
{
  return true;
}
template<class Inter>
struct IntersectorTag
{
  inline IntersectorTag(Inter &i) : intersector_m(i) { }
  Inter &intersector_m;
};
template<class Eng, class Intersect>
struct DefaultExpressionApply<Eng, IntersectorTag<Intersect> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const Eng &,
        const ExpressionApply<IntersectorTag<Intersect> > &)
  {
    PoomaCTAssert<(!(Eng::multiPatch))>::test();
    return true;
  }
};
struct AssertEquals
{
  AssertEquals(int ignore = 0) : ignore_m(ignore) { }
  int ignore_m;
};
template<class Op>
struct Combine2<int, int, Op, AssertEquals>
{
  typedef int Type_t;
  inline static
  Type_t combine(const int &a, const int &b, const AssertEquals &ae)
  {
    int ret = a;
    if ((a != ae.ignore_m) && (b != ae.ignore_m))
    {
      ;
    }
    else
    {
      if (b != ae.ignore_m) return ret = b;
    }
    return ret;
  }
};
template<class Thing>
struct View0
{
};
template<class Thing, class Sub>
struct View1
{
};
template<class Thing, class Sub1, class Sub2>
struct View2
{
};
template<class Thing, class Sub1, class Sub2, class Sub3>
struct View3
{
};
template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4>
struct View4
{
};
template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
  class Sub5>
struct View5
{
};
template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
  class Sub5, class Sub6>
struct View6
{
};
template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
  class Sub5, class Sub6, class Sub7>
struct View7
{
};
template<class Components, class Object>
struct ComponentView;
struct EnginePatch
{
  typedef TreeCombine Combine_t;
  typedef int PatchID_t;
  explicit EnginePatch(PatchID_t patch) : patch_m(patch) { }
  PatchID_t patch_m;
};
template<class Eng>
struct EngineFunctorDefault<Eng, EnginePatch>
{
  typedef Eng Type_t;
  inline static
  const Type_t &apply(const Eng &e, const EnginePatch &)
  {
    PoomaCTAssert<(!(Eng::multiPatch))>::test();
    return e;
  }
};
template<class T>
struct LeafFunctor<Scalar<T>, EnginePatch>
{
  typedef Scalar<T> Type_t;
  inline static
  Type_t apply(const Scalar<T> &scalar, const EnginePatch &)
  {
    return scalar;
  }
};
template<class Container>
struct Patch
{
};
template<class Container>
struct PatchView
{
  typedef typename Patch<Container>::Type_t Patch_t;
  typedef typename Patch_t::Domain_t Dom_t;
  typedef typename View1<Patch_t, Dom_t>::Type_t Type_t;
  inline static
  Type_t make(const Container &subject, int i)
  {
    return subject.patchLocal(i)();
  }
};
template<class Node>
struct LeafFunctor<Node, EnginePatch>
{
  typedef typename PatchView<Node>::Type_t Type_t;
  inline static
  Type_t apply(const Node &node, const EnginePatch &tag)
  {
    return node.patchLocal(tag.patch_m)();
  }
};
struct EngineNumPatches
{
  typedef AssertEquals Combine_t;
};
template<class Eng>
struct EngineFunctorDefault<Eng, EngineNumPatches>
{
  typedef int Type_t;
  inline static
  Type_t apply(const Eng &, const EngineNumPatches &)
  {
    PoomaCTAssert<(!(Eng::multiPatch))>::test();
    return 1;
  }
};
template<class T>
struct EngineFunctorScalar<T, EngineNumPatches>
{
  typedef int Type_t;
  inline static
  Type_t apply(const T &, const EngineNumPatches &)
  {
    return 0;
  }
};
template <int Dim>
class DomainLayout;
template<int Dim>
struct EvalLeaf { };
template<class T, int Dim>
struct LeafFunctor<Scalar<T>, EvalLeaf<Dim> >
{
  typedef T Type_t;
  inline static
  Type_t apply(const Scalar<T> &s, const EvalLeaf<Dim> &)
    {
      return s.value();
    }
};
template<int Dim, class T, class E>
struct LeafFunctor<Engine<Dim, T, E>, EvalLeaf<Dim> >
{
  typedef T Type_t;
  inline static
  Type_t apply(const Engine<Dim, T, E> &e, const EvalLeaf<Dim> &t)
  {
    return t.eval(e);
  }
};
template<>
struct EvalLeaf<1>
{
  int i1_m;
  inline EvalLeaf(int i1)
    : i1_m(i1)
  { }
  inline EvalLeaf(const Loc<1> &loc)
    : i1_m(loc[0].first())
  { }
  inline int val1() const { return i1_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1());
  }
};
template<>
struct EvalLeaf<2>
{
  int i1_m, i2_m;
  inline EvalLeaf(int i1, int i2)
    : i1_m(i1), i2_m(i2)
  { }
  inline EvalLeaf(const Loc<2> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2());
  }
};
template<>
struct EvalLeaf<3>
{
  int i1_m, i2_m, i3_m;
  inline EvalLeaf(int i1, int i2, int i3)
    : i1_m(i1), i2_m(i2), i3_m(i3)
  { }
  inline EvalLeaf(const Loc<3> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2(), val3());
  }
};
template<>
struct EvalLeaf<4>
{
  int i1_m, i2_m, i3_m, i4_m;
  inline EvalLeaf(int i1, int i2, int i3, int i4)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4)
  { }
  inline EvalLeaf(const Loc<4> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
      i4_m(loc[3].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2(), val3(), val4());
  }
};
template<>
struct EvalLeaf<5>
{
  int i1_m, i2_m, i3_m, i4_m, i5_m;
  inline EvalLeaf(int i1, int i2, int i3, int i4, int i5)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5)
  { }
  inline EvalLeaf(const Loc<5> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
      i4_m(loc[3].first()), i5_m(loc[4].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2(), val3(), val4(), val5());
  }
};
template<>
struct EvalLeaf<6>
{
  int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m;
  inline EvalLeaf(int i1, int i2, int i3, int i4, int i5, int i6)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6)
  { }
  inline EvalLeaf(const Loc<6> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
      i4_m(loc[3].first()), i5_m(loc[4].first()), i6_m(loc[5].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
  inline int val6() const { return i6_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2(), val3(), val4(), val5(), val6());
  }
};
template<>
struct EvalLeaf<7>
{
  int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m;
  inline EvalLeaf(int i1, int i2, int i3, int i4, int i5, int i6, int i7)
    : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7)
  { }
  inline EvalLeaf(const Loc<7> &loc)
    : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
      i4_m(loc[3].first()), i5_m(loc[4].first()), i6_m(loc[5].first()),
      i7_m(loc[6].first())
  { }
  inline int val1() const { return i1_m; }
  inline int val2() const { return i2_m; }
  inline int val3() const { return i3_m; }
  inline int val4() const { return i4_m; }
  inline int val5() const { return i5_m; }
  inline int val6() const { return i6_m; }
  inline int val7() const { return i7_m; }
  template<class Engine>
  inline typename Engine::Element_t eval(const Engine &e) const
  {
    return e.read(val1(), val2(), val3(), val4(), val5(), val6(), val7());
  }
};
template<class Domain>
struct ViewFunctorTag
{
  const Domain &domain_m;
  inline ViewFunctorTag(const Domain &domain) : domain_m(domain) { }
};
template<class T, class Domain>
struct LeafFunctor<Scalar<T>, ViewFunctorTag<Domain> >
{
  typedef Scalar<T> Type_t;
  inline static
  Type_t apply(const Scalar<T> &s, const ViewFunctorTag<Domain> &)
  {
    return s;
  }
};
struct DomainFunctorTag { };
template<class T>
struct LeafFunctor<Scalar<T>, DomainFunctorTag>
{
  typedef NullDomain Type_t;
  inline static
  Type_t apply(const Scalar<T> &, const DomainFunctorTag &)
  {
    return NullDomain();
  }
};
template<class T>
struct LeafFunctor<T, DomainFunctorTag>
{
  typedef typename T::Domain_t Type_t;
  inline static
  Type_t apply(const T &leaf, const DomainFunctorTag &)
  {
    return leaf.domain();
  }
};
template<class Domain1, class Domain2, class Op>
struct Combine2<Domain1, Domain2, Op, DomainFunctorTag>
{
  typedef ErrorDomain Type_t;
  inline static
  Type_t combine(const Domain1 &, const Domain2 &, const DomainFunctorTag &)
  {
    return ErrorDomain();
  }
};
template<class Domain, class Op>
struct Combine2<Domain, Domain, Op, DomainFunctorTag>
{
  typedef Domain Type_t;
  inline static
  Type_t combine(const Domain &a, const Domain &, const DomainFunctorTag &)
  {
    return a;
  }
};
template<class Domain, class Op>
struct Combine2<Domain, NullDomain, Op, DomainFunctorTag>
{
  typedef Domain Type_t;
  inline static
  Type_t combine(const Domain &a, const NullDomain &,
   const DomainFunctorTag &)
  {
    return a;
  }
};
template<class Domain,class Op>
struct Combine2<NullDomain, Domain, Op, DomainFunctorTag>
{
  typedef Domain Type_t;
  inline static
  Type_t combine(const NullDomain &, const Domain &b,
   const DomainFunctorTag &)
    {
      return b;
    }
};
template<class Tag>
struct EngineFunctorTag
{
  EngineFunctorTag() : tag_m() { }
  EngineFunctorTag(const Tag &tag) : tag_m(tag) { }
  inline const Tag &tag() const
  {
    return tag_m;
  }
  Tag tag_m;
};
template<class Expr>
struct ExpressionTag
{
  typedef Expr Expression_t;
};
template<int Dim, class T, class Expr>
class Engine<Dim, T, ExpressionTag<Expr> >
{
public:
  typedef Engine<Dim, T, ExpressionTag<Expr> > Engine_t;
  typedef ExpressionTag<Expr> Tag_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  typedef typename ForEach<Expr, DomainFunctorTag, DomainFunctorTag>::Type_t
    Domain_t;
  typedef Expr Expression_t;
  typedef DomainLayout<Dim> Layout_t;
  enum { dimensions = Dim };
  enum { multiPatch = true };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = true };
  inline Engine(const Expr &expr) : expr_m(expr),
    domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) { }
  inline Engine(const Engine_t &engine) : expr_m(engine.expression()),
    domain_m(engine.domain()) { }
  template<int Dim2, class T2, class Expr2, class Initializer>
  inline Engine(const Engine<Dim2, T2, ExpressionTag<Expr2> > &e,
    const Initializer &i)
  : expr_m(e.expression(), i),
    domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
    { }
  template<int Dim2, class T2, class Expr2, class I1, class I2>
  inline Engine(const Engine<Dim2, T2, ExpressionTag<Expr2> > &e,
                const I1 &i1, const I2 &i2)
    : expr_m(e.expression(), i1, i2),
      domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
  { }
  template<class Expr2>
  explicit inline Engine(const Engine<Dim,T,ExpressionTag<Expr2> > &e)
    : expr_m(e.expression()),
      domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
  { }
  inline const Expression_t &expression() const { return expr_m; }
  inline Expression_t &expression() { return expr_m; }
  Engine_t &makeOwnCopy();
  inline Element_t read(int i0) const
    {
      return forEach(expr_m, EvalLeaf<1>(i0), OpCombine());
    }
  inline Element_t read(int i0, int i1) const
    {
      return forEach(expr_m, EvalLeaf<2>(i0, i1), OpCombine());
    }
  inline Element_t read(int i0, int i1, int i2) const
    {
      return forEach(expr_m, EvalLeaf<3>(i0, i1, i2), OpCombine());
    }
  inline Element_t read(int i0, int i1, int i2, int i3) const
    {
      return forEach(expr_m, EvalLeaf<4>(i0, i1, i2, i3),
        OpCombine());
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
    {
      return forEach(expr_m, EvalLeaf<5>(i0, i1, i2, i3, i4),
        OpCombine());
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
    {
      return forEach(expr_m, EvalLeaf<6>(i0, i1, i2, i3, i4, i5),
        OpCombine());
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5,
    int i6) const
    {
      return forEach(expr_m, EvalLeaf<7>(i0, i1, i2, i3, i4, i5, i6),
        OpCombine());
    }
  inline Element_t read(const Loc<Dim> &loc) const
  {
    return forEach(expr_m, EvalLeaf<Dim>(loc), OpCombine());
  }
  inline const Domain_t& domain() const
    {
      return domain_m;
    }
  inline Layout_t layout() const { return Layout_t(domain()); }
  inline int first(int) const
  {
    return 0;
  }
  template<class RequestType>
  inline
  typename DataObjectRequest<RequestType>::Type_t
  dataObjectRequest(const DataObjectRequest<RequestType>& f) const
  {
    typedef DataObjectRequest<RequestType> Tag_t;
    typedef EngineFunctorTag<Tag_t> Functor_t;
    typedef typename Tag_t::Combine_t Combine_t;
    return forEach(expr_m,Functor_t(f),Combine_t());
  }
private:
  Expr expr_m;
  Domain_t domain_m;
};
template<int Dim, class T, class Expr, class Domain>
struct NewEngine<Engine<Dim, T, ExpressionTag<Expr> >, Domain>
{
  typedef ViewFunctorTag<Domain> FTag_t;
  typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
  typedef Engine<Dim, T, ExpressionTag<ExprView_t> > Type_t;
};
template <int Dim, class T, class Expr, int SliceDim>
struct NewEngine<Engine<Dim, T, ExpressionTag<Expr> >,
  SliceInterval<Dim,SliceDim> >
{
  typedef ViewFunctorTag<SliceInterval<Dim,SliceDim> > FTag_t;
  typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
  typedef Engine<SliceDim, T, ExpressionTag<ExprView_t> > Type_t;
};
template <int Dim, class T, class Expr, int SliceDim>
struct NewEngine<Engine<Dim,T,ExpressionTag<Expr> >,
  SliceRange<Dim,SliceDim> >
{
  typedef ViewFunctorTag<SliceRange<Dim,SliceDim> > FTag_t;
  typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
  typedef Engine<SliceDim, T, ExpressionTag<ExprView_t> > Type_t;
};
template<class Node, class Tag>
struct LeafFunctor<Node, EngineFunctorTag<Tag> >
{
};
template<class T, class Tag>
struct LeafFunctor<Scalar<T>, EngineFunctorTag<Tag> >
{
  typedef typename EngineFunctorScalar<T,Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Scalar<T> &scalar, const EngineFunctorTag<Tag> &tag)
  {
    return EngineFunctorScalar<T,Tag>::apply(scalar.value(), tag.tag());
  }
};
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Engine<Dim, T, E>, EngineFunctorTag<Tag> >
{
  typedef Engine<Dim, T, E> Engine_t;
  typedef typename EngineFunctor<Engine_t, Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Engine_t &engine,
        const EngineFunctorTag<Tag> &tag)
  {
    return EngineFunctor<Engine_t, Tag>::apply(engine, tag.tag());
  }
};
template<int Dim, class T, class Expr, class Tag>
struct EngineFunctor<Engine<Dim,T,ExpressionTag<Expr> >,Tag>
{
  typedef EngineFunctorTag<Tag> Functor_t;
  typedef typename Tag::Combine_t Combine_t;
  typedef typename ForEach<Expr,Functor_t,Combine_t>::Type_t Type_t;
  inline static
  Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
        const Tag &tag)
  {
    return forEach(engine.expression(), Functor_t(tag), Combine_t());
  }
};
template<int Dim, class T, class Expr>
struct EngineFunctor<Engine<Dim, T, ExpressionTag<Expr> >, EnginePatch>
{
  typedef typename EnginePatch::Combine_t Combine_t;
  typedef typename ForEach<Expr, EnginePatch, Combine_t>::Type_t NewExpr_t;
  typedef Engine<Dim, T, ExpressionTag<NewExpr_t> > Type_t;
  inline static
  Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
        const EnginePatch &tag)
  {
    return Type_t(forEach(engine.expression(), tag, Combine_t()));
  }
};
template<int Dim, class T, class Expr, class Tag>
struct LeafFunctor<Engine<Dim, T, ExpressionTag<Expr> >, EngineView<Tag> >
{
  typedef EngineView<Tag> Functor_t;
  typedef typename Functor_t::Combine_t Combine_t;
  typedef typename ForEach<Expr, Functor_t, Combine_t>::Type_t NewExpr_t;
  typedef Engine<Dim, T, ExpressionTag<NewExpr_t> > Type_t;
  inline static
  Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
        const EngineView<Tag> &tag)
  {
    return Type_t(forEach(engine.expression(), tag, Combine_t()));
  }
};
template<int Dim, class T, class Expr, class Tag>
struct LeafFunctor<Engine<Dim, T, ExpressionTag<Expr> >, ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
        const ExpressionApply<Tag> &tag)
  {
    return forEach(engine.expression(), tag, NullCombine());
  }
};
template<class Components>
class ComponentWrapper
{
public:
  explicit ComponentWrapper(const Components &c) : c_m(c) { }
  const Components &components() const { return c_m; }
private:
  const Components &c_m;
};
template<class T, class Components>
struct ComponentAccess
{
  typedef T Element_t;
  typedef T &ElementRef_t;
  static inline ElementRef_t indexRef(T &v, const Components &)
  {
    return v;
  }
  static inline Element_t index(const T &v, const Components &)
  {
    return v;
  }
};
template<class Engine>
struct NotifyEngineWrite
{
  NotifyEngineWrite(){}
 ~NotifyEngineWrite(){}
 inline static void
  notify(const Engine &)
  {
    PoomaCTAssert<(!(Engine::multiPatch))>::test();
  }
};
template<class Engine>
inline
void notifyEngineWrite(const Engine &e)
{
  NotifyEngineWrite<Engine>::notify(e);
}
template<class Engine>
inline
void notifyEngineWrite(const Engine &, const WrappedInt<false> &)
{
}
template<class Engine>
inline
void notifyEngineWrite(const Engine &e, const WrappedInt<true> &)
{
  NotifyEngineWrite<Engine>::notify(e);
}
template <int Dim> class DomainLayout;
template<class Eng, class Components>
struct CompFwd { };
template<int Dim, class T, class Eng, class Components>
class Engine<Dim, T, CompFwd<Eng, Components> >
{
public:
  typedef Engine<Dim, T, Eng> This_t;
  typedef This_t Engine_t;
  typedef Eng ElemEngine_t;
  typedef typename Eng::Element_t FwdElement_t;
  typedef ComponentAccess<FwdElement_t, Components> CompAccess_t;
  typedef typename CompAccess_t::Element_t Element_t;
  typedef typename CompAccess_t::ElementRef_t ElementRef_t;
  typedef typename Eng::Domain_t Domain_t;
  typedef CompFwd<Eng, Components> Tag_t;
  typedef typename Eng::Layout_t Layout_t;
  enum { dimensions = Eng::dimensions };
  enum { hasDataObject = Eng::hasDataObject };
  enum { dynamic = false };
  enum { zeroBased = Eng::zeroBased };
  enum { multiPatch = Eng::multiPatch };
  Engine()
    : engine_m(), components_m()
  { }
  Engine(const Eng &e, const Components &l)
    : engine_m(e), components_m(l)
  { }
  Engine(const This_t &e)
    : engine_m(e.elemEngine()), components_m(e.components()) { }
  template<class OtherEng, class Domain>
  Engine(const Engine< Dim, T, CompFwd<OtherEng, Components> > &e,
  const Domain &domain)
    : engine_m(NewEngineEngine<OtherEng,Domain>::apply(e.elemEngine(),domain),
        NewEngineDomain<OtherEng,Domain>::apply(e.elemEngine(),domain)),
      components_m(e.components()) { }
  ~Engine() { }
  inline ElementRef_t operator()(const Loc<dimensions> &eloc) const
  {
    return CompAccess_t::indexRef(elemEngine()(eloc), components());
  }
  inline ElementRef_t operator()(int i1) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1), components());
  }
  inline ElementRef_t operator()(int i1, int i2) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2), components());
  }
  inline ElementRef_t operator()(int i1, int i2, int i3) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2, i3),
      components());
  }
  inline ElementRef_t operator()(int i1, int i2, int i3, int i4) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4),
      components());
  }
  inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5),
      components());
  }
  inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5,
     int i6) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5, i6),
      components());
  }
  inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5,
     int i6, int i7) const
  {
    return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5, i6, i7),
      components());
  }
  inline Element_t read(const Loc<dimensions> &eloc) const
  {
    return CompAccess_t::index(elemEngine().read(eloc), components());
  }
  inline Element_t read(int i1) const
  {
    return CompAccess_t::index(elemEngine().read(i1), components());
  }
  inline Element_t read(int i1, int i2) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2), components());
  }
  inline Element_t read(int i1, int i2, int i3) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2, i3),
          components());
  }
  inline Element_t read(int i1, int i2, int i3, int i4) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4),
          components());
  }
  inline Element_t read(int i1, int i2, int i3, int i4, int i5) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5),
          components());
  }
  inline Element_t read(int i1, int i2, int i3, int i4, int i5,
   int i6) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5, i6),
          components());
  }
  inline Element_t read(int i1, int i2, int i3, int i4, int i5,
   int i6, int i7) const
  {
    return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5, i6, i7),
          components());
  }
  inline const Layout_t& layout() const
  {
    return elemEngine().layout();
  }
  inline Layout_t& layout()
  {
    return elemEngine().layout();
  }
  inline const Domain_t& domain() const { return elemEngine().domain(); }
  inline int first(int i) const
  {
    return elemEngine().first(i);
  }
  This_t &makeOwnCopy()
  {
    elemEngine().makeOwnCopy();
    return *this;
  }
  Eng &elemEngine() { return engine_m; }
  const Eng &elemEngine() const { return engine_m; }
  const Components &components() const { return components_m; }
private:
  Eng engine_m;
  Components components_m;
};
template <int Dim, class T, class Eng, class Components, class Domain>
struct NewEngine<Engine<Dim, T, CompFwd<Eng, Components> >, Domain>
{
  typedef typename NewEngine<Eng, Domain>::Type_t NewEngine_t;
  typedef Engine<NewEngine_t::dimensions, T, CompFwd<NewEngine_t, Components> > Type_t;
};
template<int Dim, class T, class Eng, class Components, class EFTag>
struct EngineFunctor<Engine<Dim, T, CompFwd<Eng, Components> >, EFTag>
{
  typedef typename EngineFunctor<Eng, EFTag>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, CompFwd<Eng, Components> > &engine,
 const EFTag &tag)
  {
    return engineFunctor(engine.elemEngine(), tag);
  }
};
template <int D, class T, class E, class Comp, class Tag>
struct LeafFunctor<Engine<D, T, CompFwd<E, Comp> >, EngineView<Tag> >
{
  typedef LeafFunctor<E, EngineView<Tag> > LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t NewViewed_t;
  typedef Engine<D, T, CompFwd<NewViewed_t, Comp> > Type_t;
  static
  Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
        const EngineView<Tag> &tag)
  {
    return Type_t(LeafFunctor_t::apply(engine.elemEngine(), tag),
    engine.components());
  }
};
template <int D, class T, class E, class Comp, class Tag>
struct LeafFunctor<Engine<D, T, CompFwd<E, Comp> >, ExpressionApply<Tag> >
{
  typedef LeafFunctor<E, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  static
  Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
        const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(engine.elemEngine(), tag);
  }
};
template<int Dim, class T, class Eng, class Components>
struct NotifyEngineWrite<Engine<Dim,T,CompFwd<Eng,Components> > >
{
  inline static void
  notify(const Engine<Dim,T,CompFwd<Eng,Components> > &engine)
  {
    typedef typename Engine<Dim, T,
      CompFwd<Eng, Components> >::ElemEngine_t Engine_t;
    NotifyEngineWrite<Engine_t>::notify(engine.elemEngine());
  }
};
template <int D, class T, class E, class Comp>
struct EngineFunctor<Engine<D, T, CompFwd<E, Comp> >, EnginePatch>
{
  typedef typename EngineFunctor<E, EnginePatch>::Type_t NewViewed_t;
  typedef Engine<D, T, CompFwd<NewViewed_t, Comp> > Type_t;
  static
  Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
        const EnginePatch &tag)
  {
    return Type_t(engineFunctor(engine.elemEngine(), tag),
    engine.components());
  }
};
struct WriteRequest {};
struct ReadRequest {};
struct WriteRelease {};
struct ReadRelease {};
struct CountBlocks {};
template<>
class DataObjectRequest<WriteRequest>
{
public:
  typedef int Type_t;
  typedef NullCombine Combine_t;
  DataObjectRequest(Pooma::Iterate_t& iterate)
    : iterate_m(iterate),
      lhs1_m(NULL), lhs2_m(NULL)
  { }
  inline Type_t operator()(Pooma::DataObject_t* obj) const
  {
    if ((obj != lhs1_m) && (obj != lhs2_m))
    {
      if (lhs1_m == NULL)
      {
 lhs1_m = obj;
      }
      else
      {
 if (lhs2_m == NULL)
 {
   lhs2_m = obj;
 }
 else
 {
   ;
 }
      }
      obj->request(iterate_m,Pooma::SmartsTag_t::Write);
    }
    return 0;
  }
  inline Type_t defaultValue() const
  {
    return 0;
  }
  Pooma::DataObject_t* dataObject1() const { return lhs1_m; }
  Pooma::DataObject_t* dataObject2() const { return lhs2_m; }
  Pooma::Iterate_t& iterate() const { return iterate_m; }
private:
  // LLVM: Remove 'mutable' keyword from iterate_m.
  Pooma::Iterate_t& iterate_m;
  mutable Pooma::DataObject_t* lhs1_m;
  mutable Pooma::DataObject_t* lhs2_m;
};
template<>
class DataObjectRequest<ReadRequest>
{
public:
  typedef int Type_t;
  typedef NullCombine Combine_t;
  DataObjectRequest(const DataObjectRequest<WriteRequest>& write)
    : iterate_m(write.iterate()),
      lhs1_m(write.dataObject1()),
      lhs2_m(write.dataObject2())
  { }
  DataObjectRequest(Pooma::Iterate_t& iterate)
    : iterate_m(iterate),
      lhs1_m(NULL), lhs2_m(NULL)
  { }
  inline Type_t operator()(Pooma::DataObject_t* obj) const
  {
    if ((lhs1_m != obj) && (lhs2_m != obj))
    {
      obj->request(iterate_m, Pooma::SmartsTag_t::Read);
    }
    return 0;
  }
  inline Type_t defaultValue() const
  {
    return 0;
  }
private:
  Pooma::Iterate_t& iterate_m;
  Pooma::DataObject_t* lhs1_m;
  Pooma::DataObject_t* lhs2_m;
};
template<>
class DataObjectRequest<WriteRelease>
{
public:
  typedef int Type_t;
  typedef NullCombine Combine_t;
  DataObjectRequest()
    : lhs1_m(NULL), lhs2_m(NULL)
  { }
  inline Type_t operator()(Pooma::DataObject_t* obj) const
  {
    if ((obj != lhs1_m) && (obj != lhs2_m))
    {
      if (lhs1_m == NULL)
      {
 lhs1_m = obj;
      }
      else
      {
 if (lhs2_m == NULL)
 {
   lhs2_m = obj;
 }
 else
 {
   ;
 }
      }
      obj->release(Pooma::SmartsTag_t::Write);
    }
    return 0;
  }
  inline Type_t defaultValue() const
  {
    return 0;
  }
  Pooma::DataObject_t* dataObject1() const { return lhs1_m; }
  Pooma::DataObject_t* dataObject2() const { return lhs2_m; }
private:
  mutable Pooma::DataObject_t* lhs1_m;
  mutable Pooma::DataObject_t* lhs2_m;
};
template<>
class DataObjectRequest<ReadRelease>
{
public:
  typedef int Type_t;
  typedef NullCombine Combine_t;
  DataObjectRequest()
    : lhs1_m(NULL), lhs2_m(NULL)
  { }
  DataObjectRequest(const DataObjectRequest<WriteRelease>& write)
    : lhs1_m(write.dataObject1()), lhs2_m(write.dataObject2())
  { }
  inline Type_t operator()(Pooma::DataObject_t* obj) const
  {
    if ((lhs1_m != obj) && (lhs2_m != obj))
    {
      obj->release(Pooma::SmartsTag_t::Read);
    }
    return 0;
  }
  inline Type_t defaultValue() const
  {
    return 0;
  }
private:
  Pooma::DataObject_t* lhs1_m;
  Pooma::DataObject_t* lhs2_m;
};
template<>
class DataObjectRequest<CountBlocks>
{
public:
  typedef int Type_t;
  typedef SumCombine Combine_t;
  DataObjectRequest() { }
  inline Type_t operator()(Pooma::DataObject_t*) const
  {
    return 1;
  }
  inline Type_t defaultValue() const
  {
    return 0;
  }
};
template<class Eng, class Tag>
struct DefaultExpressionApply<Eng, DataObjectRequest<Tag> >
{
  enum { hasDataObject = Eng::hasDataObject };
  inline static
  int apply(const Eng &e,
     const ExpressionApply<DataObjectRequest<Tag> > &request)
  {
    DataObjectApply<hasDataObject>::apply(e, request.tag());
    return 0;
  }
};
template<int Dim> class DomainLayout;
template<class A1,class A2>
struct IndirectionTag
{ };
template<int Dim,class T,class A1,class A2>
class Engine<Dim,T,IndirectionTag<A1,A2> >
{
public:
  typedef IndirectionTag<A1,A2> Tag_t;
  typedef Engine<Dim,T,Tag_t> Engine_t;
  typedef typename A1::Element_t Element_t;
  typedef typename A1::ElementRef_t ElementRef_t;
  typedef typename A2::Domain_t Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef typename A1::Engine_t Engine1_t;
  typedef typename A2::Engine_t Engine2_t;
  enum { dimensions = Dim };
  enum { hasDataObject = Engine1_t::hasDataObject ||
  Engine2_t::hasDataObject };
  enum { multiPatch = Engine1_t::multiPatch ||
  Engine2_t::multiPatch };
  enum { dynamic = false };
  enum { zeroBased = Engine2_t::zeroBased };
  inline
  Engine(const A1 &array1,const A2 &array2)
    : array1_m(array1),array2_m(array2)
  {
    PoomaCTAssert<(A2::dimensions == Dim)>::test();
  }
  inline
  Engine(const Engine_t &engine)
    : array1_m(engine.array1()),array2_m(engine.array2())
  { }
  template<int OtherDim,class OtherA2, class Domain>
  inline
  Engine(const Engine<OtherDim,T,IndirectionTag<A1,OtherA2> > &e,
  const Domain &d)
    : array1_m(e.array1()),array2_m(e.array2(),d)
  {
    PoomaCTAssert<(A2::dimensions == Dim)>::test();
  }
  inline const A1 &array1() const { return array1_m; }
  inline A1 &array1() { return array1_m; }
  inline const A2 &array2() const { return array2_m; }
  inline A2 &array2() { return array2_m; }
  inline Element_t read(int i0) const
  {
    return array1_m.read(array2_m.read(i0));
  }
  inline Element_t read(int i0, int i1) const
  {
    return array1_m.read(array2_m.read(i0,i1));
  }
  inline Element_t read(int i0, int i1,int i2) const
  {
    return array1_m.read(array2_m.read(i0,i1,i2));
  }
  inline Element_t read(int i0, int i1,int i2,int i3) const
  {
    return array1_m.read(array2_m.read(i0,i1,i2,i3));
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
  {
    return array1_m.read(array2_m.read(i0,i1,i2,i3,i4));
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
  {
    return array1_m.read(array2_m.read(i0,i1,i2,i3,i4,i5));
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5,
   int i6) const
  {
    return array1_m.read(array2_m.read(i0,i1,i2,i3,i4,i5,i6));
  }
  template<class Domain>
  inline Element_t read(const Domain &loc) const
  {
    return array1_m.read(array2_m.read(loc));
  }
  inline ElementRef_t operator()(int i0) const
  {
    return array1_m(array2_m.read(i0));
  }
  inline ElementRef_t operator()(int i0, int i1) const
  {
    return array1_m(array2_m.read(i0,i1));
  }
  inline ElementRef_t operator()(int i0, int i1,int i2) const
  {
    return array1_m(array2_m.read(i0,i1,i2));
  }
  inline ElementRef_t operator()(int i0, int i1,int i2,int i3) const
  {
    return array1_m(array2_m.read(i0,i1,i2,i3));
  }
  inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4) const
  {
    return array1_m(array2_m.read(i0,i1,i2,i3,i4));
  }
  inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4,
     int i5) const
  {
    return array1_m(array2_m.read(i0,i1,i2,i3,i4,i5));
  }
  inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4,
     int i5, int i6) const
  {
    return array1_m(array2_m.read(i0,i1,i2,i3,i4,i5,i6));
  }
  template<class Domain>
  inline ElementRef_t operator()(const Domain &loc) const
  {
    return array1_m(array2_m.read(loc));
  }
  inline const Domain_t& domain() const
  {
    return array2_m.domain();
  }
  inline int first(int i) const
  {
    return array2_m.first(i);
  }
private:
  A1 array1_m;
  A2 array2_m;
};
template<int Dim,class T,class A1,class A2,class Domain>
struct NewEngine<Engine<Dim,T,IndirectionTag<A1,A2> >,Domain>
{
  typedef typename View1<A2,Domain>::Type_t NewA2_t;
  enum { newDim = NewA2_t::dimensions };
  typedef Engine<newDim,T,IndirectionTag<A1,NewA2_t> > Type_t;
};
template<int Dim, class T, class A1, class A2, class RequestType>
struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
  DataObjectRequest<RequestType> >
{
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  typedef typename DataObjectRequest<RequestType>::Combine_t Combine_t;
  static Type_t
  apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
 const DataObjectRequest<RequestType> &tag)
  {
    return Combine2<Type_t,Type_t,OpAdd,
      Combine_t>::combine(
     engineFunctor(engine.array1().engine(), tag),
     engineFunctor(engine.array2().engine(), tag),
     Combine_t()
     );
  }
};
template<int Dim, class T, class A1, class A2>
struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
  DataObjectRequest<WriteRequest> >
{
  typedef typename DataObjectRequest<WriteRequest>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
 const DataObjectRequest<WriteRequest> &tag)
  {
    engineFunctor(engine.array1().engine(), tag);
    return engineFunctor(engine.array2().engine(),
    DataObjectRequest<ReadRequest>(tag));
  }
};
template<int Dim, class T, class A1, class A2>
struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
  DataObjectRequest<WriteRelease> >
{
  typedef typename DataObjectRequest<WriteRelease>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
 const DataObjectRequest<WriteRelease> &tag)
  {
    engineFunctor(engine.array1().engine(), tag);
    return engineFunctor(engine.array2().engine(),
    DataObjectRequest<ReadRelease>(tag));
  }
};
struct Brick;
struct BrickView;
struct CompressibleBrick;
struct CompressibleBrickView;
template<class Eng, class Components> struct CompFwd;
template<class A1,class A2> struct IndirectionTag;
struct ConstantFunction;
template<class Expr> struct ExpressionTag;
template<class Stencil, class Expression> struct StencilEngine;
struct Compressible
{
  typedef AndCombine Combine_t;
};
struct Compressed
{
  typedef AndCombine Combine_t;
};
struct CompressedRead
{
  typedef OpCombine Combine_t;
};
struct CompressedReadWrite
{
};
struct CompressedBrickIsWholeView
{
};
struct UnCompressedViewEngine
{
};
template<int A, int B, class Op>
struct Combine2<WrappedInt<A>, WrappedInt<B>, Op, AndCombine>
{
  enum { val = A && B };
  typedef WrappedInt<val> Type_t;
  inline static
  Type_t combine(WrappedInt<A> , WrappedInt<B>, AndCombine)
  {
    return Type_t();
  }
};
template<class T>
struct EngineFunctorScalar<T, Compressible >
{
  typedef WrappedInt<true> Type_t;
  static Type_t apply(const T &, const Compressible &)
  {
    return Type_t();
  }
};
template<class T>
struct EngineFunctorScalar<T, Compressed >
{
  typedef bool Type_t;
  static Type_t apply(const T &, const Compressed &)
  {
    return true;
  }
};
template<class T>
struct EngineFunctorScalar<T, CompressedRead >
{
  typedef T Type_t;
  static inline
  Type_t apply(const T& s, const CompressedRead &)
  {
    return s;
  }
};
template<class Engine>
struct EngineFunctorDefault<Engine,Compressible>
{
  typedef WrappedInt<false> Type_t;
};
template<class Engine>
struct EngineFunctorDefault<Engine,Compressed>
{
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine &, const Compressed &)
  {
    return false;
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,Compressible>
{
  typedef WrappedInt<true> Type_t;
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,Compressed>
{
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine_t &e, const Compressed &)
  {
    return e.compressed();
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,CompressedRead>
{
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef T Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedRead &)
  {
    return e.compressedRead();
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,CompressedReadWrite>
{
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef T &Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedReadWrite &)
  {
    return e.compressedReadWrite();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,
  CompressedBrickIsWholeView>
{
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef bool Type_t;
  static inline
  bool apply(const Engine_t &e, const CompressedBrickIsWholeView &)
  {
    return e.compressedBrickIsWholeView();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,UnCompressedViewEngine>
{
  typedef Engine<Dim,T,CompressibleBrick> Engine_t;
  typedef Engine<Dim,T,BrickView> Type_t;
  static inline
  Type_t apply(const Engine_t &e, const UnCompressedViewEngine &)
  {
    return Type_t(e);
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView>,Compressible>
{
  typedef WrappedInt<true> Type_t;
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,Compressed>
{
  typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine_t &e, const Compressed &)
  {
    return e.compressed();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,CompressedRead>
{
  typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
  typedef T Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedRead &)
  {
    return e.compressedRead();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
  CompressedReadWrite>
{
  typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
  typedef T &Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedReadWrite &)
  {
    return e.compressedReadWrite();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
  CompressedBrickIsWholeView>
{
  typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
  typedef bool Type_t;
  static inline
  bool apply(const Engine_t &e, const CompressedBrickIsWholeView &)
  {
    return e.compressedBrickIsWholeView();
  }
};
template<int Dim, class T>
struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
  UnCompressedViewEngine>
{
  typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
  typedef Engine<Dim,T,BrickView> Type_t;
  static inline
  Type_t apply(const Engine_t &e, const UnCompressedViewEngine &)
  {
    return Type_t(e);
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,ConstantFunction>,Compressible>
{
  typedef WrappedInt<true> Type_t;
  static inline
  Type_t apply(const Engine<Dim,T,ConstantFunction> &, const Compressible &)
  {
    return WrappedInt<true>();
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,ConstantFunction>,Compressed>
{
  typedef bool Type_t;
  static inline
  Type_t apply(const Engine<Dim,T,ConstantFunction> &, const Compressed &)
  {
    return true;
  }
};
template<int Dim,class T>
struct EngineFunctor<Engine<Dim,T,ConstantFunction>,CompressedRead>
{
  typedef T Type_t;
  static inline
  Type_t apply(const Engine<Dim,T,ConstantFunction> &e,
        const CompressedRead &)
  {
    return e.constant();
  }
};
template<int Dim, class T, class Eng, class Components>
struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,Compressible>
{
  typedef typename EngineFunctor<Eng,Compressible>::Type_t Comp_t;
  enum { compressible = Comp_t::val };
  typedef WrappedInt<compressible> Type_t;
};
template<int Dim, class T, class Eng, class Components>
struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,CompressedRead>
{
  typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
  typedef typename Engine_t::CompAccess_t CompAccess_t;
  typedef typename CompAccess_t::Element_t Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedRead &tag)
  {
    return CompAccess_t::index(engineFunctor(e.elemEngine(),tag),
          e.components());
  }
};
template<int Dim, class T, class Eng, class Components>
struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,CompressedReadWrite>
{
  typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
  typedef typename Engine_t::CompAccess_t CompAccess_t;
  typedef typename CompAccess_t::ElementRef_t Type_t;
  static inline
  Type_t apply(const Engine_t &e, const CompressedReadWrite &tag)
  {
    return CompAccess_t::indexRef(engineFunctor(e.elemEngine(),tag),
      e.components());
  }
};
template<int Dim, class T, class Eng, class Components>
struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,
  UnCompressedViewEngine>
{
  typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
  typedef typename EngineFunctor<Eng,
    UnCompressedViewEngine>::Type_t CompEngine_t;
  typedef Engine<Dim,T,CompFwd<CompEngine_t, Components> > Type_t;
  static inline
  Type_t apply(const Engine_t &e,const UnCompressedViewEngine &tag)
  {
    return Type_t(engineFunctor(e.elemEngine(), tag), e.components());
  }
};
template<class Expr> struct CreateLeaf;
struct ErrorKernelTag
{
  ErrorKernelTag(){}
  ~ErrorKernelTag(){}
};
struct InlineKernelTag
{
  InlineKernelTag(){}
  ~InlineKernelTag(){}
};
struct CompressibleKernelTag
{
  CompressibleKernelTag(){}
  ~CompressibleKernelTag(){}
};
struct CompressibleViewKernelTag
{
  CompressibleViewKernelTag(){}
  ~CompressibleViewKernelTag(){}
};
template<bool lhsComp,bool rhsComp>
struct CompressibleKernel
{
  CompressibleKernel(){}
  ~CompressibleKernel(){}
};
template<>
struct CompressibleKernel<false,false>
{
  CompressibleKernel(){}
  ~CompressibleKernel(){}
  typedef InlineKernelTag Kernel_t;
};
template<>
struct CompressibleKernel<false,true>
{
  CompressibleKernel(){}
  ~CompressibleKernel(){}
  typedef InlineKernelTag Kernel_t;
};
template<>
struct CompressibleKernel<true,false>
{
  CompressibleKernel(){}
  ~CompressibleKernel(){}
  typedef CompressibleViewKernelTag Kernel_t;
};
template<>
struct CompressibleKernel<true,true>
{
  CompressibleKernel(){}
  ~CompressibleKernel(){}
  typedef CompressibleKernelTag Kernel_t;
};
template<class Expr>
struct KernelTag1
{
  KernelTag1(){}
 ~KernelTag1(){}
  typedef typename Expr::Engine_t ExprEngine_t;
  typedef typename EngineFunctor<ExprEngine_t, Compressible>::Type_t Expr_t;
  enum { exprComp = Expr_t::val };
  typedef typename CompressibleKernel<exprComp,exprComp>::Kernel_t Kernel_t;
};
template<class LHS,class RHS>
struct KernelTag
{
  KernelTag(){}
 ~KernelTag(){}
  typedef typename LHS::Engine_t LHSEngine_t;
  typedef typename RHS::Engine_t RHSEngine_t;
  typedef typename EngineFunctor<LHSEngine_t,Compressible>::Type_t LHST_t;
  typedef typename EngineFunctor<RHSEngine_t,Compressible>::Type_t RHST_t;
  enum { lhsComp = LHST_t::val };
  enum { rhsComp = RHST_t::val };
  typedef typename CompressibleKernel<lhsComp,rhsComp>::Kernel_t Kernel_t;
};
template<class KernelTag>
struct KernelEvaluator;
template<>
struct KernelEvaluator<InlineKernelTag>
{
  template<class LHS,class Op,class RHS,class Domain>
  static /*__attribute__((leafify))*/
  void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain)
  {
    PoomaCTAssert<(Domain::unitStride)>::test();
    for (int i=0; i<Domain::dimensions; ++i)
      ;
    evaluate(lhs,op,rhs,domain,
      WrappedInt<Domain::dimensions>());
    ;
  }
  template<class LHS,class Op,class RHS>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs)
  {
    evaluate(lhs,op,rhs,lhs.domain());
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<1>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
;
#pragma omp parallel for if (e0 > 512)
    for (int i0=0; i0<e0; ++i0)
      op(localLHS(i0),localRHS.read(i0));
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<2>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
#pragma omp parallel for
    for (int i1=0; i1<e1; ++i1) {
;
      for (int i0=0; i0<e0; ++i0)
 op(localLHS(i0,i1),localRHS.read(i0,i1));
    }
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<3>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
#pragma omp parallel for
    for (int i2=0; i2<e2; ++i2)
      for (int i1=0; i1<e1; ++i1) {
;
 for (int i0=0; i0<e0; ++i0)
   op(localLHS(i0,i1,i2),localRHS.read(i0,i1,i2));
      }
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<4>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
#pragma omp parallel for
    for (int i3=0; i3<e3; ++i3)
      for (int i2=0; i2<e2; ++i2)
 for (int i1=0; i1<e1; ++i1) {
;
   for (int i0=0; i0<e0; ++i0)
     op(localLHS(i0,i1,i2,i3),localRHS.read(i0,i1,i2,i3));
 }
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<5>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
#pragma omp parallel for
    for (int i4=0; i4<e4; ++i4)
      for (int i3=0; i3<e3; ++i3)
 for (int i2=0; i2<e2; ++i2)
   for (int i1=0; i1<e1; ++i1) {
;
     for (int i0=0; i0<e0; ++i0)
       op(localLHS(i0,i1,i2,i3,i4),localRHS.read(i0,i1,i2,i3,i4));
   }
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<6>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
    int e5 = domain[5].length();
#pragma omp parallel for
    for (int i5=0; i5<e5; ++i5)
      for (int i4=0; i4<e4; ++i4)
 for (int i3=0; i3<e3; ++i3)
   for (int i2=0; i2<e2; ++i2)
     for (int i1=0; i1<e1; ++i1) {
;
       for (int i0=0; i0<e0; ++i0)
  op(localLHS(i0,i1,i2,i3,i4,i5),
     localRHS.read(i0,i1,i2,i3,i4,i5));
     }
  }
  template<class LHS,class Op,class RHS,class Domain>
  inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
         const Domain& domain,WrappedInt<7>)
  {
    LHS localLHS(lhs);
    RHS localRHS(rhs);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
    int e5 = domain[5].length();
    int e6 = domain[6].length();
#pragma omp parallel for
    for (int i6=0; i6<e6; ++i6)
      for (int i5=0; i5<e5; ++i5)
 for (int i4=0; i4<e4; ++i4)
   for (int i3=0; i3<e3; ++i3)
     for (int i2=0; i2<e2; ++i2)
       for (int i1=0; i1<e1; ++i1) {
;
  for (int i0=0; i0<e0; ++i0)
    op(localLHS(i0,i1,i2,i3,i4,i5,i6),
       localRHS.read(i0,i1,i2,i3,i4,i5,i6));
       }
  }
private:
};
template<>
struct KernelEvaluator<CompressibleViewKernelTag>
{
  template<class LHS, class Op, class RHS>
  static void evaluate(const LHS &lhs, const Op &op, const RHS &rhs)
  {
    KernelEvaluator<InlineKernelTag>().
      evaluate(engineFunctor(lhs, UnCompressedViewEngine()),
        op, rhs);
    ;
  }
};
template<>
struct KernelEvaluator<CompressibleKernelTag>
{
  template<class LHS, class Op, class RHS>
  static void evaluate(const LHS &lhs, const Op &op, const RHS &rhs)
  {
    typedef typename LHS::Element_t LHST_t;
    typedef typename RHS::Element_t RHST_t;
    if (engineFunctor(lhs, Compressed()) &&
 engineFunctor(rhs, Compressed()))
      {
        LHST_t &l = engineFunctor(lhs, CompressedReadWrite());
        LHST_t test = l;
        RHST_t r = engineFunctor(rhs, CompressedRead());
        op(test, r);
        if (test != l)
          {
     if (engineFunctor(lhs, CompressedBrickIsWholeView()))
       {
         l = test;
         ;
       }
     else
       {
         KernelEvaluator<CompressibleViewKernelTag>::
                  evaluate(lhs, op, rhs);
       }
          }
        else
          {
            ;
          }
      }
    else
      {
        KernelEvaluator<CompressibleViewKernelTag>::evaluate(lhs, op, rhs);
      }
  }
};
struct Brick;
struct BrickView;
struct BrickViewU;
struct CompressibleBrick;
struct CompressibleBrickView;
struct Dynamic;
struct DynamicView;
template<class LayoutTag, class PatchTag>
struct MultiPatch;
template<class LayoutTag, class PatchTag, int Dim2>
struct MultiPatchView;
template<class Functor>
struct IndexFunction;
template<int Dim2, class Functor>
struct IndexFunctionView;
template<class Eng, class Components>
struct CompFwd;
template<class A1,class A2>
struct IndirectionTag;
struct ConstantFunction;
template<class Expr>
struct ExpressionTag;
template<class Tag>
struct Remote;
struct DistributedTag;
struct ReplicatedTag;
struct ScalarEngineTag
{
  ScalarEngineTag() {}
  ~ScalarEngineTag() {}
};
struct MainEvaluatorTag
{
  MainEvaluatorTag() {}
  ~MainEvaluatorTag() {}
};
struct SinglePatchEvaluatorTag
{
  SinglePatchEvaluatorTag() {}
  ~SinglePatchEvaluatorTag() {}
};
struct MultiPatchEvaluatorTag
{
  MultiPatchEvaluatorTag() {}
  ~MultiPatchEvaluatorTag() {}
};
struct RemoteSinglePatchEvaluatorTag
{
  RemoteSinglePatchEvaluatorTag() {}
  ~RemoteSinglePatchEvaluatorTag() {}
};
struct RemoteMultiPatchEvaluatorTag
{
  RemoteMultiPatchEvaluatorTag() {}
  ~RemoteMultiPatchEvaluatorTag() {}
};
struct EvaluatorTypeTag
{
  EvaluatorTypeTag() {}
  ~EvaluatorTypeTag() {}
};
struct EvaluatorCombineTag
{
  EvaluatorCombineTag() {}
  ~EvaluatorCombineTag() {}
};
template<class EngineTag>
struct EvaluatorEngineTraits
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
};
template<>
struct EvaluatorEngineTraits<ScalarEngineTag>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<ConstantFunction>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<class Functor>
struct EvaluatorEngineTraits<IndexFunction<Functor> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<int Dim2, class Functor>
struct EvaluatorEngineTraits<IndexFunctionView<Dim2, Functor> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<Brick>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<BrickView>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<BrickViewU>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<CompressibleBrick>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<CompressibleBrickView>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<Dynamic>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorEngineTraits<DynamicView>
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<class A1,class A2>
struct EvaluatorEngineTraits<IndirectionTag<A1,A2> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<class Tag>
struct EvaluatorEngineTraits<Remote<Tag> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
};
template<class LayoutTag, class PatchTag>
struct EvaluatorEngineTraits<MultiPatch<LayoutTag, PatchTag> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef MultiPatchEvaluatorTag Evaluator_t;
};
template<class LayoutTag, class PatchTag, int Dim2>
struct EvaluatorEngineTraits<MultiPatchView<LayoutTag, PatchTag, Dim2> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef MultiPatchEvaluatorTag Evaluator_t;
};
template<class LayoutTag, class Tag>
struct EvaluatorEngineTraits<MultiPatch<LayoutTag, Remote<Tag> > >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
};
template<class LayoutTag, class Tag, int Dim2>
struct EvaluatorEngineTraits<MultiPatchView<LayoutTag, Remote<Tag>, Dim2> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
};
template<class Eng, class Components>
struct EvaluatorEngineTraits<CompFwd<Eng, Components> >
{
  EvaluatorEngineTraits() {}
  ~EvaluatorEngineTraits() {}
  typedef EvaluatorEngineTraits<typename Eng::Tag_t> ET;
  typedef typename ET::Evaluator_t Evaluator_t;
};
template<class Expr>
struct EvaluatorEngineTraits<ExpressionTag<Expr> >
{
 EvaluatorEngineTraits() {}
 ~EvaluatorEngineTraits() {}
 typedef typename ForEach<Expr, EvaluatorTypeTag,
   EvaluatorCombineTag>::Type_t Evaluator_t;
};
template<class ETag>
struct DistributionTraits
{
  enum { remote = false };
  typedef ReplicatedTag LayoutTag_t;
};
template<class ETag>
struct DistributionTraits<Remote<ETag> >
{
  enum { remote = true };
  typedef DistributedTag LayoutTag_t;
};
template<class Eval1, class Eval2>
struct EvaluatorCombine
{
 EvaluatorCombine() {}
 ~EvaluatorCombine() {}
 typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<SinglePatchEvaluatorTag,
                        MultiPatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef MultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<MultiPatchEvaluatorTag,
                        SinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef MultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
                        MultiPatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<MultiPatchEvaluatorTag,
                        RemoteSinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
                        SinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<SinglePatchEvaluatorTag,
                        RemoteSinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<MultiPatchEvaluatorTag,
                        MultiPatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef MultiPatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
                        RemoteSinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
};
template<>
struct EvaluatorCombine<SinglePatchEvaluatorTag,
                        SinglePatchEvaluatorTag>
{
  EvaluatorCombine() {}
  ~EvaluatorCombine() {}
  typedef SinglePatchEvaluatorTag Evaluator_t;
};
template<class T>
struct LeafFunctor<Scalar<T>, EvaluatorTypeTag>
{
 LeafFunctor() {}
 ~LeafFunctor() {}
 typedef typename EvaluatorEngineTraits<ScalarEngineTag>::Evaluator_t Type_t;
};
template<class A>
struct LeafFunctor<A, EvaluatorTypeTag>
{
  LeafFunctor() {}
  ~LeafFunctor() {}
  typedef typename
    EvaluatorEngineTraits<typename A::Engine_t::Tag_t>::Evaluator_t Type_t;
};
template<class Eval1,class Eval2,class Op>
struct Combine2<Eval1, Eval2, Op, EvaluatorCombineTag>
{
  Combine2() {}
  ~Combine2() {}
  typedef typename EvaluatorCombine<Eval1, Eval2>::Evaluator_t Type_t;
};
template<class Expr>
struct EvaluatorTag1
{
  EvaluatorTag1() {}
  ~EvaluatorTag1() {}
  typedef typename LeafFunctor<Expr, EvaluatorTypeTag>::Type_t Evaluator_t;
};
template<class LHS, class RHS>
struct EvaluatorTag
{
  EvaluatorTag() {}
  ~EvaluatorTag() {}
  typedef typename LeafFunctor<LHS, EvaluatorTypeTag>::Type_t LHSEval_t;
  typedef typename LeafFunctor<RHS, EvaluatorTypeTag>::Type_t RHSEval_t;
  typedef typename EvaluatorCombine<LHSEval_t, RHSEval_t>::Evaluator_t
    Evaluator_t;
};
template<class LHS,class Op,class RHS,class EvalTag>
class ExpressionKernel : public Pooma::Iterate_t
{
public:
  typedef ExpressionKernel<LHS,Op,RHS,EvalTag> This_t;
  ExpressionKernel(const LHS&,const Op&,const RHS&);
  virtual ~ExpressionKernel();
  virtual void /*__attribute__((leafify))*/ run();
private:
  LHS lhs_m;
  Op op_m;
  RHS rhs_m;
};
template<class LHS,class Op,class RHS,class EvalTag>
ExpressionKernel<LHS,Op,RHS,EvalTag>::
ExpressionKernel(const LHS& lhs,const Op& op,const RHS& rhs)
  : Pooma::Iterate_t(Pooma::scheduler()),
    lhs_m(lhs), op_m(op), rhs_m(rhs)
{
  hintAffinity(engineFunctor(lhs, DataObjectRequest<BlockAffinity>()));
  DataObjectRequest<WriteRequest> writeReq(*this);
  engineFunctor(lhs_m, writeReq);
  DataObjectRequest<ReadRequest> readReq(writeReq);
  engineFunctor(rhs_m, readReq);
}
template<class LHS,class Op,class RHS,class EvalTag>
ExpressionKernel<LHS,Op,RHS,EvalTag>::~ExpressionKernel()
{
  DataObjectRequest<WriteRelease> writeReq;
  engineFunctor(lhs_m, writeReq);
  DataObjectRequest<ReadRelease> readReq(writeReq);
  engineFunctor(rhs_m, readReq);
}
template<class LHS,class Op,class RHS,class EvalTag>
void
ExpressionKernel<LHS,Op,RHS,EvalTag>::run()
{
  KernelEvaluator<EvalTag>::evaluate(lhs_m,op_m,rhs_m);
}
template<class LHS,class Op,class RHS,class EvalTag>
inline static
ExpressionKernel<LHS,Op,RHS,EvalTag>*
generateKernel(const LHS& lhs, const Op& op, const RHS& rhs, const EvalTag&)
{
  return new ExpressionKernel<LHS,Op,RHS,EvalTag>(lhs, op, rhs);
}
template<int Dim>
class IntersectorData
  : public RefCounted
{
public:
  typedef IntersectorData<Dim> This_t;
  typedef std::vector<int> IDContainer_t;
  typedef Range<7> BaseDomain_t;
  typedef std::vector<BaseDomain_t> BaseDomainContainer_t;
  typedef INode<Dim> INode_t;
  typedef std::vector<INode_t> INodeContainer_t;
  typedef typename INodeContainer_t::const_iterator const_iterator;
  typedef Unique::Value_t LayoutID_t;
  enum { dimensions = Dim };
  inline IntersectorData() { }
  inline ~IntersectorData() { }
  template<class Engine>
  void intersect(const Engine &engine)
  {
    typedef typename Engine::Layout_t Layout_t;
    const Layout_t &layout(engine.layout());
    int n = ids_m.size();
    for (int i = 0; i < n; ++i)
    {
      if (ids_m[i] == layout.ID())
 return;
      if (baseIDs_m[i] == layout.baseID()
   && sameBaseDomain(i, layout.baseDomain()))
      {
 shared(layout.ID(),ids_m[i]);
 return;
      }
    }
    touches(layout);
  }
  template<class Engine, int Dim2>
  bool intersect(const Engine &engine, const GuardLayers<Dim2> &guard,
   GuardLayers<Dim2> &usedGuards)
  {
    PoomaCTAssert<(Engine::dimensions == Dim)>::test();
    typedef typename Engine::Layout_t Layout_t;
    const Layout_t &layout(engine.layout());
    int n = ids_m.size();
    for (int i = 0; i < n; ++i)
    {
      if (ids_m[i] == layout.ID())
 return false;
      if (baseIDs_m[i] == layout.baseID()
   && sameBaseDomain(i, layout.baseDomain(), guard))
      {
 shared(layout.ID(),ids_m[i]);
 if (baseDims_m[i] < Dim2)
   return true;
 bool used = false;
 for (int j = 0; j < Dim2; j++)
 {
   usedGuards.lower(j) = std::max(0, baseDomains_m[i][j].first() - layout.baseDomain()[j].first());
   if (usedGuards.lower(j) != 0)
     used = true;
   usedGuards.upper(j) = std::max(0, layout.baseDomain()[j].last() - baseDomains_m[i][j].last());
   if (usedGuards.upper(j) != 0)
     used = true;
 }
 return used;
      }
    }
    touches(layout);
    return false;
  }
  template<int Dim2>
  bool sameBaseDomain(int i, const Range<Dim2> &domain,
        const GuardLayers<Dim2> &guard)
  {
    if (baseDims_m[i] != Dim2)
      return false;
    for (int j = 0; j < Dim2; j++)
    {
      if (baseDomains_m[i][j].stride() != domain[j].stride()) return false;
      if (baseDomains_m[i][j].first() > domain[j].first() + guard.lower(j))
 return false;
      if (baseDomains_m[i][j].last() < domain[j].last() - guard.upper(j))
 return false;
    }
    return true;
  }
  template<int Dim2>
  bool sameBaseDomain(int i, const Range<Dim2> &domain)
  {
    if (baseDims_m[i] != Dim2)
      return false;
    for (int j = 0; j < Dim2; j++)
      if (baseDomains_m[i][j] != domain[j]) return false;
    return true;
  }
  template<int Dim2>
  bool sameBaseDomain(int i, const Interval<Dim2> &domain,
        const GuardLayers<Dim2> & guard)
  {
    if (baseDims_m[i] != Dim2)
      return false;
    for (int j = 0; j < Dim2; j++)
    {
      if (baseDomains_m[i][j].stride() != 1) return false;
      if (baseDomains_m[i][j].first() > domain[j].first() + guard.lower(j))
 return false;
      if (baseDomains_m[i][j].last() < domain[j].last() - guard.upper(j))
 return false;
    }
    return true;
  }
  template<int Dim2>
  void pushBaseDomain(const Range<Dim2> &domain)
  {
    int i = baseDomains_m.size();
    baseDims_m.push_back(Dim2);
    baseDomains_m.push_back(BaseDomain_t());
    for (int j = 0; j < Dim2; j++)
      baseDomains_m[i][j] =
        Range<1>(domain[j].first(), domain[j].last(), domain[j].stride());
  }
  template<int Dim2>
  bool sameBaseDomain(int i, const Interval<Dim2> &domain)
  {
    if (baseDims_m[i] != Dim2)
      return false;
    for (int j = 0; j < Dim2; j++)
      if (baseDomains_m[i][j] != domain[j]) return false;
    return true;
  }
  template<int Dim2>
  void pushBaseDomain(const Interval<Dim2> &domain)
  {
    int i = baseDomains_m.size();
    baseDims_m.push_back(Dim2);
    baseDomains_m.push_back(BaseDomain_t());
    for (int j = 0; j < Dim2; j++)
      baseDomains_m[i][j] =
        Range<1>(domain[j].first(), domain[j].last(), domain[j].stride());
  }
  template<class Layout>
  void touches(const Layout &l)
  {
    int n = ids_m.size();
    ids_m.push_back(l.ID());
    baseIDs_m.push_back(l.baseID());
    pushBaseDomain(l.baseDomain());
    if (n == 0)
    {
      typename Layout::const_iterator p = l.beginGlobal();
      while (p != l.endGlobal())
      {
 if (! (*p).domain().empty())
   inodes_m.push_back(INode_t(*p,l.ID(),
         &(gidStore_m)));
 ++p;
      }
    }
    else
    {
      int ni = inodes_m.size();
      for (int i = 0; i < ni; i++)
 l.touches(inodes_m[i].domain(),
    std::back_inserter(inodes_m),
    inodes_m[i].touchesConstructINode(l.ID())
    );
      inodes_m.erase(inodes_m.begin(),
        inodes_m.begin() + ni);
    }
  }
  inline
  void shared(LayoutID_t id1, LayoutID_t id2)
  {
    gidStore_m.shared(id1,id2);
  }
  IntersectorData(const This_t &);
  This_t &operator=(const This_t &);
  IDContainer_t ids_m, baseIDs_m, baseDims_m;
  BaseDomainContainer_t baseDomains_m;
  INodeContainer_t inodes_m;
  GlobalIDDataBase gidStore_m;
};
template<int Dim>
class Intersector
{
public:
  typedef IntersectorData<Dim> IntersectorData_t;
  typedef Intersector<Dim> This_t;
  typedef typename IntersectorData_t::IDContainer_t IDContainer_t;
  typedef typename IntersectorData_t::BaseDomain_t BaseDomain_t;
  typedef typename IntersectorData_t::BaseDomainContainer_t
                                                        BaseDomainContainer_t;
  typedef typename IntersectorData_t::INode_t INode_t;
  typedef typename IntersectorData_t::INodeContainer_t INodeContainer_t;
  typedef typename IntersectorData_t::const_iterator const_iterator;
  typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
  enum { dimensions = Dim };
  Intersector()
    : pdata_m(new IntersectorData_t())
  { }
  Intersector(const This_t &model)
    : pdata_m(model.pdata_m)
  { }
  This_t &operator=(const This_t &model)
  {
    if (this != &model)
      pdata_m = model.pdata_m;
    return *this;
  }
  ~Intersector() { }
  inline DataPtr_t &data() { return pdata_m; }
  inline const DataPtr_t &data() const { return pdata_m; }
  inline const_iterator begin() const { return data()->inodes_m.begin(); }
  inline const_iterator end() const { return data()->inodes_m.end(); }
  inline int size() const { return data()->inodes_m.size(); }
  template<class Engine>
  inline
  void intersect(const Engine &l)
  {
    data()->intersect(l);
  }
  template<class Engine, int Dim2>
  inline
  bool intersect(const Engine &l, const GuardLayers<Dim2> &guard, GuardLayers<Dim2> &usedGuards)
  {
    return (data()->intersect(l,guard,usedGuards));
  }
private:
  DataPtr_t pdata_m;
};
template <class EvalTag>
struct Evaluator
{
};
template <>
struct Evaluator<MainEvaluatorTag>
{
  Evaluator() { }
  ~Evaluator() { }
  template <class LHS, class RHS, class Op>
  void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
  {
    typedef typename EvaluatorTag<LHS, RHS>::Evaluator_t Eval_t;
    Evaluator<Eval_t> evaluator;
    Pooma::beginExpression();
    evaluator.evaluate(lhs(), op, rhs());
    notifyEngineWrite(lhs.engine());
    Pooma::endExpression();
    ;
  }
  template <class LHS, class RHS, class Op>
  void evaluateZeroBased(const LHS& lhs, const Op& op, const RHS& rhs) const
  {
    typedef typename EvaluatorTag<LHS, RHS>::Evaluator_t Eval_t;
    Evaluator<Eval_t> evaluator;
    Pooma::beginExpression();
    evaluator.evaluate(lhs, op, rhs);
    notifyEngineWrite(lhs.engine());
    Pooma::endExpression();
    ;
  }
};
template <>
struct Evaluator<SinglePatchEvaluatorTag>
{
  Evaluator() { }
  ~Evaluator() { }
  template <class LHS, class RHS, class Op>
  void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
  {
    typedef typename KernelTag<LHS,RHS>::Kernel_t Kernel_t;
    Pooma::Iterate_t *iterate = ::generateKernel(lhs, op, rhs, Kernel_t());
    Pooma::scheduler().handOff(iterate);
  }
};
template <>
struct Evaluator<MultiPatchEvaluatorTag>
{
  Evaluator() { }
  ~Evaluator() { }
  template <class LHS, class RHS, class Op>
  void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
  {
    typedef Intersector<LHS::dimensions> Inter_t;
    Inter_t inter;
    expressionApply(lhs, IntersectorTag<Inter_t>(inter));
    expressionApply(rhs, IntersectorTag<Inter_t>(inter));
    typename Inter_t::const_iterator i = inter.begin();
    while (i != inter.end())
    {
      Evaluator<SinglePatchEvaluatorTag>().evaluate(lhs(*i), op, rhs(*i));
      ++i;
    }
    ;
    ;
  }
};
template<class T>
struct MaskAssign
{
  MaskAssign() { }
  MaskAssign(bool q) : cond_m(q) { }
  MaskAssign(bool q, const T& v) : cond_m(q), value_m(v) { }
  ~MaskAssign() { }
  inline bool defined() const { return cond_m; }
  inline const T &value() const { return value_m; }
  inline bool operator!=(const MaskAssign<T> &other) const
  {
    if (defined())
    {
      return ((other.defined() != defined()) || (other.value() != value()));
    }
    else
    {
      return other.defined();
    }
  }
  MaskAssign(const MaskAssign<T> &) { }
  MaskAssign<T> &operator=(const MaskAssign<T> &) { return *this; }
  bool cond_m;
  T value_m;
};
template<class Op>
struct OpMask
{
  OpMask() { }
  OpMask(const Op &op) : op_m(op) { }
  ~OpMask() { }
  template<class T1, class T2>
  inline void
  operator()(T1 &a, const MaskAssign<T2> &b) const
  {
    if (b.defined())
    {
      op_m(a, b.value());
    }
  }
  template<class T1, class T2>
  inline void
  operator()(T1 &a, const T2 &b) const
  {
    op_m(a, b);
  }
  Op op_m;
};
template<class T1, class T2, class Op>
struct BinaryReturn<T1, T2, OpMask<Op> >
{
  typedef T1 &Type_t;
};
#ifdef _OPENMP
#include <omp.h>
#endif
template <class Op, class T>
struct ReductionTraits;
template <class Op, class T>
struct ReductionTraits<OpMask<Op>, T>
{
  static T identity() { return ReductionTraits<Op, T>::identity(); }
};
struct WhereMask
{
  WhereMask() { }
  WhereMask(const WhereMask &) { }
  WhereMask &operator=(const WhereMask &) { return *this; }
  ~WhereMask() { }
};
template<class T1, class T2>
struct BinaryReturn<T1, T2, WhereMask>
{
  typedef MaskAssign<T2> Type_t;
};
template<class A, class B, class FTag>
struct ForEach< BinaryNode<WhereMask, A, B>, FTag, OpCombine >
{
  typedef typename ForEach<A,FTag,OpCombine>::Type_t TypeA_t;
  typedef typename ForEach<B,FTag,OpCombine>::Type_t TypeB_t;
  typedef MaskAssign<TypeB_t> Type_t;
  inline
  static Type_t
  apply(const BinaryNode<WhereMask,A,B>& expr,
 const FTag &f, const OpCombine &c)
  {
    bool mask = forEach(expr.left(), f, c);
    if ( mask )
    {
      return Type_t(mask, forEach(expr.right(), f, c));
    }
    else
    {
      return Type_t(mask);
    }
  }
};
struct FarLeftTag;
template<class A, class B>
struct ForEach< BinaryNode<WhereMask, A, B>, FarLeftTag, FarLeftTag >
{
  typedef typename ForEach<B,FarLeftTag,FarLeftTag>::Type_t Type_t;
  inline
  static Type_t
  apply(const BinaryNode<WhereMask,A,B>& expr,
 const FarLeftTag &f, const FarLeftTag &c)
  {
    return forEach(expr.right(), f, c);
  }
};
template<class A, class T>
struct ForEach< BinaryNode<WhereMask, A, Scalar<T> >, FarLeftTag, FarLeftTag >
{
  typedef typename ForEach<A,FarLeftTag,FarLeftTag>::Type_t Type_t;
  inline
  static Type_t
  apply(const BinaryNode<WhereMask,A,Scalar<T> >& expr,
 const FarLeftTag &f, const FarLeftTag &c)
  {
    return forEach(expr.left(), f, c);
  }
};
template<class A, class B>
struct ForEachRef< BinaryNode<WhereMask, A, B>, FarLeftTag, FarLeftTag >
{
  typedef typename ForEach<B,FarLeftTag,FarLeftTag>::Type_t Type_t;
  inline
  static const Type_t&
  apply(const BinaryNode<WhereMask,A,B>& expr,
 const FarLeftTag &f, const FarLeftTag &c)
  {
    return forEachRef(expr.right(), f, c);
  }
};
template<class A, class T>
struct ForEachRef< BinaryNode<WhereMask, A, Scalar<T> >, FarLeftTag, FarLeftTag >
{
  typedef typename ForEach<A,FarLeftTag,FarLeftTag>::Type_t Type_t;
  inline
  static const Type_t&
  apply(const BinaryNode<WhereMask,A,Scalar<T> >& expr,
 const FarLeftTag &f, const FarLeftTag &c)
  {
    return forEachRef(expr.left(), f, c);
  }
};
template<class T>
struct ExpressionTraits
{
  typedef void Type_t;
};
struct ExpressionIsScalar { };
template<class T>
struct ExpressionTraits<Scalar<T> >
{
  typedef ExpressionIsScalar Type_t;
};
template<class A, class B>
struct CombineExpressionTraits
{ };
template<class T>
struct ExpressionTraits<Reference<T> >
{
  typedef typename ExpressionTraits<T>::Type_t Type_t;
};
template<class Op, class Child>
struct ExpressionTraits<UnaryNode<Op, Child> >
{
  typedef typename ExpressionTraits<Child>::Type_t Type_t;
};
template<class Op, class Left, class Right>
struct ExpressionTraits<BinaryNode<Op, Left, Right> >
{
  typedef typename ExpressionTraits<Left>::Type_t Left_t;
  typedef typename ExpressionTraits<Right>::Type_t Right_t;
  typedef typename CombineExpressionTraits<Left_t, Right_t>::Type_t Type_t;
};
template<class Op, class Left, class Middle, class Right>
struct ExpressionTraits<TrinaryNode<Op, Left, Middle, Right> >
{
  typedef typename ExpressionTraits<Left>::Type_t Left_t;
  typedef typename ExpressionTraits<Middle>::Type_t Middle_t;
  typedef typename ExpressionTraits<Right>::Type_t Right_t;
  typedef typename CombineExpressionTraits<Left_t, Right_t>::Type_t Temp_t;
  typedef typename CombineExpressionTraits<Temp_t, Middle_t>::Type_t Type_t;
};
template<class ETrait, class Tree>
struct ConvertWhereProxy
{ };
template<class F, class B>
struct WhereProxy
{
  template <class Cond, class Val, class F1, class B1>
  struct WhereProxyTraits {
    enum { dimensions = F1::dimensions };
    typedef typename ForEach<Val, EvalLeaf<dimensions>, OpCombine>::Type_t Element_t;
  };
  template <class Cond, class T, class F1, class B1>
  struct WhereProxyTraits<Cond, Scalar<T>, F1, B1> {
    enum { dimensions = F1::dimensions };
    typedef T Element_t;
  };
  template <class Val, class T, class F1, class B1>
  struct WhereProxyTraits<Scalar<T>, Val, F1, B1> {
    enum { dimensions = B1::dimensions };
    typedef typename ForEach<Val, EvalLeaf<dimensions>, OpCombine>::Type_t Element_t;
  };
  template <class T1, class T2, class F1, class B1>
  struct WhereProxyTraits<Scalar<T1>, Scalar<T2>, F1, B1> {
  };
  WhereProxy(const F& f, const B& b) : f_m(f), b_m(b) { }
  typedef BinaryNode<WhereMask,
    typename CreateLeaf<F>::Leaf_t,
    typename CreateLeaf<B>::Leaf_t> Tree_t;
  typedef typename ExpressionTraits<Tree_t>::Type_t ETrait_t;
  typedef typename ConvertWhereProxy<ETrait_t,Tree_t>::Make_t MakeFromTree_t;
  typedef typename MakeFromTree_t::Expression_t WhereMask_t;
  typedef typename WhereProxyTraits<typename CreateLeaf<F>::Leaf_t,
 typename CreateLeaf<B>::Leaf_t, F, B>::Element_t Element_t;
  inline WhereMask_t
  whereMask() const
  {
    return MakeFromTree_t::make(Tree_t(CreateLeaf<F>::make(f_m),
           CreateLeaf<B>::make(b_m)));
  }
  template<class Op>
  inline OpMask<Op>
  opMask(const Op &op) const
  {
    return OpMask<Op>(op);
  }
  inline const F &flag() { return f_m; }
  inline const B &value() { return b_m; }
  const F &f_m;
  const B &b_m;
};
template<class F, class B>
inline WhereProxy<F,B>
where(const F &f, const B &b)
{
  return WhereProxy<F,B>(f,b);
}
template<int D,class T,class E> class Vector;
template<int DR, int DC, class T, class E> class TinyMatrix;
template<int D, class T, class E> class Tensor;
template<int D, class T, class EngineTag> class Tensor;
template<class OutputEngineTag, int D, class T, class EngineTag>
Tensor<D, T, OutputEngineTag>
symmetrize(const Tensor<D, T, EngineTag> &x);
struct FnReal
{
 
  template<class T>
  inline typename UnaryReturn<T, FnReal >::Type_t
  operator()(const T &a) const
  {
    return (real(a));
  }
};
struct FnImag
{
 
  template<class T>
  inline typename UnaryReturn<T, FnImag >::Type_t
  operator()(const T &a) const
  {
    return (imag(a));
  }
};
struct FnAbs
{
 
  template<class T>
  inline typename UnaryReturn<T, FnAbs >::Type_t
  operator()(const T &a) const
  {
    return (std::abs(a));
  }
};
struct FnArg
{
 
  template<class T>
  inline typename UnaryReturn<T, FnArg >::Type_t
  operator()(const T &a) const
  {
    return (arg(a));
  }
};
struct FnNorm
{
 
  template<class T>
  inline typename UnaryReturn<T, FnNorm >::Type_t
  operator()(const T &a) const
  {
    return (norm(a));
  }
};
struct FnConj
{
 
  template<class T>
  inline typename UnaryReturn<T, FnConj >::Type_t
  operator()(const T &a) const
  {
    return (conj(a));
  }
};
struct FnPow2
{
 
  template<class T>
  inline typename UnaryReturn<T, FnPow2 >::Type_t
  operator()(const T &a) const
  {
    return (a*a);
  }
};
struct FnPow3
{
 
  template<class T>
  inline typename UnaryReturn<T, FnPow3 >::Type_t
  operator()(const T &a) const
  {
    return (a*a*a);
  }
};
struct FnPow4
{
 
  template<class T>
  inline typename UnaryReturn<T, FnPow4 >::Type_t
  operator()(const T &a) const
  {
    return (a*a*a*a);
  }
};
struct FnMagnitude
{
 
  template<class T>
  inline typename UnaryReturn<T, FnMagnitude >::Type_t
  operator()(const T &a) const
  {
    return (magnitude(a));
  }
};
struct FnTrace
{
 
  template<class T>
  inline typename UnaryReturn<T, FnTrace >::Type_t
  operator()(const T &a) const
  {
    return (trace(a));
  }
};
struct FnDet
{
 
  template<class T>
  inline typename UnaryReturn<T, FnDet >::Type_t
  operator()(const T &a) const
  {
    return (det(a));
  }
};
struct FnTranspose
{
 
  template<class T>
  inline typename UnaryReturn<T, FnTranspose >::Type_t
  operator()(const T &a) const
  {
    return (transpose(a));
  }
};
template<class OutputSymmetry>
struct FnSymmetrize
{
 
  template<class T>
  inline typename UnaryReturn<T, FnSymmetrize<OutputSymmetry> >::Type_t
  operator()(const T &a) const
  {
    return (symmetrize<OutputSymmetry>(a));
  }
};
struct FnDot
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnDot >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return dot(a,b);
  }
};
struct FnPolar
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnPolar >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (polar(a,b));
  }
};
struct FnOuterProduct
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnOuterProduct >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (outerProduct(a,b));
  }
};
struct FnOuterProductAsTinyMatrix
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnOuterProductAsTinyMatrix >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (outerProductAsTinyMatrix(a,b));
  }
};
struct FnDotDot
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnDotDot >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (dotdot(a,b));
  }
};
struct FnMin
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnMin >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return
        std::min(a, b)
;
  }
};
struct FnMax
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnMax >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return
        std::max(a, b)
;
  }
};
struct OpLT2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLT2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a < b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLT2 > {
  typedef bool Type_t;
};
struct OpLE2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpLE2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a <= b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpLE2 > {
  typedef bool Type_t;
};
struct OpGT2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpGT2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a > b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpGT2 > {
  typedef bool Type_t;
};
struct OpGE2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpGE2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a >= b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpGE2 > {
  typedef bool Type_t;
};
struct OpEQ2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpEQ2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a == b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpEQ2 > {
  typedef bool Type_t;
};
struct OpNE2
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, OpNE2 >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    return (a != b);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, OpNE2 > {
  typedef bool Type_t;
};
struct FnMinAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnMinAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
        const_cast<T1 &>(a) = std::min(a, b)
;
    return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, FnMinAssign > {
  typedef T1 &Type_t;
};
struct FnMaxAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnMaxAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
        const_cast<T1 &>(a) = std::max(a, b)
;
    return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, FnMaxAssign > {
  typedef T1 &Type_t;
};
struct FnAndAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnAndAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    const_cast<T1 &>(a) = (a && b);
    return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, FnAndAssign > {
  typedef bool Type_t;
};
struct FnOrAssign
{
 
  template<class T1, class T2>
  inline typename BinaryReturn<T1, T2, FnOrAssign >::Type_t
  operator()(const T1 &a, const T2 &b) const
  {
    const_cast<T1 &>(a) = (a || b);
    return const_cast<T1 &>(a);
  }
};
template<class T1, class T2 >
struct BinaryReturn<T1, T2, FnOrAssign > {
  typedef bool Type_t;
};
using std::complex;
template<class T>
struct UnaryReturn< complex<T>, FnConj >
{
  typedef complex<T> Type_t;
};
template<class T>
struct UnaryReturn<complex<T>, FnReal>
{
  typedef T Type_t;
};
template<class T>
struct UnaryReturn<complex<T>, FnImag>
{
  typedef T Type_t;
};
template<class T>
struct UnaryReturn<complex<T>, FnArg>
{
  typedef T Type_t;
};
template<class T>
struct UnaryReturn<complex<T>, FnNorm>
{
  typedef T Type_t;
};
template<class T>
struct UnaryReturn<T, FnAbs>
{
  typedef T Type_t;
};
template<class T>
struct UnaryReturn<complex<T>, FnAbs>
{
  typedef T Type_t;
};
template<class T>
struct Promote<complex<T>, complex<T> >
{
  typedef complex<T> Type_t;
};
template<class T>
struct Promote<complex<T>, T>
{
  typedef complex<T> Type_t;
};
template<class T>
struct Promote<T, complex<T> >
{
  typedef complex<T> Type_t;
};
template<class T>
struct BinaryReturn<complex<T>, int, FnPow>
{
  typedef complex<T> Type_t;
};
template<class T>
struct UnaryReturn<T, FnPow2>
{
  typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
};
template<class T>
struct UnaryReturn<T, FnPow3>
{
  typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
};
template<class T>
struct UnaryReturn<T, FnPow4>
{
  typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
};
template<class T, class A> struct LeafFunctor;
template<class T> class Scalar;
template<int D>
class ConformTag
{
public:
  template<class Domain>
  ConformTag(const Domain& domain)
  {
    for (int i=0; i<D; ++i)
      lengths_m[i] = domain[i].length();
  }
  int length(int i) const { return lengths_m[i]; }
private:
  int lengths_m[D];
};
template<class Domain>
bool conforms(const Domain &d, const ConformTag<1> &ct)
{
  return d.length() == ct.length(0);
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<2> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1));
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<3> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1))
      && (d[2].length() == ct.length(2));
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<4> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1))
      && (d[2].length() == ct.length(2))
      && (d[3].length() == ct.length(3));
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<5> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1))
      && (d[2].length() == ct.length(2))
      && (d[3].length() == ct.length(3))
      && (d[4].length() == ct.length(4));
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<6> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1))
      && (d[2].length() == ct.length(2))
      && (d[3].length() == ct.length(3))
      && (d[3].length() == ct.length(4))
      && (d[5].length() == ct.length(5));
}
template<class Domain>
bool conforms(const Domain &d, const ConformTag<7> &ct)
{
  return (d[0].length() == ct.length(0))
      && (d[1].length() == ct.length(1))
      && (d[2].length() == ct.length(2))
      && (d[3].length() == ct.length(3))
      && (d[3].length() == ct.length(4))
      && (d[5].length() == ct.length(5))
      && (d[6].length() == ct.length(6));
}
template<int D, class T>
struct LeafFunctor<Scalar<T>, ConformTag<D> >
{
  typedef bool Type_t;
  static Type_t apply(const Scalar<T> &, const ConformTag<D> &)
  {
    return true;
  }
};
template<class T, class A> struct LeafFunctor;
struct PerformUpdateTag {};
template<class Node>
struct LeafFunctor<Node, PerformUpdateTag>
{
  typedef int Type_t;
  inline static
  Type_t apply(const Node &, const PerformUpdateTag &)
    {
      return 0;
    }
};
template<class T>
class ModelElement
{
public:
  explicit ModelElement(const T &e) : e_m(e) { }
  ModelElement(const ModelElement<T> &m) : e_m(m.e_m) { }
  const T &element() const { return e_m; }
private:
  const T &e_m;
};
template<class T>
inline ModelElement<T> modelElement(const T &elem)
  {
    return ModelElement<T>(elem);
  }
template<class T, class A> struct LeafFunctor;
template<class T> class Scalar;
struct NotifyPreReadTag { };
template<class T>
struct LeafFunctor<Scalar<T>, NotifyPreReadTag>
{
  typedef bool Type_t;
  static Type_t apply(const Scalar<T> &, const NotifyPreReadTag &)
  {
    return true;
  }
};
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnArcCos,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
acos(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnArcCos,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnArcSin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
asin(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnArcSin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnArcTan,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
atan(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnArcTan,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnCeil,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
ceil(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnCeil,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnCos,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
cos(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnCos,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnHypCos,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
cosh(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnHypCos,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnExp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
exp(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnExp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnFabs,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
fabs(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnFabs,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnFloor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
floor(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnFloor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnLog,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
log(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnLog,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnLog10,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
log10(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnLog10,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnSin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
sin(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnSin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnHypSin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
sinh(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnHypSin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnSqrt,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
sqrt(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnSqrt,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnTan,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
tan(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnTan,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnHypTan,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
tanh(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnHypTan,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpUnaryMinus,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<OpUnaryMinus,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpUnaryPlus,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<OpUnaryPlus,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpBitwiseNot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator~(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<OpBitwiseNot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpIdentity,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
PETE_identity(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<OpIdentity,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpNot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator!(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<OpNot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<UnaryNode<OpCast<T1>,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
peteCast(const T1&, const Array<D2,T2,E2> & l)
{
  typedef UnaryNode<OpCast<T1>,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D2,T2,E2> >::make(l)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLeftShift,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<<(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLeftShift,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpRightShift,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>>(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpRightShift,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpLT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpLE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<=(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpGT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpGE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>=(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator&&(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator||(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpLeftShift,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<<(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLeftShift,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpRightShift,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>>(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpRightShift,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLT,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGT,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAnd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpOr,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class T2,class T3>
inline typename MakeReturn<TrinaryNode<FnWhere,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t,
  typename CreateLeaf<T3 >::Leaf_t> >::Expression_t
where(const Array<D1,T1,E1> & c,const T2 & t,const T3 & f)
{
  typedef TrinaryNode<FnWhere,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t,
    typename CreateLeaf<T3 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(c),
    CreateLeaf<T2 >::make(t),
    CreateLeaf<T3 >::make(f)));
}
template<int D, class T, class EngineTag> class Tensor;
template<class OutputEngineTag, int D, class T, class EngineTag>
Tensor<D, T, OutputEngineTag>
symmetrize(const Tensor<D, T, EngineTag> &x);
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnReal,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
real(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnReal,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnImag,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
imag(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnImag,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnAbs,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
abs(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnAbs,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnArg,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
arg(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnArg,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnNorm,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
norm(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnNorm,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnConj,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
conj(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnConj,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnPow2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
pow2(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnPow2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnPow3,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
pow3(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnPow3,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnPow4,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
pow4(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnPow4,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnMagnitude,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
magnitude(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnMagnitude,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnTrace,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
trace(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnTrace,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnDet,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
det(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnDet,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnTranspose,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
transpose(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnTranspose,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<class OutputSymmetry,int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnSymmetrize<OutputSymmetry>,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
symmetrize(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnSymmetrize<OutputSymmetry>,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
polar(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnMin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
min(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnMax,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
max(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LT(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GT(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
NE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
polar(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
outerProduct(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
dotdot(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnMin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
min(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<FnMax,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
max(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
LT(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
LE(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
GT(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
GE(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
EQ(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class T2>
inline typename MakeReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
NE(const Array<D1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPolar,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
polar(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnMin,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
min(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnMax,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
max(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLT2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LT(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpLE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LE(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGT2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GT(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpGE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GE(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class T1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
NE(const T1 & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<BinaryNode<FnMin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
min(const Array<D1,T1,E1> & l,const Array<D1,T1,E1> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D1,T1,E1> >::make(r)));
}
template<int D1,class T1,class E1>
inline typename MakeReturn<BinaryNode<FnMax,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
max(const Array<D1,T1,E1> & l,const Array<D1,T1,E1> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D1,T1,E1> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpAdd,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpDivide,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpMod,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnDot,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnPow,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnFmod,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpEQ,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeReturn<BinaryNode<OpNE,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<int Dim, class T, class EngineTag>
struct CreateLeaf<Array<Dim, T, EngineTag> >
{
  typedef Array<Dim, T, EngineTag> Input_t;
  typedef Reference<Input_t> Leaf_t;
  typedef Leaf_t Return_t;
  inline static
  Return_t make(const Input_t &a)
    {
      return Leaf_t(a);
    }
};
template<int Dim, class T, class Expr>
struct CreateLeaf<Array<Dim, T, ExpressionTag<Expr> > >
{
  typedef Array<Dim, T, ExpressionTag<Expr> > Input_t;
  typedef Expr Leaf_t;
  typedef const Leaf_t &Return_t;
  inline static
  Return_t make(const Input_t &a)
    {
      return a.engine().expression();
    }
};
template<int Dim, class T, class EngineTag>
struct CreateLeaf<Scalar<Array<Dim, T, EngineTag> > >
{
  typedef Scalar<Array<Dim, T, EngineTag> > Input_t;
  typedef Scalar<ErrorType> Leaf_t;
  typedef Leaf_t Return_t;
  inline static
  Return_t make(const Input_t &)
    {
      return ErrorType();
    }
};
template<class Op,class Leaf>
struct MakeReturn<UnaryNode<Op,Leaf> >
{
  typedef UnaryNode<Op,Leaf> Tree_t;
  typedef typename ForEach<Tree_t,
    DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename UnaryReturn<typename ForEach<Leaf,
    EvalLeaf<dim>,OpCombine>::Type_t,
    Op>::Type_t T_t;
  typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
  typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class Op,class Left,class Right>
struct MakeReturn<BinaryNode<Op,Left,Right> >
{
  typedef BinaryNode<Op,Left,Right> Tree_t;
  typedef typename ForEach<Tree_t,
    DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename BinaryReturn<typename ForEach<Left,
    EvalLeaf<dim>,OpCombine>::Type_t,
    typename ForEach<Right,EvalLeaf<dim>,OpCombine>::Type_t,
    Op>::Type_t T_t;
  typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
  typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class Op,class Cl,class Tr,class Fl>
struct MakeReturn<TrinaryNode<Op,Cl,Tr,Fl> >
{
  typedef TrinaryNode<Op,Cl,Tr,Fl> Tree_t;
  typedef typename ForEach<Tree_t,
    DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename TrinaryReturn<typename ForEach<Cl,
    EvalLeaf<dim>,OpCombine>::Type_t,
    typename ForEach<Tr,EvalLeaf<dim>,OpCombine>::Type_t,
    typename ForEach<Fl,EvalLeaf<dim>,OpCombine>::Type_t,
    Op>::Type_t T_t;
  typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
  typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class Op, class T>
struct ReductionTraits {
};
template<class T>
struct ReductionTraits<OpAddAssign, T> {
  static inline T identity() { return T(0); }
};
template<class T>
struct ReductionTraits<OpMultiplyAssign, T> {
  static inline T identity() { return T(1); }
};
template<class T>
struct ReductionTraits<FnMinAssign, T> {
  static inline T identity() { return std::numeric_limits<T>::max(); }
};
template<class T>
struct ReductionTraits<FnMaxAssign, T> {
  static inline T identity() { return std::numeric_limits<T>::min(); }
};
template<class T>
struct ReductionTraits<FnOrAssign, T> {
  static inline T identity() { return T(false); }
};
template<class T>
struct ReductionTraits<FnAndAssign, T> {
  static inline T identity() { return T(true); }
};
template<class T>
struct ReductionTraits<OpBitwiseOrAssign, T> {
  static inline T identity() { return T(); }
};
template<class T>
struct ReductionTraits<OpBitwiseAndAssign, T> {
  static inline T identity() { return ~T(); }
};
#ifndef _OPENMP
template<class T>
struct PartialReduction {
 static inline void init() {}
 inline void storePartialResult(const T& result)
 {
   answer = result;
 }
 template <class Op>
 inline void reduce(T& ret, const Op&)
 { 
   ret = answer;
 } 
 T answer;
};
#else
template<class T>
struct PartialReduction {
  static inline void init()
  {
    if (!answer)
     answer = new T[omp_get_max_threads()];
  }
  inline void storePartialResult(const T& result)
  {
    int n = omp_get_thread_num();
    answer[n] = result;
    if (n == 0)
      num_threads = omp_get_num_threads();
  }
  template <class Op>
  inline void reduce(T& ret, const Op& op)
  {
    T res = answer[0];
    for (int i = 1; i<num_threads; ++i)
      op(res, answer[i]);
    ret = res;
  }
  int num_threads;
  static T *answer;
};
template <class T>
T *PartialReduction<T>::answer = NULL;
#endif
template<class KernelTag>
struct ReductionEvaluator;
template<>
struct ReductionEvaluator<InlineKernelTag>
{
  template<class T, class Op, class Expr>
  static /*__attribute__((leafify))*/
  void evaluate(T &ret, const Op &op, const Expr &e)
  {
    typedef typename Expr::Domain_t Domain_t;
    PoomaCTAssert<(Domain_t::unitStride)>::test();
    for (int i=0; i<Domain_t::dimensions; ++i)
      ;
    PartialReduction<T>::init();
    evaluate(ret, op, e, e.domain(),
      WrappedInt<Domain_t::dimensions>());
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<1>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    PartialReduction<T> reduction;
#pragma omp parallel if (e0 > 512)
    {
      T answer = ReductionTraits<Op, T>::identity();
;
#pragma omp for nowait
      for (int i0 = 0; i0 < e0; ++i0)
        op(answer, localExpr.read(i0));
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<2>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i1 = 0; i1 < e1; ++i1) {
;
 for (int i0 = 0; i0 < e0; ++i0)
   op(answer, localExpr.read(i0, i1));
      }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<3>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i2 = 0; i2 < e2; ++i2)
 for (int i1 = 0; i1 < e1; ++i1) {
;
   for (int i0 = 0; i0 < e0; ++i0)
     op(answer, localExpr.read(i0, i1, i2));
 }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<4>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i3 = 0; i3 < e3; ++i3)
 for (int i2 = 0; i2 < e2; ++i2)
   for (int i1 = 0; i1 < e1; ++i1) {
;
     for (int i0 = 0; i0 < e0; ++i0)
       op(answer, localExpr.read(i0, i1, i2, i3));
   }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<5>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i4 = 0; i4 < e4; ++i4)
 for (int i3 = 0; i3 < e3; ++i3)
   for (int i2 = 0; i2 < e2; ++i2)
     for (int i1 = 0; i1 < e1; ++i1) {
;
       for (int i0 = 0; i0 < e0; ++i0)
  op(answer, localExpr.read(i0, i1, i2, i3, i4));
     }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<6>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
    int e5 = domain[5].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i5 = 0; i5 < e5; ++i5)
 for (int i4 = 0; i4 < e4; ++i4)
   for (int i3 = 0; i3 < e3; ++i3)
     for (int i2 = 0; i2 < e2; ++i2)
       for (int i1 = 0; i1 < e1; ++i1) {
;
  for (int i0 = 0; i0 < e0; ++i0)
    op(answer, localExpr.read(i0, i1, i2, i3, i4, i5));
       }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
  template<class T, class Op, class Expr, class Domain>
  inline static void evaluate(T &ret, const Op &op, const Expr &e,
    const Domain &domain, WrappedInt<7>)
  {
    Expr localExpr(e);
    int e0 = domain[0].length();
    int e1 = domain[1].length();
    int e2 = domain[2].length();
    int e3 = domain[3].length();
    int e4 = domain[4].length();
    int e5 = domain[5].length();
    int e6 = domain[6].length();
    PartialReduction<T> reduction;
#pragma omp parallel
    {
      T answer = ReductionTraits<Op, T>::identity();
#pragma omp for nowait
      for (int i6 = 0; i6 < e6; ++i6)
 for (int i5 = 0; i5 < e5; ++i5)
   for (int i4 = 0; i4 < e4; ++i4)
     for (int i3 = 0; i3 < e3; ++i3)
       for (int i2 = 0; i2 < e2; ++i2)
  for (int i1 = 0; i1 < e1; ++i1) {
;
    for (int i0 = 0; i0 < e0; ++i0)
      op(answer, localExpr.read(i0, i1, i2, i3, i4, i5, i6));
  }
      reduction.storePartialResult(answer);
    }
    reduction.reduce(ret, op);
  }
};
template<class T, class Op>
struct CompressibleReduce
{
  template<class T1>
  inline static void evaluate(T &ret, const Op &, const T1 &val, int)
  {
    ret = static_cast<T>(val);
  }
};
template<class T>
struct CompressibleReduce<T, OpAddAssign>
{
  template<class T1>
  inline static void evaluate(T &ret, const OpAddAssign &, const T1 &val,
    int n)
  {
    ret = static_cast<T>(n * val);
  }
};
template<class T>
struct CompressibleReduce<T, OpMultiplyAssign>
{
  template<class T1>
  inline static void evaluate(T &ret, const OpMultiplyAssign &, const T1 &val,
    int n)
  {
    ret = static_cast<T>(val);
    while (--n > 0)
      ret *= static_cast<T>(val);
  }
};
template<>
struct ReductionEvaluator<CompressibleKernelTag>
{
  template<class T, class Op, class Expr>
  inline static void evaluate(T &ret, const Op &op, const Expr &e)
  {
    if (engineFunctor(e, Compressed()))
      {
        CompressibleReduce<T, Op>::
          evaluate(ret, op, engineFunctor(e, CompressedRead()),
            e.domain().size());
      }
    else
      {
        ReductionEvaluator<InlineKernelTag>::evaluate(ret, op, e);
      }
  }
};
namespace Pooma {
class CountingSemaphore
{
public:
  CountingSemaphore() { }
  CountingSemaphore(const CountingSemaphore &) { }
  CountingSemaphore &operator=(const CountingSemaphore &) { return *this; }
  void wait() const { }
  int count() const { return 0; }
  int height() const { return 0; }
  void height(int) { }
  void raise_height(int) { }
  void incr() { }
  CountingSemaphore &operator++() { incr(); return *this; }
  int operator+=(int) { return 0; }
};
}
template<class T, class Op, class Expr, class KernelTag>
class ReductionKernel : public Pooma::Iterate_t
{
public:
  typedef ReductionKernel<T, Op, Expr, KernelTag> This_t;
  ReductionKernel(T &ret, const Op &op, const Expr &e,
    Pooma::CountingSemaphore &csem);
  virtual ~ReductionKernel();
  virtual void /*__attribute__((leafify))*/ run();
private:
  T &ret_m;
  Op op_m;
  Expr expr_m;
  Pooma::CountingSemaphore &csem_m;
};
template<class T, class Op, class Expr, class KernelTag>
ReductionKernel<T, Op, Expr, KernelTag>::
ReductionKernel(T &ret, const Op &op, const Expr &e,
  Pooma::CountingSemaphore &csem)
  : Pooma::Iterate_t(Pooma::scheduler()),
    ret_m(ret), op_m(op), expr_m(e), csem_m(csem)
{
  DataObjectRequest<ReadRequest> readReq(*this);
  engineFunctor(expr_m, readReq);
}
template<class T, class Op, class Expr, class KernelTag>
ReductionKernel<T, Op, Expr, KernelTag>::~ReductionKernel()
{
  DataObjectRequest<ReadRelease> readRelease;
  engineFunctor(expr_m, readRelease);
  csem_m.incr();
}
template<class T, class Op, class Expr, class KernelTag>
void ReductionKernel<T, Op, Expr, KernelTag>::run()
{
  ReductionEvaluator<KernelTag>::evaluate(ret_m, op_m, expr_m);
}
template <class EvalTag>
struct Reduction
{ };
template <>
struct Reduction<MainEvaluatorTag>
{
  Reduction() { }
  ~Reduction() { }
  template <class Expr>
  static inline bool checkValidity(const Expr &e, WrappedInt<false>)
  {
    return true;
  }
  template <class Expr>
  static inline bool checkValidity(const Expr &e, WrappedInt<true>)
  {
    return e.centeringSize() == 1 && e.numMaterials() == 1;
  }
  template<class T, class Op, class Cond, class Expr>
  void evaluate(T &ret, const Op &op, const WhereProxy<Cond, Expr> &w) const
  {
    evaluate(ret, w.opMask(op), w.whereMask());
  }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e) const
  {
    typedef typename EvaluatorTag1<Expr>::Evaluator_t Evaluator_t;
    Pooma::scheduler().beginGeneration();
    ;
    forEach(e, PerformUpdateTag(), NullCombine());
    Reduction<Evaluator_t>().evaluate(ret, op, e());
    Pooma::scheduler().endGeneration();
    ;
  }
};
template <>
struct Reduction<SinglePatchEvaluatorTag>
{
  Reduction() { }
  ~Reduction() { }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e,
  Pooma::CountingSemaphore &csem) const
  {
    typedef typename KernelTag1<Expr>::Kernel_t Kernel_t;
    Pooma::Iterate_t *iterate =
      new ReductionKernel<T, Op, Expr, Kernel_t>(ret, op, e, csem);
    Pooma::scheduler().handOff(iterate);
  }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e) const
  {
    Pooma::CountingSemaphore csem;
    csem.height(1);
    evaluate(ret, op, e, csem);
    csem.wait();
  }
};
template <>
struct Reduction<MultiPatchEvaluatorTag>
{
  Reduction() { }
  ~Reduction() { }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e) const
  {
    typedef Intersector<Expr::dimensions> Inter_t;
    Inter_t inter;
    expressionApply(e, IntersectorTag<Inter_t>(inter));
    const int n = inter.size();
    Pooma::CountingSemaphore csem;
    csem.height(n);
    T *vals = new T[n];
    typename Inter_t::const_iterator i = inter.begin();
    int j = 0;
    while (j < n)
      {
        Reduction<SinglePatchEvaluatorTag>().
          evaluate(vals[j], op, e(*i), csem);
        ++i; ++j;
      }
    csem.wait();
    ret = vals[0];
    for (j = 1; j < n; j++)
      op(ret, vals[j]);
    delete [] vals;
  }
};
template<class Subject>
typename Subject::Element_t sum(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, OpAddAssign(), s);
  return ret;
}
template<class Subject>
typename Subject::Element_t prod(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, OpMultiplyAssign(), s);
  return ret;
}
template<class Subject>
typename Subject::Element_t min(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, FnMinAssign(), s);
  return ret;
}
template<class Subject>
typename Subject::Element_t max(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, FnMaxAssign(), s);
  return ret;
}
template<class Subject>
bool all(const Subject &s)
{
  bool ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, FnAndAssign(), s);
  return ret;
}
template<class Subject>
bool any(const Subject &s)
{
  bool ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, FnOrAssign(), s);
  return ret;
}
template<class Subject>
typename Subject::Element_t bitOr(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, OpBitwiseOrAssign(), s);
  return ret;
}
template<class Subject>
typename Subject::Element_t bitAnd(const Subject &s)
{
  typename Subject::Element_t ret;
  Reduction<MainEvaluatorTag>().evaluate(ret, OpBitwiseAndAssign(), s);
  return ret;
}
template<int Dim, class T, class EngineTag,
  int OtherDim, class OtherT, class OtherEngineTag, class Op>
inline const Array<Dim, T, EngineTag> &
assign(const Array<Dim, T, EngineTag> &lhs,
       const Array<OtherDim, OtherT, OtherEngineTag> &rhs,
       const Op &op);
template<int Dim, class T, class EngineTag, class T1, class Op>
inline const Array<Dim, T, EngineTag> &
assign(const Array<Dim, T, EngineTag> &lhs, const T1 &rhs, const Op &op);
template<class Subject, class Sub1, bool SV>
struct View1Implementation;
template<int Dim, class T, class EngineTag, class Domain>
struct View1Implementation<Array<Dim, T, EngineTag>, Domain, true>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  template<class S1, class Combine>
  inline static
  Type_t make(const Subject_t &a, const S1 &s1,
       const Combine &)
    {
      Domain s(Combine::make(a, s1));
      return a.engine()(s);
    }
  template<class S1, class S2, class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2));
      return a.engine()(s);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3));
      return a.engine()(s);
    }
  template<class S1, class S2, class S3, class S4,
    class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const S4 &s4,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4));
      return a.engine()(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const S4 &s4, const S5 &s5,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5));
      return a.engine()(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const S4 &s4, const S5 &s5, const S6 &s6,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
      return a.engine()(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class S7, class Combine>
  inline static
  Type_t make(const Subject_t &a,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const S4 &s4, const S5 &s5, const S6 &s6,
       const S7 &s7,
       const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
      return a.engine()(s);
    }
  template<class S1, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a, const S1 &s1,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1));
      return a.engine().read(s);
    }
  template<class S1, class S2, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2));
      return a.engine().read(s);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2, const S3 &s3,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3));
      return a.engine().read(s);
    }
  template<class S1, class S2, class S3, class S4,
    class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2, const S3 &s3,
                   const S4 &s4,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4));
      return a.engine().read(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2, const S3 &s3,
                   const S4 &s4, const S5 &s5,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5));
      return a.engine().read(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2, const S3 &s3,
                   const S4 &s4, const S5 &s5, const S6 &s6,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
      return a.engine().read(s);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class S7, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &a,
                   const S1 &s1, const S2 &s2, const S3 &s3,
                   const S4 &s4, const S5 &s5, const S6 &s6,
                   const S7 &s7,
                   const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
      return a.engine().read(s);
    }
};
template<int Dim, class T, class EngineTag, class Domain>
struct View1Implementation<Array<Dim, T, EngineTag>, Domain, false>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef typename NewEngine<Engine_t, Domain>::Type_t NewEngine_t;
  enum { newDim = NewEngine_t::dimensions };
  typedef typename NewEngine_t::Tag_t NewEngineTag_t;
  typedef Array<newDim, T, NewEngineTag_t> Type_t;
  typedef Type_t ReadType_t;
  typedef NewEngineEngine<Engine_t, Domain> NewEE_t;
  typedef NewEngineDomain<Engine_t, Domain> NewED_t;
  template<class S1, class Combine>
  static
  Type_t make(const Subject_t &a, const S1 &s1,
           const Combine &)
    {
      Domain s(Combine::make(a, s1));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class Combine>
  static
  Type_t make(const Subject_t &a, const S1 &s1,
           const S2 &s2, const Combine &)
    {
      Domain s(Combine::make(a, s1, s2));
      return Type_t(
     NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class S3,
    class Combine>
  static
  Type_t make(const Subject_t &a,
           const S1 &s1, const S2 &s2, const S3 &s3,
           const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class S3, class S4,
    class Combine>
  static
  Type_t make(const Subject_t &a,
           const S1 &s1, const S2 &s2, const S3 &s3,
           const S4 &s4,
           const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class Combine>
  static
  Type_t make(const Subject_t &a,
           const S1 &s1, const S2 &s2, const S3 &s3,
           const S4 &s4, const S5 &s5,
           const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class Combine>
  static
  Type_t make(const Subject_t &a,
           const S1 &s1, const S2 &s2, const S3 &s3,
           const S4 &s4, const S5 &s5, const S6 &s6,
           const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class S7, class Combine>
  static
  Type_t make(const Subject_t &a,
           const S1 &s1, const S2 &s2, const S3 &s3,
           const S4 &s4, const S5 &s5, const S6 &s6,
           const S7 &s7,
           const Combine &)
    {
      Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
      return Type_t(
  NewEE_t::apply(a.engine(), s),
  NewED_t::apply(a.engine(), s));
    }
  template<class S1, class Combine>
  inline static
  Type_t makeRead(const Subject_t &a, const S1 &s1,
               const Combine &c)
    {
      return make(a, s1, c);
    }
  template<class S1, class S2, class Combine>
  inline static
  Type_t makeRead(const Subject_t &a, const S1 &s1,
               const S2 &s2, const Combine &c)
    {
      return make(a, s1, s2, c);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &a,
               const S1 &s1, const S2 &s2, const S3 &s3,
               const Combine &c)
    {
      return make(a, s1, s2, s3, c);
    }
  template<class S1, class S2, class S3, class S4,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &a,
               const S1 &s1, const S2 &s2, const S3 &s3,
               const S4 &s4, const Combine &c)
    {
      return make(a, s1, s2, s3, s4, c);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &a,
               const S1 &s1, const S2 &s2, const S3 &s3,
               const S4 &s4, const S5 &s5, const Combine &c)
    {
      return make(a, s1, s2, s3, s4, s5, c);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &a,
               const S1 &s1, const S2 &s2, const S3 &s3,
               const S4 &s4, const S5 &s5, const S6 &s6,
               const Combine &c)
    {
      return make(a, s1, s2, s3, s4, s5, s6, c);
    }
  template<class S1, class S2, class S3, class S4, class S5,
    class S6, class S7,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &a,
               const S1 &s1, const S2 &s2, const S3 &s3,
               const S4 &s4, const S5 &s5, const S6 &s6,
               const S7 &s7, const Combine &c)
    {
      return make(a, s1, s2, s3, s4, s5, s6, s7, c);
    }
};
template<int Dim, class T, class EngineTag, class Domain>
struct View1<Array<Dim, T, EngineTag>, Domain>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef TemporaryNewDomain1<Domain_t, Domain> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Domain &s1)
    {
      return Dispatch_t::make(a, s1, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Domain &s1)
    {
      return Dispatch_t::makeRead(a, s1, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View0<Array<Dim, T, EngineTag> >
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef typename NewEngine<Engine_t, Domain_t>::Type_t NewEngine_t;
  enum { newDim = NewEngine_t::dimensions };
  typedef typename NewEngine_t::Tag_t NewEngineTag_t;
  typedef Array<newDim, T, NewEngineTag_t> Type_t;
  typedef Type_t ReadType_t;
  static Type_t make(const Subject_t &a)
    {
      typedef NewEngineEngine<Engine_t, Domain_t> NewEE_t;
      typedef NewEngineDomain<Engine_t, Domain_t> NewED_t;
      return Type_t(
  NewEE_t::apply(a.engine(), a.engine().domain()),
  NewED_t::apply(a.engine(), a.engine().domain()));
    }
  inline static ReadType_t makeRead(const Subject_t &a)
    {
      return make(a);
    }
};
template<int Dim, class T, class EngineTag>
struct View1<Array<Dim, T, EngineTag>, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1)
    {
      return a.engine()(s1);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1)
    {
      return a.engine().read(s1);
    }
};
template<int Dim, class T, class EngineTag>
struct View1<Array<Dim, T, EngineTag>, Loc<Dim> >
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, const Loc<Dim>& s1)
    {
      ;
      return a.engine()(s1);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Loc<Dim>& s1)
    {
      ;
      return a.engine().read(s1);
    }
};
template<int D1, class T1, class E1, int D2, class T2, class E2>
struct View1<Array<D1, T1, E1>, Array<D2, T2, E2> >
{
  typedef Array<D1, T1, E1> Array1_t;
  typedef Array<D2, T2, E2> Array2_t;
  typedef IndirectionTag<Array1_t, Array2_t> Tag_t;
  typedef Array<D2, T1, Tag_t> Type_t;
  typedef Type_t ReadType_t;
  static
  Type_t make(const Array1_t &a, const Array2_t &s)
    {
      return Type_t(a, s);
    }
  inline static
  Type_t makeRead(const Array1_t &a, const Array2_t &s)
    {
      return make(a, s);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2>
struct View2<Array<Dim, T, EngineTag>, Sub1, Sub2>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain2<Sub1, Sub2> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2)
    {
      return Dispatch_t::make(a, s1, s2, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2)
    {
      return Dispatch_t::makeRead(a, s1, s2, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View2<Array<Dim, T, EngineTag>, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1, int s2)
    {
      return a.engine()(s1, s2);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2)
    {
      return a.engine().read(s1, s2);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3>
struct View3<Array<Dim, T, EngineTag>, Sub1, Sub2, Sub3>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain3<Sub1, Sub2, Sub3> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3)
    {
      return Dispatch_t::make(a, s1, s2, s3, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3)
    {
      return Dispatch_t::makeRead(a, s1, s2, s3, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View3<Array<Dim, T, EngineTag>, int, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1, int s2, int s3)
    {
      return a.engine()(s1, s2, s3);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3)
    {
      return a.engine().read(s1, s2, s3);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3, class Sub4>
struct View4<Array<Dim, T, EngineTag>,
  Sub1, Sub2, Sub3, Sub4>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain4<Sub1, Sub2, Sub3, Sub4> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4)
    {
      return Dispatch_t::make(a, s1, s2, s3, s4, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4)
    {
      return Dispatch_t::makeRead(a, s1, s2, s3, s4, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View4<Array<Dim, T, EngineTag>, int, int, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4)
    {
      return a.engine()(s1, s2, s3, s4);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3, int s4)
    {
      return a.engine().read(s1, s2, s3, s4);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
struct View5<Array<Dim, T, EngineTag>,
  Sub1, Sub2, Sub3, Sub4, Sub5>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5)
    {
      return Dispatch_t::make(a, s1, s2, s3, s4, s5, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5)
    {
      return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View5<Array<Dim, T, EngineTag>, int, int, int, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
    int s4, int s5)
    {
      return a.engine().read(s1, s2, s3, s4, s5);
    }
  inline static
  Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5)
    {
      return a.engine()(s1, s2, s3, s4, s5);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
  class Sub6>
struct View6<Array<Dim, T, EngineTag>,
  Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
    {
      return Dispatch_t::make(a, s1, s2, s3, s4, s5, s6, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
    {
      return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, s6, Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View6<Array<Dim, T, EngineTag>, int, int, int, int, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5,
       int s6)
    {
      return a.engine()(s1, s2, s3, s4, s5, s6);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
    int s4, int s5, int s6)
    {
      return a.engine().read(s1, s2, s3, s4, s5, s6);
    }
};
template<int Dim, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
  class Sub6, class Sub7>
struct View7<Array<Dim, T, EngineTag>,
  Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>
    NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::Type_t Type_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  inline static
  Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
    const Sub7 &s7)
    {
      return Dispatch_t::make(a, s1, s2, s3, s4, s5, s6, s7, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
    const Sub7 &s7)
    {
      return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, s6, s7,
        Combine_t());
    }
};
template<int Dim, class T, class EngineTag>
struct View7<Array<Dim, T, EngineTag>, int, int, int, int, int, int, int>
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5,
       int s6, int s7)
    {
      return a.engine()(s1, s2, s3, s4, s5, s6, s7);
    }
  inline static
  ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
    int s4, int s5, int s6, int s7)
    {
      return a.engine().read(s1, s2, s3, s4, s5, s6, s7);
    }
};
template <class Subject, class Domain>
struct ReverseSliceView;
template <int SliceDim, class T, class EngineTag, int Dim>
struct ReverseSliceView<Array<SliceDim, T, EngineTag>, SliceInterval<Dim, SliceDim> >
{
  typedef Array<SliceDim, T, EngineTag> Subject_t;
  typedef SliceInterval<Dim, SliceDim> Domain_t;
  typedef typename NewEngine<typename Subject_t::Engine_t, Domain_t>::Type_t NewEngine_t;
  typedef Array<Dim, T, typename NewEngine_t::Tag_t> Type_t;
  inline static
  Type_t make(const Subject_t &a, const SliceInterval<Dim, SliceDim>& dom,
       const Interval<Dim>& totalDom)
  {
    return Type_t(NewEngine_t(a.engine(), dom, totalDom));
  }
};
template<int Dim, class T, class EngineTag>
struct Patch<Array<Dim, T, EngineTag> >
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t OldEngine_t;
  typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
  typedef Array<Dim, T, typename Engine_t::Tag_t> Type_t;
  inline static
  Type_t make(const Subject_t &subject, int i)
    {
      return Type_t(engineFunctor(subject.engine(), EnginePatch(i)));
    }
};
template<class Components, int Dim, class T, class EngineTag>
struct ComponentView<Components, Array<Dim, T, EngineTag> >
{
  typedef Array<Dim, T, EngineTag> Subject_t;
  typedef Engine<Dim, T, EngineTag> Engine_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename ComponentAccess<Element_t, Components>::Element_t NewT_t;
  typedef CompFwd<Engine_t, Components> NewEngineTag_t;
  typedef Array<Dim, NewT_t, NewEngineTag_t> Type_t;
  inline static
  Type_t make(const Subject_t &a, const Components &c)
    {
      return Type_t(a, ComponentWrapper<Components>(c));
    }
};
template<int Dim, class T = double,
  class EngineTag = Brick>
class Array
{
public:
  typedef Array<Dim, T, EngineTag> This_t;
  typedef Engine<Dim, T, EngineTag> Engine_t;
  typedef EngineTag EngineTag_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef typename Engine_t::Domain_t Domain_t;
  typedef typename Engine_t::Layout_t Layout_t;
  enum { dimensions = Engine_t::dimensions };
  enum { rank = Engine_t::dimensions };
  enum { hasRelations = false };
  Array() { }
  inline explicit Array(const Engine_t &modelEngine)
  : engine_m(modelEngine)
    { }
  template<int Dim2, class T2, class EngineTag2, class Initializer>
  inline Array(const Engine<Dim2, T2, EngineTag2> &engine,
    const Initializer &init)
  : engine_m(engine, init)
    { }
  template<int D1, class T1, class E1, int D2, class T2, class E2>
  inline Array(const Array<D1, T1, E1> &a1, const Array<D2, T2, E2> &a2)
  : engine_m(a1, a2)
    { }
  inline Array(const This_t &model)
  : engine_m(model.engine())
    { }
  template<int OtherDim, class OtherT, class OtherEngineTag>
  inline explicit Array(const Array<OtherDim, OtherT, OtherEngineTag> &model)
  : engine_m(model.engine())
    { }
  template<int OtherDim, class OtherT, class OtherEngineTag, class OtherDomain>
  inline Array(const Array<OtherDim, OtherT, OtherEngineTag> &model,
        const OtherDomain &domain)
  : engine_m(NewEngineEngine<Engine<OtherDim,OtherT,OtherEngineTag>,
             OtherDomain>::apply(model.engine(),domain),
             NewEngineDomain<Engine<OtherDim,OtherT,OtherEngineTag>,
             OtherDomain>::apply(model.engine(),domain))
    { }
  template <class OtherT, class OtherEngineTag, class Components>
  Array(const Array<Dim, OtherT, OtherEngineTag> &a,
 const ComponentWrapper<Components>& c)
  : engine_m(a.engine(), c.components())
    { }
  template<class Sub1>
  explicit Array(const Sub1 &s1)
  : engine_m(NewDomain1<Sub1>::combine(s1))
    { }
  template<class Sub1, class Sub2>
  Array(const Sub1 &s1, const Sub2 &s2)
  : engine_m(NewDomain2<Sub1, Sub2>::combine(s1, s2))
    { }
  template<class Sub1, class Sub2, class Sub3>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
  : engine_m(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3))
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4)
  : engine_m(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
      combine(s1, s2, s3, s4))
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5)
  : engine_m(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
      combine(s1, s2, s3, s4, s5))
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5, const Sub6 &s6)
  : engine_m(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
      combine(s1, s2, s3, s4, s5, s6))
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5, const Sub6 &s6, const Sub7 &s7)
  : engine_m(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
      combine(s1, s2, s3, s4, s5, s6, s7))
    { }
  template<class Sub1>
  Array(const Sub1 &s1, const ModelElement<Element_t> &model)
  : engine_m(NewDomain1<Sub1>::combine(s1), model.element())
    { }
  template<class Sub1, class Sub2>
  Array(const Sub1 &s1, const Sub2 &s2,
        const ModelElement<Element_t> &model)
  : engine_m(NewDomain2<Sub1, Sub2>::combine(s1, s2), model.element())
    { }
  template<class Sub1, class Sub2, class Sub3>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
        const ModelElement<Element_t> &model)
  : engine_m(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3),
      model.element())
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const ModelElement<Element_t> &model)
  : engine_m(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
      combine(s1, s2, s3, s4), model.element())
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5, const ModelElement<Element_t> &model)
  : engine_m(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
      combine(s1, s2, s3, s4, s5), model.element())
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5, const Sub6 &s6, const ModelElement<Element_t> &model)
  : engine_m(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
      combine(s1, s2, s3, s4, s5, s6), model.element())
    { }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
        const Sub5 &s5, const Sub6 &s6, const Sub7 &s7,
        const ModelElement<Element_t> &model)
  : engine_m(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
      combine(s1, s2, s3, s4, s5, s6, s7), model.element())
    { }
  void initialize(const Engine_t &modelEngine)
    {
      engine_m = modelEngine;
    }
  template<int Dim2, class T2, class EngineTag2, class Initializer>
  void initialize(const Engine<Dim2, T2, EngineTag2> &engine,
    const Initializer &init)
    {
      engine_m = Engine_t(engine, init);
    }
  void initialize(const This_t &model)
    {
      engine_m = model.engine();
    }
  template<int OtherDim, class OtherT, class OtherEngineTag>
  void initialize(const Array<OtherDim, OtherT, OtherEngineTag> &model)
    {
      engine_m = Engine_t(model.engine());
    }
  template<int OtherDim, class OtherT, class OtherEngineTag, class OtherDomain>
  void initialize(const Array<OtherDim, OtherT, OtherEngineTag> &model,
    const OtherDomain &domain)
    {
      engine_m = Engine_t(
        NewEngineEngine<Engine<OtherDim,OtherT,OtherEngineTag>, OtherDomain>::
        apply(model.engine(),domain),
        NewEngineDomain<Engine<OtherDim,OtherT,OtherEngineTag>, OtherDomain>::
        apply(model.engine(),domain));
    }
  template<class Sub1>
  void initialize(const Sub1 &s1)
    {
      engine_m = Engine_t(NewDomain1<Sub1>::combine(s1));
    }
  template<class Sub1, class Sub2>
  void initialize(const Sub1 &s1, const Sub2 &s2)
    {
      engine_m = Engine_t(NewDomain2<Sub1, Sub2>::combine(s1, s2));
    }
  template<class Sub1, class Sub2, class Sub3>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
    {
      engine_m = Engine_t(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3));
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4)
    {
      engine_m = Engine_t(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
                          combine(s1, s2, s3, s4));
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
                  const Sub5 &s5)
    {
      engine_m = Engine_t(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
                          combine(s1, s2, s3, s4, s5));
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
                  const Sub5 &s5, const Sub6 &s6)
    {
      engine_m = Engine_t(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
                          combine(s1, s2, s3, s4, s5, s6));
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7)
    {
      engine_m =
        Engine_t(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
        combine(s1, s2, s3, s4, s5, s6, s7));
    }
  template<class Sub1>
  void initialize(const Sub1 &s1, const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain1<Sub1>::combine(s1), model.element());
    }
  template<class Sub1, class Sub2>
  void initialize(const Sub1 &s1, const Sub2 &s2,
    const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain2<Sub1, Sub2>::combine(s1, s2),
        model.element());
    }
  template<class Sub1, class Sub2, class Sub3>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3),
        model.element());
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
    const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
        combine(s1, s2, s3, s4), model.element());
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
    const Sub5 &s5, const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
        combine(s1, s2, s3, s4, s5), model.element());
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
    const Sub5 &s5, const Sub6 &s6, const ModelElement<Element_t> &model)
    {
      engine_m = Engine_t(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
        combine(s1, s2, s3, s4, s5, s6), model.element());
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7,
    const ModelElement<Element_t> &model)
    {
      engine_m =
        Engine_t(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
        combine(s1, s2, s3, s4, s5, s6, s7), model.element());
    }
  ~Array()
    { }
  inline typename Patch<This_t>::Type_t
  patchLocal(int i) const
    {
      return Patch<This_t>::make(*this, i);
    }
  inline int
  numPatchesLocal() const
    {
      return engineFunctor(engine_m, EngineNumPatches());
    }
  inline const Domain_t& domain() const
    {
      return engine_m.domain();
    }
  inline Domain_t physicalDomain() const
    {
      return engine_m.layout().innerDomain();
    }
  inline const Domain_t& totalDomain() const
    {
      return engine_m.domain();
    }
  inline typename Engine_t::Layout_t layout() const
    {
      return engine_m.layout();
    }
  typename View0<This_t>::ReadType_t
  read() const
    {
      typedef View0<This_t> Ret_t;
      return Ret_t::makeRead(*this);
    }
  template<class Sub1>
  inline typename View1<This_t, Sub1>::ReadType_t
  read(const Sub1 &s1) const
    {
      typedef View1<This_t, Sub1> Ret_t;
      return Ret_t::makeRead(*this, s1);
    }
  template<class Sub1, class Sub2>
  inline typename View2<This_t, Sub1, Sub2>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2) const
    {
      typedef View2<This_t, Sub1, Sub2> Ret_t;
      return Ret_t::makeRead(*this, s1, s2);
    }
  template<class Sub1, class Sub2, class Sub3>
  inline typename View3<This_t, Sub1, Sub2, Sub3>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
    {
      typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  inline typename View4<This_t, Sub1, Sub2, Sub3, Sub4>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4) const
    {
      typedef View4<This_t, Sub1, Sub2, Sub3, Sub4> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3, s4);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  inline typename View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5) const
    {
      typedef View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3, s4, s5);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  inline typename View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6) const
    {
      typedef View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  inline typename
    View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7) const
    {
      typedef View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6, s7);
    }
  typename View0<This_t>::Type_t
  operator()() const
    {
      typedef View0<This_t> Ret_t;
      return Ret_t::make(*this);
    }
  template<class Sub1>
  inline typename View1<This_t,Sub1>::Type_t
  operator()(const Sub1 &s1) const
    {
      typedef View1<This_t, Sub1> Ret_t;
      return Ret_t::make(*this, s1);
    }
  template<class Sub1, class Sub2>
  inline typename View2<This_t, Sub1, Sub2>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2) const
    {
      typedef View2<This_t, Sub1, Sub2> Ret_t;
      return Ret_t::make(*this, s1, s2);
    }
  template<class Sub1, class Sub2, class Sub3>
  inline typename View3<This_t, Sub1, Sub2, Sub3>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
    {
      typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
      return Ret_t::make(*this, s1, s2, s3);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4>
  inline typename View4<This_t, Sub1, Sub2, Sub3, Sub4>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4) const
    {
      typedef View4<This_t, Sub1, Sub2, Sub3, Sub4> Ret_t;
      return Ret_t::make(*this, s1, s2, s3, s4);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
  inline typename View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5) const
    {
      typedef View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5> Ret_t;
      return Ret_t::make(*this, s1, s2, s3, s4, s5);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6>
  inline typename
    View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6) const
    {
      typedef View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> Ret_t;
      return Ret_t::make(*this, s1, s2, s3, s4, s5, s6);
    }
  template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
    class Sub6, class Sub7>
  inline typename
    View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
    const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7) const
    {
      typedef View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7> Ret_t;
      return Ret_t::make(*this, s1, s2, s3, s4, s5, s6, s7);
    }
  inline typename ComponentView<Loc<1>, This_t>::Type_t
  comp(int i1) const
    {
      return ComponentView<Loc<1>, This_t>::make(*this, Loc<1>(i1));
    }
  inline typename ComponentView<Loc<2>, This_t>::Type_t
  comp(int i1, int i2) const
    {
      return ComponentView<Loc<2>, This_t>::make(*this, Loc<2>(i1, i2));
    }
  inline typename ComponentView<Loc<3>, This_t>::Type_t
  comp(int i1, int i2, int i3) const
    {
      return ComponentView<Loc<3>, This_t>::make(*this, Loc<3>(i1, i2, i3));
    }
  inline typename ComponentView<Loc<4>, This_t>::Type_t
  comp(int i1, int i2, int i3, int i4) const
    {
      return ComponentView<Loc<4>, This_t>::make(*this,
        Loc<4>(i1, i2, i3, i4));
    }
  inline typename ComponentView<Loc<5>, This_t>::Type_t
  comp(int i1, int i2, int i3, int i4, int i5) const
    {
      return ComponentView<Loc<5>, This_t>::make(*this,
        Loc<5>(i1, i2, i3, i4, i5));
    }
  inline typename ComponentView<Loc<6>, This_t>::Type_t
  comp(int i1, int i2, int i3, int i4, int i5, int i6) const
    {
      return ComponentView<Loc<6>, This_t>::make(*this,
        Loc<6>(i1, i2, i3, i4, i5, i6));
    }
  inline typename ComponentView<Loc<7>, This_t>::Type_t
  comp(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
    {
      return ComponentView<Loc<7>, This_t>::make(*this,
        Loc<7>(i1, i2, i3, i4, i5, i6, i7));
    }
  template<class Components>
  inline typename ComponentView<Components, This_t>::Type_t
  comp(const Components &components) const
    {
      return ComponentView<Components, This_t>::make(*this, components);
    }
  inline void makeOwnCopy()
    { engine_m.makeOwnCopy(); }
  inline int first(int d) const
  {
      return engine_m.first(d);
    }
  inline int last(int d) const
    {
      return engine_m.domain()[d].last();
    }
  inline int length(int d) const
    {
      return engine_m.domain()[d].length();
    }
  inline Loc<Dim> firsts() const
    {
      return engine_m.domain().firsts();
    }
  inline Loc<Dim> lasts() const
    {
      return engine_m.domain().lasts();
    }
  inline Loc<Dim> lengths() const
    {
      return engine_m.domain().lengths();
    }
  inline long size() const
    {
      return engine_m.domain().size();
    }
  This_t &operator=(const Array<Dim, T, EngineTag> &rhs)
    {
      assign(*this, rhs, OpAssign());
      return *this;
    }
  const This_t &operator=(const Array<Dim, T, EngineTag> &rhs) const
    {
      return assign(*this, rhs, OpAssign());
    }
  template<class T1>
  const This_t &operator=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpAssign());
    }
  template<class T1>
  const This_t &operator+=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpAddAssign());
    }
  template<class T1>
  const This_t &operator-=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpSubtractAssign());
    }
  template<class T1>
  const This_t &operator*=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpMultiplyAssign());
    }
  template<class T1>
  const This_t &operator/=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpDivideAssign());
    }
  template<class T1>
  const This_t &operator%=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpModAssign());
    }
  template<class T1>
  const This_t &operator|=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseOrAssign());
    }
  template<class T1>
  const This_t &operator&=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseAndAssign());
    }
  template<class T1>
  const This_t &operator^=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseXorAssign());
    }
  template<class T1>
  const This_t &operator<<=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpLeftShiftAssign());
    }
  template<class T1>
  const This_t &operator>>=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpRightShiftAssign());
    }
  inline Engine_t &engine()
    { return engine_m; }
  inline const Engine_t &engine() const
    { return engine_m; }
private:
  Engine_t engine_m;
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, DomainFunctorTag>
{
  typedef typename Engine<Dim, T, EngineTag>::Domain_t Type_t;
  static Type_t apply(const Array<Dim, T, EngineTag> &a,
        const DomainFunctorTag &)
  {
    return a.domain();
  }
};
template<int Dim, class T, class EngineTag, class Domain>
struct LeafFunctor<Array<Dim, T, EngineTag>, ViewFunctorTag<Domain> >
{
  typedef typename View1<Array<Dim, T, EngineTag>, Domain>::Type_t Type_t;
  inline static Type_t apply(const Array<Dim, T, EngineTag> &a,
    const ViewFunctorTag<Domain> &t)
    {
      typedef View1<Array<Dim, T, EngineTag>, Domain> Ret_t;
      return Ret_t::make(a, t.domain_m + a.firsts());
    }
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, EvalLeaf<Dim> >
{
  typedef typename Array<Dim, T, EngineTag>::Element_t Type_t;
  inline static
  Type_t apply(const Array<Dim, T, EngineTag> &a, const EvalLeaf<Dim> &t)
    {
      return t.eval(a.engine());
    }
};
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Array<Dim, T, E>, EngineView<Tag> >
{
  typedef LeafFunctor<Engine<Dim, T, E>, EngineView<Tag> > LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t NewEngine_t;
  typedef typename NewEngine_t::Tag_t NewTag_t;
  typedef Array<Dim, T, NewTag_t> Type_t;
  inline static
  Type_t apply(const Array<Dim, T, E> &array,
        const EngineView<Tag> &tag)
  {
    return Type_t(LeafFunctor_t::apply(array.engine(), tag));
  }
};
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Array<Dim, T, E>, ExpressionApply<Tag> >
{
  typedef LeafFunctor<Engine<Dim, T, E>, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Array<Dim, T, E> &array,
        const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(array.engine(), tag);
  }
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, ConformTag<Dim> >
{
  typedef bool Type_t;
  static Type_t apply(const Array<Dim, T, EngineTag> &array,
    const ConformTag<Dim> &ct)
    {
      return conforms(array.domain(), ct);
    }
};
template<int Dim1, int Dim2, class T, class EngineTag>
struct LeafFunctor<Array<Dim1, T, EngineTag>, ConformTag<Dim2> >
{
  typedef bool Type_t;
  static Type_t apply(const Array<Dim1, T, EngineTag> &,
    const ConformTag<Dim2> &)
    {
      return false;
    }
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, NotifyPreReadTag>
{
  typedef bool Type_t;
  static Type_t apply(const Array<Dim, T, EngineTag> &a,
    const NotifyPreReadTag &)
    {
      return true;
    }
};
template<int Dim, class T, class E, class Tag>
struct LeafFunctor<Array<Dim, T, E>, EngineFunctorTag<Tag> >
{
  typedef typename Array<Dim,T,E>::Engine_t Engine_t;
  typedef typename EngineFunctor<Engine_t,Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Array<Dim, T, E> &array, const EngineFunctorTag<Tag> &tag)
  {
    return EngineFunctor<Engine_t,Tag>::apply(array.engine(), tag.tag());
  }
};
template<int Dim, class T, class E, class Tag>
struct EngineFunctor<Array<Dim, T, E>, Tag>
{
  typedef typename EngineFunctor<Engine<Dim, T, E>, Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Array<Dim, T, E> &array,
        const Tag &tag)
  {
    return engineFunctor(array.engine(), tag);
  }
};
template <int Dim, class T, class EngineTag>
std::ostream &operator<<(std::ostream &o,
                         const Array<Dim, T, EngineTag> &ca)
{
  Pooma::blockAndEvaluate();
  PrintArray().print(o, ca);
  return o;
}
template <int Dim, class T, class EngineTag>
std::fstream &operator<<(std::fstream &f,
                         const Array<Dim, T, EngineTag> &ca)
{
  Pooma::blockAndEvaluate();
  PrintArray().print(f, ca);
  return f;
}
struct ExpressionIsArray { };
template<int Dim, class T, class EngineTag>
struct ExpressionTraits<Array<Dim, T, EngineTag> >
{
  typedef ExpressionIsArray Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsArray>
{
  typedef ExpressionIsArray Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsScalar>
{
  typedef ExpressionIsArray Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsArray>
{
  typedef ExpressionIsArray Type_t;
};
template<int Dim, class T, class EngineTag,
  int OtherDim, class OtherT, class OtherEngineTag, class Op>
inline const Array<Dim, T, EngineTag> &
assign(const Array<Dim, T, EngineTag> &lhs,
       const Array<OtherDim, OtherT, OtherEngineTag> &rhs,
       const Op &op)
{
  ;
  Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhs);
  return lhs;
}
template<int Dim, class T, class EngineTag, class T1, class Op>
inline const Array<Dim, T, EngineTag> &
assign(const Array<Dim, T, EngineTag> &lhs, const T1 &rhs, const Op &op)
{
  Array<Dim, T1, ConstantFunction> rhsExpr(lhs.domain());
  rhsExpr.engine().setConstant(rhs);
  Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhsExpr);
  return lhs;
}
template<class Tree>
struct ConvertWhereProxy<ExpressionIsArray, Tree>
{
  typedef MakeReturn<Tree> Make_t;
};
template<int Dim, class T, class EngineTag, class F, class B, class Op>
inline const Array<Dim, T, EngineTag> &
assign(const Array<Dim, T, EngineTag> &lhs,
       const WhereProxy<F,B> &rhs,
       const Op &op)
{
  assign(lhs, rhs.whereMask(), rhs.opMask(op));
  return lhs;
}
template<int Dim, class T, class EngineTag>
inline long
elementsCompressed(const Array<Dim, T, EngineTag> &a)
{
  return elementsCompressed(a.engine());
}
template<int Dim, class T, class EngineTag>
inline bool
compressed(const Array<Dim, T, EngineTag> &a)
{
  return compressed(a.engine());
}
template<int Dim, class T, class EngineTag>
inline void
compress(Array<Dim, T, EngineTag> &a)
{
  compress(a.engine());
}
template<int Dim, class T, class EngineTag>
inline void
uncompress(Array<Dim, T, EngineTag> &a)
{
  uncompress(a.engine());
}
template <int Dim, class T, class EngineTag>
struct ElementProperties< Array<Dim, T, EngineTag> >
  : public MakeOwnCopyProperties< Array<Dim, T, EngineTag> >
{ };
template <int Dim> class UniformGridLayout;
template <int Dim, int Dim2> class UniformGridLayoutView;
struct UniformTag { };
template <int Dim>
struct MultiPatchLayoutTraits<UniformTag,Dim>
{
  typedef UniformGridLayout<Dim> Layout_t;
  template <int ViewDim>
  struct View
  {
    typedef UniformGridLayoutView<ViewDim,Dim> Layout_t;
  };
};
template <int Dim>
class UniformGridLayoutData
 : public LayoutBaseData<Dim>,
   public RefCounted,
   public Observable<UniformGridLayoutData<Dim> >
{
public:
  typedef Interval<Dim> Domain_t;
  typedef Interval<Dim> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef typename LayoutBaseData<Dim>::GCFillInfo GCFillInfo_t;
  typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  enum { dimensions = Dim };
  enum { repartitionEvent = 1 };
  enum { dynamic = false };
  UniformGridLayoutData();
  template <class Partitioner>
  UniformGridLayoutData(const Domain_t &gdom,
   const Partitioner &gpar,
   const ContextMapper<Dim> & cmap );
  void initialize(const Domain_t& idom,
    const List_t& nodes,
    const Loc<Dim>& blocks,
    bool hasIG, bool hasEG,
    const GuardLayers_t& ig,
    const GuardLayers_t& eg);
  ~UniformGridLayoutData()
  {
    typename List_t::iterator a;
    for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
      delete (*a);
  }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &d, OutIter o, const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesLocal(const OtherDomain &d,
     OutIter o,
     const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesRemote(const OtherDomain &d,
      OutIter o,
      const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAlloc(const OtherDomain &d, OutIter o,
                   const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAllocLocal(const OtherDomain &d, OutIter o,
   const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAllocRemote(const OtherDomain &d, OutIter o,
    const ConstructTag &ctag) const;
  friend class UniformGridLayout<Dim>;
  int globalID(const Loc<Dim> &loc) const;
  int globalID(int) const;
  int globalID(int,int) const;
  int globalID(int,int,int) const;
  int globalID(int,int,int,int) const;
  int globalID(int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int,int) const;
  template <class Partitioner>
  void partition(const Partitioner &, const ContextMapper<Dim>& cmap);
  template <class Partitioner>
  bool repartition(const Partitioner &,const ContextMapper<Dim>&);
  void calcGCFillList();
  int blockstride_m[Dim];
  int blocksizes_m[Dim];
  Interval<Dim> allDomain_m;
};
template <int Dim>
class UniformGridLayout : public LayoutBase<Dim,UniformGridLayoutData<Dim> >,
                          public Observable<UniformGridLayout<Dim> >,
                          public Observer<UniformGridLayoutData<Dim> >
{
public:
  typedef UniformGridLayoutData<Dim> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef UniformGridLayout<Dim> This_t;
  typedef Observable<This_t> Observable_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
  typedef typename
    std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  enum { dimensions = Dim };
  enum { repartitionEvent = LayoutData_t::repartitionEvent };
  enum { dynamic = false };
  UniformGridLayout();
  UniformGridLayout(const Domain_t &,
      const DistributedTag &);
  UniformGridLayout(const Domain_t &,
                    const GuardLayers_t &,
      const DistributedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
      const DistributedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
                    const GuardLayers_t &,
      const DistributedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
                    const GuardLayers_t &,
                    const GuardLayers_t &,
      const DistributedTag &);
  UniformGridLayout(const Domain_t &,
      const ReplicatedTag &);
  UniformGridLayout(const Domain_t &,
                    const GuardLayers_t &,
      const ReplicatedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
      const ReplicatedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
                    const GuardLayers_t &,
      const ReplicatedTag &);
  UniformGridLayout(const Domain_t &,
                    const Loc<Dim> &,
                    const GuardLayers_t &,
                    const GuardLayers_t &,
      const ReplicatedTag &);
  template <class Partitioner>
  UniformGridLayout(const Domain_t &,
      const Partitioner &,
      const ContextMapper<Dim> & );
  template <class Partitioner>
  UniformGridLayout(const Domain_t &,
                    const Partitioner &,
      const DistributedTag &);
  template <class Partitioner>
  UniformGridLayout(const Domain_t &,
                    const Partitioner &,
      const ReplicatedTag &);
  UniformGridLayout(const This_t &);
  This_t &operator=(const This_t &);
  inline ~UniformGridLayout()
  {
    this->pdata_m->detach(*this);
  }
  void initialize(const Domain_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const DistributedTag & );
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const ReplicatedTag & );
  void initialize(const Domain_t &,
                  const Loc<Dim> &,
                  const GuardLayers_t &,
                  const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
                  const Loc<Dim> &,
                  const GuardLayers_t &,
                  const GuardLayers_t &,
    const ReplicatedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const DistributedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const ReplicatedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const ContextMapper<Dim> &);
  void initialize(const Domain_t& idom,
    const List_t& nodes,
    const Loc<Dim>& blocks,
    bool hasIG, bool hasEG,
    const GuardLayers_t& ig,
    const GuardLayers_t& eg);
  virtual void notify(LayoutData_t &d, const ObserverEvent &event)
  {
    ;
    Observable_t::notify(event);
  }
  template <class Ostream>
  void print(Ostream &ostr) const;
  template <int Dim1, int Dim2>
  friend class UniformGridLayoutView;
  friend class UniformGridLayoutData<Dim>;
};
template <int Dim, int Dim2>
class UniformGridLayoutViewData
  : public LayoutBaseViewData<Dim, Dim2, UniformGridLayout<Dim2> >,
    public RefCounted
{
public:
  typedef UniformGridLayout<Dim2> Layout_t;
  typedef UniformGridLayoutView<Dim, Dim2> ViewLayout_t;
  typedef LayoutBaseViewData<Dim,Dim2,Layout_t> Base_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim2> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef typename Layout_t::Domain_t AllocatedDomain_t;
  typedef ViewIndexer<Dim,Dim2> Indexer_t;
  typedef Node<Domain_t,AllocatedDomain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  enum { dim = Dim };
  enum { dim2 = Dim2};
  UniformGridLayoutViewData() { };
  template <class DT>
  inline
  UniformGridLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(layout,dom)
  {
  }
  template <class DT>
  inline
  UniformGridLayoutViewData(const Layout_t &layout, const SliceDomain<DT> &dom)
  :LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(layout,dom)
  {
  }
  template <class DT>
  UniformGridLayoutViewData(const ViewLayout_t &layout,
                            const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(
           layout.pdata_m->layout_m,
           layout,
           layout.pdata_m->indexer_m,
           dom,
           layout.internalGuards(),
           layout.externalGuards())
  {
  }
  template <int OrigDim, class DT>
  UniformGridLayoutViewData(const UniformGridLayoutView<OrigDim,Dim2> &layout,
                            const SliceDomain<DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(
        layout.pdata_m->layout_m,
        layout,
        Indexer_t(layout.pdata_m->indexer_m,dom),
        dom)
  {
  }
  ~UniformGridLayoutViewData()
  {
    typename List_t::iterator a;
    for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
      delete (*a);
  }
};
template <int Dim, int Dim2>
class UniformGridLayoutView
  : public LayoutBaseView<Dim, Dim2, UniformGridLayoutViewData<Dim,Dim2> >
{
public:
  enum { dimensions = Dim };
  enum { dim = Dim };
  enum { dim2 = Dim2};
  typedef UniformGridLayoutViewData<Dim, Dim2> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Layout_t Layout_t;
  typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef typename LayoutData_t::Indexer_t Indexer_t;
  typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
  typedef UniformGridLayoutView<Dim, Dim2> This_t;
  typedef UniformGridLayoutView<Dim, Dim2> ViewLayout_t;
  typedef LayoutBaseView<Dim,Dim2,LayoutData_t> Base_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  UniformGridLayoutView()
  : Base_t(new LayoutData_t())
  { }
  template <class DT>
  UniformGridLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
  : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
    (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  UniformGridLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
  : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
    (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  UniformGridLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
    (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <int OldViewDim, class DT>
  UniformGridLayoutView(const UniformGridLayoutView<OldViewDim, Dim2> &layout,
                        const SliceDomain<DT> &dom)
  : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
    (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  inline UniformGridLayoutView(const This_t &model)
    : LayoutBaseView<Dim,
                     Dim2,
                     UniformGridLayoutViewData<Dim,Dim2> >(model.pdata_m)
  { }
  inline This_t &operator=(const This_t &model)
  {
    if (this != &model)
      {
        this->pdata_m = model.pdata_m;
      }
    return *this;
  }
  inline ~UniformGridLayoutView()
  { }
  template <class Ostream>
  void print(Ostream &ostr) const;
  template <int OtherDim, int OtherDim2>
  friend class UniformGridLayoutView;
  template <int OtherDim, int OtherDim2>
  friend class UniformGridLayoutViewData;
};
template <int Dim>
struct NewDomain1<UniformGridLayout<Dim> >
{
  typedef UniformGridLayout<Dim> &Type_t;
  inline static Type_t combine(const UniformGridLayout<Dim> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim, int Dim2>
struct NewDomain1<UniformGridLayoutView<Dim, Dim2> >
{
  typedef UniformGridLayoutView<Dim, Dim2> &Type_t;
  inline static Type_t combine(const UniformGridLayoutView<Dim, Dim2> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim>
std::ostream &operator<<(std::ostream &ostr,
                         const UniformGridLayout<Dim> &layout)
{
  layout.print(ostr);
  return ostr;
}
template <int Dim, int Dim2>
std::ostream &operator<<(std::ostream &ostr,
                         const UniformGridLayoutView<Dim, Dim2> &layout)
{
  layout.print(ostr);
  return ostr;
}
template <int Dim>
inline UniformGridLayoutData<Dim>::
UniformGridLayoutData()
  : Observable<UniformGridLayoutData>(*this)
{
  for (int i = 0; i < Dim; ++i)
    blockstride_m[i] = blocksizes_m[i] = 0;
}
template <int Dim>
template <class Partitioner>
UniformGridLayoutData<Dim>::
UniformGridLayoutData(const Domain_t &gdom,
        const Partitioner &gpar,
        const ContextMapper<Dim> & cmap )
  : LayoutBaseData<Dim>(false,
   false,
   GuardLayers_t(0),
   GuardLayers_t(0),
   gdom,
   gdom),
    Observable<UniformGridLayoutData>(*this)
{
  if (gpar.hasInternalGuards() && gpar.maxSize() > 1)
    {
      this->hasInternalGuards_m = true;
      this->internalGuards_m = gpar.internalGuards();
    }
  if (gpar.hasExternalGuards())
    {
      this->hasExternalGuards_m = true;
      this->externalGuards_m = gpar.externalGuards();
      GuardLayers<Dim>::addGuardLayers(this->domain_m,this->externalGuards_m);
    }
  partition(gpar,cmap);
}
template <int Dim>
template <class Partitioner>
void UniformGridLayoutData<Dim>::partition(const Partitioner &gpar,
        const ContextMapper<Dim> &cmap)
{
  int i;
  PoomaCTAssert<(Partitioner::uniform)>::test();
  ;
  ;
  ;
  ;
  ;
  this->blocks_m = gpar.blocks();
  blockstride_m[0] = 1;
  int blocks[Dim];
  for (i = 0; i < Dim; ++i)
  {
    this->firsti_m[i] = this->innerdomain_m[i].first();
    this->firste_m[i] = this->domain_m[i].first();
    blocks[i] = gpar.blocks()[i].first();
    allDomain_m[i] = Interval<1>(blocks[i]);
    blocksizes_m[i] = this->innerdomain_m[i].length() / blocks[i];
    if (i > 0)
      blockstride_m[i] = blockstride_m[i-1] * blocks[i-1];
  }
  gpar.partition(this->innerdomain_m, this->all_m, cmap);
  typename List_t::const_iterator start = this->all_m.begin();
  typename List_t::const_iterator end = this->all_m.end();
  for ( ; start!=end ; ++start)
    {
      if ( (*start)->context() == Pooma::context()
    || (*start)->context() == -1 )
 {
   (*start)->localID() = this->local_m.size();
   this->local_m.push_back(*start);
 }
      else
 this->remote_m.push_back(*start);
    }
  if (this->hasInternalGuards_m)
    {
      this->gcFillList_m.clear();
      calcGCFillList();
    }
}
template<int Dim>
void UniformGridLayoutData<Dim>::initialize(const Domain_t& idom,
     const List_t& nodes,
     const Loc<Dim>& ublocks,
     bool hasIG, bool hasEG,
     const GuardLayers_t& ig,
     const GuardLayers_t& eg)
{
  int i;
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  this->domain_m = idom;
  this->innerdomain_m = idom;
  this->hasInternalGuards_m = hasIG;
  if (this->hasInternalGuards_m)
    {
      this->internalGuards_m = ig;
    }
  this->hasExternalGuards_m = (hasEG && ! this->domain_m.empty());
  if (this->hasExternalGuards_m)
    {
      this->externalGuards_m = eg;
      GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
    }
  this->blocks_m = ublocks;
  blockstride_m[0] = 1;
  int blocks[Dim];
  for (i = 0; i < Dim; ++i)
  {
    this->firsti_m[i] = this->innerdomain_m[i].first();
    this->firste_m[i] = this->domain_m[i].first();
    blocks[i] = ublocks[i].first();
    allDomain_m[i] = Interval<1>(blocks[i]);
    blocksizes_m[i] = this->innerdomain_m[i].length() / blocks[i];
    if (i > 0)
      blockstride_m[i] = blockstride_m[i-1] * blocks[i-1];
  }
  this->all_m= nodes;
  typename List_t::iterator start = this->all_m.begin();
  typename List_t::iterator end = this->all_m.end();
  for ( ; start!=end ;++start )
    {
      if( (*start)->context() == Pooma::context() ||
   (*start)->context() == -1 )
 this->local_m.push_back(*start);
      else
 this->remote_m.push_back(*start);
    }
  if (this->hasInternalGuards_m)
    {
      this->gcFillList_m.clear();
      calcGCFillList();
    }
}
template <int Dim>
void UniformGridLayoutData<Dim>::calcGCFillList()
  {
    int d, p;
    int numPatches = this->all_m.size();
    this->gcFillList_m.reserve(2*Dim*this->local_m.size());
    for (d = 0; d < Dim; ++d)
      {
        if (this->internalGuards_m.lower(d) > 0)
          {
            typename Interval<Dim>::iterator pos = allDomain_m.begin();
            for (p = 0; p < numPatches; ++p, ++pos)
              {
                if ( (*pos)[d].first() == allDomain_m[d].last() ) continue;
                int sourceID = p;
                int destID = p + blockstride_m[d];
                ;
                ;
                Domain_t gcdom(this->all_m[p]->allocated());
                int max = this->all_m[p]->domain()[d].last();
                int min = max - this->internalGuards_m.lower(d) + 1;
                gcdom[d] = Interval<1>(min,max);
   if (
      this->all_m[sourceID]->context() == -1 ||
      this->all_m[sourceID]->context() == Pooma::context() ||
       this->all_m[destID]->context() == Pooma::context()
      )
                this->gcFillList_m.push_back(GCFillInfo_t(gcdom,sourceID,destID,d*2));
              }
          }
        if (this->internalGuards_m.upper(d) > 0)
          {
            typename Interval<Dim>::iterator pos = allDomain_m.begin();
            for (p = 0; p < numPatches; ++p, ++pos)
              {
                if ( (*pos)[d].first() == allDomain_m[d].first() ) continue;
                int sourceID = p;
                int destID = p - blockstride_m[d];
                ;
                Domain_t gcdom(this->all_m[p]->allocated());
                int min = this->all_m[p]->domain()[d].first();
                int max = min + this->internalGuards_m.upper(d) - 1;
                gcdom[d] = Interval<1>(min,max);
   if (
      this->all_m[sourceID]->context() == -1 ||
      this->all_m[sourceID]->context() == Pooma::context() ||
       this->all_m[destID]->context() == Pooma::context()
      )
    this->gcFillList_m.push_back(GCFillInfo_t(gcdom,sourceID,destID,d*2+1));
              }
          }
      }
  }
template <int Dim>
template <class Partitioner>
bool UniformGridLayoutData<Dim>::
repartition(const Partitioner &p,
     const ContextMapper<Dim>& cmap)
{
  ;
  for (int i = 0; i < this->all_m.size(); ++i)
    delete this->all_m[i];
  this->all_m.clear();
  this->local_m.clear();
  this->remote_m.clear();
  partition(p,cmap);
  if (this->hasInternalGuards_m)
    {
      this->gcFillList_m.clear();
      calcGCFillList();
    }
  this->notify(repartitionEvent);
  return true;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touches(const OtherDomain &d, OutIter o,
     const ConstructTag &ctag) const
{
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->all_m[indx]->domain());
      ;
      *o = touchesConstruct(outDomain,
       this->all_m[indx]->allocated(),
       this->all_m[indx]->affinity(),
       this->all_m[indx]->context(),
       this->all_m[indx]->globalID(),
       this->all_m[indx]->localID(),
       ctag);
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touchesLocal(const OtherDomain &d,
          OutIter o,
          const ConstructTag &ctag) const
{
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->local_m[indx]->domain());
      ;
      *o = touchesConstruct(outDomain,
       this->local_m[indx]->allocated(),
       this->local_m[indx]->affinity(),
       this->local_m[indx]->context(),
       this->local_m[indx]->globalID(),
       this->local_m[indx]->localID(),
       ctag);
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touchesRemote(const OtherDomain &d,
           OutIter o,
           const ConstructTag &ctag) const
{
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->remote_m[indx]->domain());
      ;
      *o = touchesConstruct(outDomain,
       this->remote_m[indx]->allocated(),
       this->remote_m[indx]->affinity(),
       this->remote_m[indx]->context(),
       this->remote_m[indx]->globalID(),
       this->remote_m[indx]->localID(),
       ctag);
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touchesAlloc(const OtherDomain &d, OutIter o,
          const ConstructTag &ctag) const
{
  if (!this->hasInternalGuards_m) return touches(d,o,ctag);
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      if (a > 0) --a;
      if (b < allDomain_m[i].last()) ++b;
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->all_m[indx]->allocated());
      if (!outDomain.empty())
 {
   *o = touchesConstruct(outDomain,
    this->all_m[indx]->allocated(),
    this->all_m[indx]->affinity(),
    this->all_m[indx]->context(),
    this->all_m[indx]->globalID(),
    this->all_m[indx]->localID(),
    ctag);
 }
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touchesAllocLocal(const OtherDomain &d, OutIter o,
               const ConstructTag &ctag) const
{
  if (!this->hasInternalGuards_m) return touches(d,o,ctag);
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      if (a > 0) --a;
      if (b < allDomain_m[i].last()) ++b;
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->local_m[indx]->allocated());
      if (!outDomain.empty())
 {
   *o = touchesConstruct(outDomain,
    this->local_m[indx]->allocated(),
    this->local_m[indx]->affinity(),
    this->local_m[indx]->context(),
    this->local_m[indx]->globalID(),
    this->local_m[indx]->localID(),
    ctag);
 }
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int UniformGridLayoutData<Dim>::touchesAllocRemote(const OtherDomain &d, OutIter o,
                const ConstructTag &ctag) const
{
  if (!this->hasInternalGuards_m) return touches(d,o,ctag);
  int i, count = 0;
  ;
  ;
  Interval<Dim> box = Pooma::NoInit();
  for (i = 0; i < Dim; ++i)
    {
      int a, b;
      if (!this->hasExternalGuards_m)
 {
   a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
   b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
 }
      else
 {
   a = b = 0;
   int pos = d[i].min();
   int last = this->innerdomain_m[i].last();
   int del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       a = del / blocksizes_m[i];
     else
       a = allDomain_m[i].last();
   pos = d[i].max();
   del = pos - this->firsti_m[i];
   if (del >= 0)
     if (pos <= last)
       b = del / blocksizes_m[i];
     else
       b = allDomain_m[i].last();
 }
      if (a > 0) --a;
      if (b < allDomain_m[i].last()) ++b;
      box[i] = Interval<1>(a, b);
    }
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  typename Interval<Dim>::const_iterator boxiter = box.begin();
  while (boxiter != box.end())
    {
      int indx = (*boxiter)[0].first();
      for (i = 1; i < Dim; ++i)
 indx += blockstride_m[i] * (*boxiter)[i].first();
      ;
      outDomain = intersect(d, this->remote_m[indx]->allocated());
      if (!outDomain.empty())
 {
   *o = touchesConstruct(outDomain,
    this->remote_m[indx]->allocated(),
    this->remote_m[indx]->affinity(),
    this->remote_m[indx]->context(),
    this->remote_m[indx]->globalID(),
    this->remote_m[indx]->localID(),
    ctag);
 }
      ++o;
      ++count;
      ++boxiter;
    }
  return count;
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout()
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t()),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const DistributedTag& t)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(),
        DistributedMapper<Dim>(UniformGridPartition<Dim>()))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const ReplicatedTag & t)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(),
        LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const GuardLayers_t &gcs,
    const DistributedTag &)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(gcs),
        DistributedMapper<Dim>(UniformGridPartition<Dim>(gcs)))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const GuardLayers_t &gcs,
    const ReplicatedTag & )
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(gcs),
        LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const Loc<Dim> &blocks,
    const DistributedTag & )
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(blocks),
        DistributedMapper<Dim>(
          UniformGridPartition<Dim>(blocks)))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const Loc<Dim> &blocks,
    const ReplicatedTag & t)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(blocks),
        LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
                  const Loc<Dim> &blocks,
                  const GuardLayers_t &igcs,
    const DistributedTag &)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
   (new LayoutData_t(gdom,
       UniformGridPartition<Dim>(blocks,igcs),
       DistributedMapper<Dim>(
        UniformGridPartition<Dim>(blocks,igcs)))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
                  const Loc<Dim> &blocks,
                  const GuardLayers_t &igcs,
    const ReplicatedTag &)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
     (new LayoutData_t(gdom,
         UniformGridPartition<Dim>(blocks,igcs),
         LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
                  const Loc<Dim> &blocks,
                  const GuardLayers_t &igcs,
                  const GuardLayers_t &egcs,
    const DistributedTag &)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(blocks,igcs,egcs),
        DistributedMapper<Dim>(
                       UniformGridPartition<Dim>(blocks,igcs,egcs)))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
                  const Loc<Dim> &blocks,
                  const GuardLayers_t &igcs,
                  const GuardLayers_t &egcs,
    const ReplicatedTag &t)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,
        UniformGridPartition<Dim>(blocks,igcs,egcs),
        LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const Partitioner &gpar,
    const DistributedTag & )
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
   (new LayoutData_t(gdom,gpar,DistributedMapper<Dim>(gpar))),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const Partitioner &gpar,
    const ReplicatedTag &)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
   (new LayoutData_t(gdom,gpar,LocalMapper<Dim>())),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
inline UniformGridLayout<Dim>::
UniformGridLayout(const Domain_t &gdom,
    const Partitioner &gpar,
    const ContextMapper<Dim> & cmap)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >
    (new LayoutData_t(gdom,gpar,cmap)),
  Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim>::
UniformGridLayout(const This_t &model)
: LayoutBase<Dim,UniformGridLayoutData<Dim> >(model.pdata_m),
  Observable<This_t>(*this)
{
   this->pdata_m->attach(*this);
}
template <int Dim>
inline UniformGridLayout<Dim> & UniformGridLayout<Dim>::
operator=(const This_t &model)
{
  if (this != &model)
    {
      this->pdata_m->detach(*this);
      this->pdata_m = model.pdata_m;
      this->pdata_m->attach(*this);
    }
  return *this;
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const DistributedTag &)
{
  ;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(),
       DistributedMapper<Dim>(UniformGridPartition<Dim>()));
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(),
       LocalMapper<Dim>());
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const GuardLayers_t &gcs,
    const DistributedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(gcs),
       DistributedMapper<Dim>(UniformGridPartition<Dim>(gcs) ));
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const GuardLayers_t &gcs,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(gcs),
       LocalMapper<Dim>());
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const Loc<Dim> &blocks,
    const DistributedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks),
      DistributedMapper<Dim>(UniformGridPartition<Dim>(blocks)));
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
    const Loc<Dim> &blocks,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks),
       LocalMapper<Dim>());
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Loc<Dim> &blocks,
           const GuardLayers_t &gcs,
    const DistributedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks, gcs),
       DistributedMapper<Dim>(
         UniformGridPartition<Dim>(blocks, gcs)));
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Loc<Dim> &blocks,
           const GuardLayers_t &gcs,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks, gcs),
       LocalMapper<Dim>());
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Loc<Dim> &blocks,
           const GuardLayers_t &igcs,
           const GuardLayers_t &egcs,
    const DistributedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks, igcs, egcs),
       DistributedMapper<Dim>(
         UniformGridPartition<Dim>(blocks, igcs, egcs)));
}
template <int Dim>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Loc<Dim> &blocks,
           const GuardLayers_t &igcs,
           const GuardLayers_t &egcs,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->blocks_m = blocks;
  this->pdata_m->partition(UniformGridPartition<Dim>(blocks, igcs, egcs),
       LocalMapper<Dim>());
}
template <int Dim>
template <class Partitioner>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Partitioner &p,
    const DistributedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->blocks_m = p.blocks();
  this->pdata_m->partition(p,DistributedMapper<Dim>(p));
}
template <int Dim>
template <class Partitioner>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Partitioner &p,
    const ReplicatedTag &)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->blocks_m = p.blocks();
  this->pdata_m->partition(p,LocalMapper<Dim>());
}
template <int Dim>
template <class Partitioner>
inline void
UniformGridLayout<Dim>::
initialize(const Domain_t &gdom,
           const Partitioner &p,
    const ContextMapper<Dim> &cmap)
{
  ;
  this->pdata_m->innerdomain_m = gdom;
  this->pdata_m->domain_m = gdom;
  this->pdata_m->blocks_m = p.blocks();
  this->pdata_m->partition(p,cmap);
}
template <int Dim>
void UniformGridLayout<Dim>::initialize(const Domain_t& idom,
     const List_t& nodes,
     const Loc<Dim>& blocks,
     bool hasIG, bool hasEG,
     const GuardLayers_t& ig,
     const GuardLayers_t& eg)
{
  this->pdata_m->initialize(idom,nodes,blocks,hasIG,hasEG,ig,eg);
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
{
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (loc[0].first() - this->firsti_m[0]) / blocksizes_m[0];
      for (int d = 1; d < Dim; ++d)
        currloc += blockstride_m[d] *
          ((loc[d].first() - this->firsti_m[d]) / blocksizes_m[d]);
    }
  else
    {
      currloc = 0;
      for (int d = 0; d < Dim; ++d)
        {
          int l = loc[d].first();
          if (l >= this->firsti_m[d])
            {
              if (l <= this->innerdomain_m[d].last())
                {
                  currloc += blockstride_m[d] *
                    ((l - this->firsti_m[d]) / blocksizes_m[d]);
                }
              else
                {
                  currloc += blockstride_m[d] * allDomain_m[d].last();
                }
            }
        }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0) const
{
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
          currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
          currloc = allDomain_m[0].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1) const
{
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
          currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
          currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2) const
{
  ;
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
              + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
          currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
          currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
      if (i2 >= this->firsti_m[2]) {
        if (i2 <= this->innerdomain_m[2].last())
          currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
        else
          currloc += blockstride_m[2] * allDomain_m[2].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
{
  ;
  ;
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
              + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
              + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
           currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
           currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
      if (i2 >= this->firsti_m[2]) {
        if (i2 <= this->innerdomain_m[2].last())
          currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
        else
          currloc += blockstride_m[2] * allDomain_m[2].last();
      }
      if (i3 >= this->firsti_m[3]) {
        if (i3 <= this->innerdomain_m[3].last())
          currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
        else
          currloc += blockstride_m[3] * allDomain_m[3].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
                                     int i4) const
{
  ;
  ;
  ;
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
              + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
              + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
              + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
           currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
           currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
      if (i2 >= this->firsti_m[2]) {
        if (i2 <= this->innerdomain_m[2].last())
          currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
        else
          currloc += blockstride_m[2] * allDomain_m[2].last();
      }
      if (i3 >= this->firsti_m[3]) {
        if (i3 <= this->innerdomain_m[3].last())
          currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
        else
          currloc += blockstride_m[3] * allDomain_m[3].last();
      }
      if (i4 >= this->firsti_m[4]) {
        if (i4 <= this->innerdomain_m[4].last())
          currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
        else
          currloc += blockstride_m[4] * allDomain_m[4].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
                                     int i4, int i5) const
{
  ;
  ;
  ;
  ;
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
              + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
              + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
              + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4])
              + blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
           currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
           currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
      if (i2 >= this->firsti_m[2]) {
        if (i2 <= this->innerdomain_m[2].last())
          currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
        else
          currloc += blockstride_m[2] * allDomain_m[2].last();
      }
      if (i3 >= this->firsti_m[3]) {
        if (i3 <= this->innerdomain_m[3].last())
          currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
        else
          currloc += blockstride_m[3] * allDomain_m[3].last();
      }
      if (i4 >= this->firsti_m[4]) {
        if (i4 <= this->innerdomain_m[4].last())
          currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
        else
          currloc += blockstride_m[4] * allDomain_m[4].last();
      }
      if (i5 >= this->firsti_m[5]) {
        if (i5 <= this->innerdomain_m[5].last())
          currloc += blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
        else
          currloc += blockstride_m[5] * allDomain_m[5].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
inline int
UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
                                     int i4, int i5, int i6) const
{
  ;
  ;
  ;
  ;
  ;
  ;
  ;
  ;
  int currloc;
  if (!this->hasExternalGuards_m)
    {
      currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
              + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
              + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
              + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
              + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4])
              + blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5])
              + blockstride_m[6] * ((i6 - this->firsti_m[6]) / blocksizes_m[6]);
    }
  else
    {
      currloc = 0;
      if (i0 >= this->firsti_m[0]) {
        if (i0 <= this->innerdomain_m[0].last())
           currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
        else
           currloc = allDomain_m[0].last();
      }
      if (i1 >= this->firsti_m[1]) {
        if (i1 <= this->innerdomain_m[1].last())
          currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
        else
          currloc += blockstride_m[1] * allDomain_m[1].last();
      }
      if (i2 >= this->firsti_m[2]) {
        if (i2 <= this->innerdomain_m[2].last())
          currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
        else
          currloc += blockstride_m[2] * allDomain_m[2].last();
      }
      if (i3 >= this->firsti_m[3]) {
        if (i3 <= this->innerdomain_m[3].last())
          currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
        else
          currloc += blockstride_m[3] * allDomain_m[3].last();
      }
      if (i4 >= this->firsti_m[4]) {
        if (i4 <= this->innerdomain_m[4].last())
          currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
        else
          currloc += blockstride_m[4] * allDomain_m[4].last();
      }
      if (i5 >= this->firsti_m[5]) {
        if (i5 <= this->innerdomain_m[5].last())
          currloc += blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
        else
          currloc += blockstride_m[5] * allDomain_m[5].last();
      }
      if (i6 >= this->firsti_m[6]) {
        if (i6 <= this->innerdomain_m[6].last())
          currloc += blockstride_m[6] * ((i6 - this->firsti_m[6]) / blocksizes_m[6]);
        else
          currloc += blockstride_m[6] * allDomain_m[6].last();
      }
    }
  ;
  return currloc;
}
template <int Dim>
template <class Ostream>
void UniformGridLayout<Dim>::print(Ostream &ostr) const
{
  ostr << "UniformGridLayout " << this->ID() << " on global domain "
       << this->domain() << ":" << '\n';
  ostr << "   Total subdomains: " << this->sizeGlobal() << '\n';
  ostr << "   Local subdomains: " << this->sizeLocal() << '\n';
  ostr << "  Remote subdomains: " << this->sizeRemote() << '\n';
  ostr << "        Grid blocks: " << this->blocks() << '\n';
  typename UniformGridLayout<Dim>::const_iterator a;
  for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
    ostr << "  Global subdomain = " << *a << '\n';
  for (a = this->beginLocal(); a != this->endLocal(); ++a)
    ostr << "   Local subdomain = " << *a << '\n';
  for (a = this->beginRemote(); a != this->endRemote(); ++a)
    ostr << "  Remote subdomain = " << *a << '\n';
}
template <int Dim, int Dim2>
template <class Ostream>
void UniformGridLayoutView<Dim, Dim2>::print(Ostream &ostr) const
{
  ostr << "UniformGridLayoutView " << this->ID() << " on global domain "
       << this->domain() << ":" << '\n';
  ostr << "   Base ID:          " << this->baseID() << '\n';
  ostr << "   Base domain:      " << this->baseDomain() << '\n';
  ostr << "   Total subdomains: " << this->sizeGlobal() << '\n';
  ostr << "   Local subdomains: " << this->sizeLocal() << '\n';
  ostr << "  Remote subdomains: " << this->sizeRemote() << '\n';
  const_iterator a;
  for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
    ostr << "  Global subdomain = " << *a << '\n';
  for (a = this->beginLocal(); a != this->endLocal(); ++a)
    ostr << "   Local subdomain = " << *a << '\n';
  for (a = this->beginRemote(); a != this->endRemote(); ++a)
    ostr << "  Remote subdomain = " << *a << '\n';
}
template <class DT> class SliceDomain;
template<class Tag> struct Remote;
template <class LayoutTag, class PatchTag>
struct MultiPatch
{
  MultiPatch(){}
  ~MultiPatch(){}
};
template <class LayoutTag, class PatchTag, int Dim2>
struct MultiPatchView
{
  MultiPatchView(){}
  ~MultiPatchView(){}
};
template <int Dim, class T, class LayoutTag, class PatchTag>
class Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >;
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
class Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >;
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  Interval<Dim> >
{
  typedef Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  Range<Dim> >
{
  typedef Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  Node<Domain> >
{
  typedef typename
    NewEngine<Engine<Dim, T, PatchTag>, Node<Domain> >::Type_t Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
struct NewEngineEngine<
  Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> >,
  Node<Domain> >
{
  typedef Engine<Dim,T,PatchTag> &Type_t;
  static inline Engine<Dim,T,PatchTag> &
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &e,
 const Node<Domain> &i)
  {
    return e.globalPatch(i);
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
struct NewEngineDomain<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  Node<Domain> >
{
  typedef const Domain &Type_t;
  static inline const Domain &
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &,
 const Node<Domain> &i)
  {
    return i.domain();
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  INode<Dim> >
{
  typedef typename
    NewEngine<Engine<Dim, T, PatchTag>, Interval<Dim> >::Type_t Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngineEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  INode<Dim> >
{
  typedef Engine<Dim,T,PatchTag> &Type_t;
  static inline Engine<Dim,T,PatchTag> &
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &e,
 const INode<Dim> &i)
  {
    return e.globalPatch(i);
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngineDomain<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  INode<Dim> >
{
  typedef const Interval<Dim> &Type_t;
  static inline const Interval<Dim> &
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &,
 const INode<Dim> &i)
  {
    return i.domain();
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag, int SliceDim>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  SliceInterval<Dim,SliceDim> >
{
  typedef
    Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, int SliceDim>
struct NewEngine<
  Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  SliceRange<Dim,SliceDim> >
{
  typedef
    Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  Interval<Dim> >
{
  typedef
    Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  Range<Dim> >
{
  typedef
    Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, int Dim2, class Domain>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  Node<Domain> >
{
  typedef typename
    NewEngine<Engine<Dim2, T, PatchTag>, SliceRange<Dim2, Dim> >::Type_t
      Type_t;
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, class Domain>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> >,
  Node<Domain> >
{
  typedef typename
    NewEngine<Engine<Dim, T, PatchTag>, Range<Dim> >::Type_t
      Type_t;
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, int Dim2, class Domain>
struct NewEngineEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
  Node<Domain> >
{
  typedef typename NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
    Node<Domain> >::Type_t Type_t;
  static inline Type_t
  apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &e,
 const Node<Domain> &i)
  {
    return e.globalPatch(i);
  }
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, int Dim2, class Domain>
struct NewEngineDomain<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
  Node<Domain> >
{
  typedef EngineConstructTag Type_t;
  static inline EngineConstructTag
  apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &,
 const Node<Domain> &)
  {
    return EngineConstructTag();
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  INode<Dim> >
{
  typedef typename
    NewEngine<Engine<Dim2, T, PatchTag>, SliceRange<Dim2, Dim> >::Type_t
      Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> >,
  INode<Dim> >
{
  typedef typename
    NewEngine<Engine<Dim, T, PatchTag>, Range<Dim> >::Type_t
      Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
struct NewEngineEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
  INode<Dim> >
{
  typedef typename NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
    INode<Dim> >::Type_t Type_t;
  static inline Type_t
  apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &e,
 const INode<Dim> &i)
  {
    return e.globalPatch(i);
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
struct NewEngineDomain<
  Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
  INode<Dim> >
{
  typedef EngineConstructTag Type_t;
  static inline EngineConstructTag
  apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &,
 const INode<Dim> &)
  {
    return EngineConstructTag();
  }
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, int Dim2, int SliceDim>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  SliceInterval<Dim, SliceDim> >
{
  typedef
    Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
};
template <int Dim, class T,
          class LayoutTag, class PatchTag, int Dim2, int SliceDim>
struct NewEngine<
  Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
  SliceRange<Dim, SliceDim> >
{
  typedef
    Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
};
template <int Dim, class T, class LayoutTag, class PatchTag>
class Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > :
  public Observer<typename MultiPatchLayoutTraits<LayoutTag,Dim>::Layout_t>
{
public:
  typedef MultiPatch<LayoutTag,PatchTag> Tag_t;
  typedef Engine<Dim,T,Tag_t> This_t;
  typedef Engine<Dim,T,Tag_t> Engine_t;
  typedef Interval<Dim> Domain_t;
  typedef T Element_t;
  typedef PatchTag PatchTag_t;
  typedef Engine<Dim, T, PatchTag> PatchEngine_t;
  typedef typename PatchEngine_t::ElementRef_t ElementRef_t;
  typedef RefCountedBlockPtr<PatchEngine_t> PatchContainer_t;
  typedef MultiPatchLayoutTraits<LayoutTag,Dim> LayoutTraits_t;
  typedef typename LayoutTraits_t::Layout_t Layout_t;
  typedef Layout_t Observable_t;
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef ObserverEvent::ID_t DynamicID_t;
  typedef typename NewEngine<PatchEngine_t, Domain_t>::Type_t PatchView_t;
  enum { brick = false };
  enum { dimensions = Dim };
  enum { hasDataObject = false };
  enum { dynamic = PatchEngine_t::dynamic };
  enum { zeroBased = false };
  enum { multiPatch = true };
  Engine();
  explicit Engine(const Layout_t &layout);
  Engine(const Engine_t &model);
  ~Engine();
  Engine_t &operator=(const Engine_t &model);
  Element_t read(const Loc<Dim> &) const;
  ElementRef_t operator()(const Loc<Dim> &) const;
  Element_t read(int) const;
  Element_t read(int, int) const;
  Element_t read(int, int, int) const;
  Element_t read(int, int, int, int) const;
  Element_t read(int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int, int) const;
  ElementRef_t operator()(int) const;
  ElementRef_t operator()(int, int) const;
  ElementRef_t operator()(int, int, int) const;
  ElementRef_t operator()(int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int, int) const;
  inline PatchEngine_t &globalPatch(const INode<Dim> &inode) const
  {
    int gid = inode.globalID(layout_m.ID());
    PatchEngine_t &pengine = data()[gid];
    ;
    return pengine;
  }
  template<class Domain>
  inline PatchEngine_t &globalPatch(const Node<Domain> &node) const
  {
    int gid = node.globalID();
    PatchEngine_t &pengine = data()[gid];
    ;
    return pengine;
  }
  inline PatchEngine_t &globalPatch(PatchID_t gpatchID) const
  {
    return data()[gpatchID];
  }
  inline PatchEngine_t &localPatch(PatchID_t lpatchID) const
  {
    int gID = (layout_m.nodeListLocal()[lpatchID])->globalID();
    return data()[gID];
  }
  inline bool patchEmpty(PatchID_t patch) const
  {
    return data()[patch].domain().empty();
  }
  inline const Layout_t &layout() const
  {
    return layout_m;
  }
  inline Layout_t &layout()
  {
    return layout_m;
  }
  inline const Domain_t &domain() const
  {
    return layout().domain();
  }
  inline const Domain_t &innerDomain() const
  {
    return layout().innerDomain();
  }
  inline int first(int d) const
  {
    return layout().first(d);
  }
  inline bool initialized() const
  {
    return layout().initialized();
  }
  inline const PatchContainer_t &data() const
  {
    return data_m;
  }
  Engine_t &makeOwnCopy();
  inline void fillGuards(const GuardLayers<Dim>& g) const
  {
    fillGuardsHandler(g, WrappedInt<Layout_t::supportsGuards>());
  }
  inline void fillGuards() const
  {
    fillGuards(layout().internalGuards());
  }
  inline void fillGuardsHandler(const GuardLayers<Dim>&, const WrappedInt<false>&) const { };
  void fillGuardsHandler(const GuardLayers<Dim>&, const WrappedInt<true>&) const ;
  void setGuards(const T &val) const;
  void accumulateFromGuards() const;
  inline int dirty() const { return *pDirty_m; }
  inline void setDirty() const
  {
    *pDirty_m = (1<<(Dim*2))-1;
  }
  inline void clearDirty(int face = -1) const
  {
    if (face == -1)
      *pDirty_m = 0;
    else {
      ;
      *pDirty_m &= ~(1<<face);
    }
  }
  inline bool isDirty(int face = -1) const
  {
    if (face == -1)
      return *pDirty_m != 0;
    else {
      ;
      return *pDirty_m & (1<<face);
    }
  }
  virtual void notify(Observable_t &observed, const ObserverEvent &event);
  void dynamicHandler(Observable_t &, const ObserverEvent &,
                      const WrappedInt<false> &);
  void dynamicHandler(Observable_t &, const ObserverEvent &,
                      const WrappedInt<true> &);
  inline void create(CreateSize_t num, PatchID_t localPatchID = (-1))
    {
      layout().create(num, localPatchID);
    }
  template<class Dom, class DeleteMethod>
  inline void destroy(const Dom &killlist, const DeleteMethod &method)
  {
    layout().destroy(killlist, method);
  }
  template<class Dom>
  inline void destroy(const Dom &killlist)
  {
    layout().destroy(killlist, BackFill());
  }
  template<class Dom, class DeleteMethod>
  inline void destroy(const Dom &killlist, PatchID_t frompatch,
        const DeleteMethod &method)
    {
      layout().destroy(killlist, frompatch, method);
    }
  template<class Dom>
  inline void copy(const Dom &domain, PatchID_t topatch = (-1))
    {
      layout().copy(domain, topatch);
    }
  template<class Dom>
  inline void copy(const Dom &killlist,
                   PatchID_t frompatch, PatchID_t topatch)
    {
      layout().copy(killlist, frompatch, topatch);
    }
  inline void copy(const IndirectionList< IndirectionList<int> > &domlists,
     const IndirectionList< int > &fromlist,
     PatchID_t topatch,
     bool docreate)
    {
      layout().copy(domlists, fromlist, topatch, docreate);
    }
  void sync()
    {
      layout().sync();
    }
private:
  void performCreate(CreateSize_t num, PatchID_t patch,
       DynamicID_t did);
  template<class Dom, class DeleteMethod>
  void performDestroy(const Dom &killlist, PatchID_t patch,
        const DeleteMethod &method,
        DynamicID_t did);
  template<class Dom>
  void performCopy(const Dom &domain, PatchID_t frompatch, PatchID_t topatch,
     DynamicID_t did);
  void performPatchCopy(const IndirectionList< IndirectionList<int> > &dlists,
   const IndirectionList< int > &fromlist,
   PatchID_t topatch,
   bool docreate,
   DynamicID_t did);
  template <class Node, class Counter>
  class PatchAllocator : public Pooma::Runnable_t
  {
  public:
    PatchAllocator(PatchEngine_t &dest, const Node &node, Counter &c)
      : Pooma::Runnable_t(node.affinity()), dest_m(dest),
 node_m(node), counter_m(c)
    {
    }
    ~PatchAllocator() { }
    void run()
    {
      dest_m = PatchEngine_t(node_m);
      ++counter_m;
    }
  private:
    PatchEngine_t &dest_m;
    const Node &node_m;
    Counter &counter_m;
  };
  Layout_t layout_m;
  PatchContainer_t data_m;
  int *pDirty_m;
};
template <int D1, int D2>
struct SubDomainTraits
{
  typedef SliceRange<D1,D2> LocalToBase_t;
  typedef Range<D1> TotalDomain_t;
  inline static
  TotalDomain_t totalDomain(const LocalToBase_t &d)
  {
    return d.totalDomain();
  }
};
template <int D1>
struct SubDomainTraits<D1, D1>
{
  typedef Range<D1> LocalToBase_t;
  typedef Range<D1> TotalDomain_t;
  inline static
  TotalDomain_t totalDomain(const LocalToBase_t &dom)
  {
    return dom;
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
class Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >
{
public:
  typedef MultiPatchView<LayoutTag, PatchTag, Dim2> Tag_t;
  typedef Engine<Dim,T,Tag_t> This_t;
  typedef Engine<Dim,T,Tag_t> Engine_t;
  typedef Engine<Dim2,T,MultiPatch<LayoutTag,PatchTag> > ViewedEngine_t;
  typedef Interval<Dim> Domain_t;
  typedef T Element_t;
  typedef PatchTag PatchTag_t;
  typedef Engine<Dim2, T, PatchTag_t> PatchEngine_t;
  typedef typename PatchEngine_t::ElementRef_t ElementRef_t;
  typedef RefCountedBlockPtr<PatchEngine_t> PatchContainer_t;
  typedef MultiPatchLayoutTraits<LayoutTag,Dim2> ViewedLayoutTraits_t;
  typedef typename ViewedLayoutTraits_t::Layout_t ViewedLayout_t;
  typedef typename ViewedLayoutTraits_t::template View<Dim>
                                                    NestedViewTraits_t;
  typedef typename NestedViewTraits_t::Layout_t Layout_t;
  enum { dimensions = Dim };
  enum { hasDataObject = false };
  enum { dynamic = PatchEngine_t::dynamic };
  enum { zeroBased = true };
  enum { multiPatch = true };
  Engine() { }
  template<class DT>
  Engine(const ViewedEngine_t &engine, const Domain<Dim2, DT> &domain)
  : layout_m(engine.layout(), domain),
    baseEngine_m(engine)
  { }
  template<class DT>
  Engine(const ViewedEngine_t &engine, const SliceDomain<DT> &domain)
  : layout_m(engine.layout(), domain),
    baseEngine_m(engine)
  { }
  template<class DT>
  Engine(const This_t &engine, const Domain<Dim, DT> &domain)
  : layout_m(engine.layout(), domain),
    baseEngine_m(engine.baseEngine_m)
  { }
  template<int OrigDim, class DT>
  Engine(const Engine<OrigDim, T, Tag_t> &engine,
    const SliceDomain<DT> &domain)
  : layout_m(engine.layout(), domain),
    baseEngine_m(engine.baseEngine())
  { }
  Engine(const Engine_t &model);
  ~Engine();
  Engine_t &operator=(const Engine_t &model);
  Element_t read(const Loc<Dim> &) const;
  ElementRef_t operator()(const Loc<Dim> &) const;
  Element_t read(int) const;
  Element_t read(int, int) const;
  Element_t read(int, int, int) const;
  Element_t read(int, int, int, int) const;
  Element_t read(int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int, int) const;
  ElementRef_t operator()(int) const;
  ElementRef_t operator()(int, int) const;
  ElementRef_t operator()(int, int, int) const;
  ElementRef_t operator()(int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int, int) const;
  typename NewEngine<This_t, INode<Dim> >::Type_t
  globalPatch(const INode<Dim> &inode) const
  {
    typedef SubDomainTraits<Dim2, Dim> SubDomainTraits_t;
    typedef typename SubDomainTraits_t::LocalToBase_t LocalToBase_t;
    int gid = inode.globalID(layout_m.ID());
    PatchEngine_t &pengine = data()[gid];
    LocalToBase_t bdom = Pooma::NoInit();
    layout_m.localToBase(inode.domain(), bdom);
    ;
    typedef typename NewEngine<This_t,INode<Dim> >::Type_t Ret_t;
    return Ret_t(pengine, bdom);
  }
  template<class Domain>
  typename NewEngine<This_t, Node<Domain> >::Type_t
  globalPatch(const Node<Domain> &node) const
  {
    typedef SubDomainTraits<Dim2, Dim> SubDomainTraits_t;
    typedef typename SubDomainTraits_t::LocalToBase_t LocalToBase_t;
    LocalToBase_t bdom = Pooma::NoInit();
    layout_m.localToBase(node.domain(), bdom);
    int gid = node.globalID();
    PatchEngine_t &pengine = data()[gid];
    ;
    typedef typename NewEngine<This_t,Node<Domain> >::Type_t Ret_t;
    return Ret_t(pengine, bdom);
  }
  inline Layout_t &layout()
  {
    return layout_m;
  }
  inline const Layout_t &layout() const
  {
    return layout_m;
  }
  inline const Domain_t &domain() const
  {
    return layout().domain();
  }
  inline const Domain_t &innerDomain() const
  {
    return layout().innerDomain();
  }
  inline int first(int) const
  {
    return 0;
  }
  inline bool initialized() const
  {
    return layout().initialized();
  }
  inline void fillGuards() const
  {
    baseEngine_m.fillGuards();
  }
  inline void fillGuards(const GuardLayers<Dim2>& g) const
  {
    baseEngine_m.fillGuards(g);
  }
  inline void setGuards(const T &val) const
  {
    baseEngine_m.setGuards(val);
  }
  inline void accumulateFromGuards() const
  {
    baseEngine_m.accumulateFromGuards();
  }
  inline void setDirty() const
  {
    baseEngine_m.setDirty();
  }
  inline void clearDirty(int face=-1) const
  {
    baseEngine_m.clearDirty(face);
  }
  inline bool isDirty(int face=-1) const
  {
    return baseEngine_m.isDirty(face);
  }
  inline const PatchContainer_t &data() const
  {
    return baseEngine_m.data();
  }
  template<int D1, class T1>
  inline bool sameController(const Engine<D1, T1, Tag_t> &e) const
  {
    return block() == e.block();
  }
  PatchContainer_t block() const
  {
    return baseEngine_m.data();
  }
  inline const ViewedEngine_t &baseEngine() const
  {
    return baseEngine_m;
  }
private:
  Layout_t layout_m;
  ViewedEngine_t baseEngine_m;
};
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(const Loc<Dim> &loc) const
{
  return data()[layout_m.globalID(loc)].read(loc);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0) const
{
  return data()[layout_m.globalID(i0)].read(i0);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1) const
{
  return data()[layout_m.globalID(i0, i1)].read(i0, i1);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2)
const
{
  return data()[layout_m.globalID(i0, i1, i2)].read(i0, i1, i2);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
  int i3) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3)].read(i0, i1, i2, i3);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
  int i3, int i4) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4)].read
    (i0, i1, i2, i3, i4);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
  int i3, int i4, int i5) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5)].read
    (i0, i1, i2, i3, i4, i5);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
  int i3, int i4, int i5, int i6) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5, i6)].read
    (i0, i1, i2, i3, i4, i5, i6);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(const Loc<Dim> &loc)
  const
{
  return data()[layout_m.globalID(loc)](loc);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0) const
{
  return data()[layout_m.globalID(i0)](i0);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0,
  int i1) const
{
  return data()[layout_m.globalID(i0, i1)](i0, i1);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
  int i2) const
{
  return data()[layout_m.globalID(i0, i1, i2)](i0, i1, i2);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
  int i2, int i3) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3)](i0, i1, i2, i3);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
  int i2, int i3, int i4) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4)]
    (i0, i1, i2, i3, i4);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
  int i2, int i3, int i4, int i5) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5)]
    (i0, i1, i2, i3, i4, i5);
}
template<int Dim, class T, class LayoutTag, class PatchTag>
inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
  int i2, int i3, int i4, int i5, int i6) const
{
  return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5, i6)]
    (i0, i1, i2, i3, i4, i5, i6);
}
template <int Dim, class T, class LayoutTag, class PatchTag>
inline void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
dynamicHandler(Observable_t &, const ObserverEvent &,
               const WrappedInt<false> &)
{
  if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("This patch engine does not support dynamic events!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.h", 1460);
}
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
Engine(const Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >
  &modelEngine)
: layout_m(modelEngine.layout_m),
  baseEngine_m(modelEngine.baseEngine_m)
{ }
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > &
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator=(const Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >
  &rhs)
{
  if (&rhs == this) return *this;
  layout_m = rhs.layout_m;
  baseEngine_m = rhs.baseEngine_m;
  return *this;
}
template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >::
~Engine()
{ }
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(const Loc<Dim> &loc) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(loc, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::read(int i0) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1, int i2) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1, int i2, int i3) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1, int i2, int i3, int i4) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1, int i2, int i3, int i4, int i5) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline
typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
read(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, i6, gloc);
  return data()[o].read(gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(const Loc<Dim> &loc) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(loc, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1, int i2) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1, int i2, int i3) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1, int i2, int i3, int i4) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1, int i2, int i3, int i4, int i5) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, gloc);
  return data()[o](gloc);
}
template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
inline typename
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const
{
  Loc<Dim2> gloc = Pooma::NoInit();
  int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, i6, gloc);
  return data()[o](gloc);
}
template <int Dim, class T, class LayoutTag, class PatchTag, class Intersect>
struct LeafFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  ExpressionApply<IntersectorTag<Intersect> > >
{
  typedef int Type_t;
  static Type_t
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
 const ExpressionApply<IntersectorTag<Intersect> > &tag)
  {
    GuardLayers<Dim> usedGuards;
    bool useGuards =
      tag.tag().intersector_m.intersect(engine,
      engine.layout().internalGuards(), usedGuards);
    if (useGuards)
      engine.fillGuards(usedGuards);
    return 0;
  }
};
template <int Dim, class T, class LT, class PatchTag, int BD,
  class Intersect>
struct LeafFunctor<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> >,
  ExpressionApply<IntersectorTag<Intersect> > >
{
  typedef int Type_t;
  static Type_t
  apply(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
 const ExpressionApply<IntersectorTag<Intersect> > &tag)
  {
    typedef typename MultiPatchLayoutTraits<LT,Dim>::Layout_t Layout_t;
    return applyHandler(engine, tag, WrappedInt<Layout_t::supportsGuards>());
  }
  inline static Type_t
  applyHandler(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
        const ExpressionApply<IntersectorTag<Intersect> > &tag,
        const WrappedInt<true> &)
  {
    GuardLayers<BD> usedGuards;
    bool useGuards =
      tag.tag().intersector_m.
      intersect(engine,
  engine.layout().baseLayout().internalGuards(), usedGuards);
    if (useGuards)
      engine.fillGuards(usedGuards);
    return 0;
  }
  inline static Type_t
  applyHandler(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
        const ExpressionApply<IntersectorTag<Intersect> > &tag,
        const WrappedInt<false> &)
  {
    tag.tag().intersector_m.intersect(engine);
    return 0;
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  EnginePatch >
{
  typedef Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> > Subject_t;
  typedef Engine<Dim,T,PatchTag> Type_t;
  static inline
  Type_t apply(const Subject_t &engine, const EnginePatch &tag)
  {
    return engine.localPatch(tag.patch_m);
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  EngineNumPatches >
{
  typedef int Type_t;
  static inline
  Type_t apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
        const EngineNumPatches &)
  {
    return engine.layout().sizeLocal();
  }
};
template <int Dim, class T, class LayoutTag, class PatchTag>
struct NotifyEngineWrite<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > >
{
  inline static void
  notify(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine)
  {
    engine.setDirty();
  }
};
template <int Dim, class T, class LT, class PatchTag, int BD>
struct NotifyEngineWrite<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> > >
{
  inline static void
  notify(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine)
  {
    engine.setDirty();
  }
};
template<class PatchEngine>
inline
PatchEngine &localPatchEngine(PatchEngine &e)
{
  return e;
}
class TagGenerator
{
public:
  TagGenerator()
    : send_m(1), receive_m(1)
  {
    send_m[0] = 0;
    receive_m[0] = 0;
  }
  TagGenerator(int n)
    : send_m(n), receive_m(n)
  {
    int i;
    for (i = 0; i < n; ++i)
      {
        send_m[i] = 0;
        receive_m[i] = 0;
      }
  }
  int send(int otherContext)
  {
    ;
    int tag = send_m[otherContext];
    send_m[otherContext]++;
    return tag;
  }
  int receive(int otherContext)
  {
    ;
    int tag = receive_m[otherContext];
    receive_m[otherContext]++;
    return tag;
  }
private:
  std::vector<int> send_m;
  std::vector<int> receive_m;
};
namespace Pooma {
extern int expectedMessages_g;
void initializeCheetahHelpers(int contexts);
void finalizeCheetahHelpers();
int sendTag(int context);
int receiveTag(int context);
inline void addIncomingMessage()
{
  expectedMessages_g++;
}
inline void gotIncomingMessage()
{
  expectedMessages_g--;
}
inline bool incomingMessages()
{
  return (expectedMessages_g > 0);
}
}
class Full;
template<int D, class T, class E> class Vector;
template<int D, class T, class E> class VectorEngine;
template<class V, int I>
struct VectorElem
{
  typedef V Element_t;
  typedef const V& ConstElementRef_t;
  typedef V& ElementRef_t;
  static const V& get(const V& x) { return x; }
  static V& get( V& x) { return x; }
};
template<int D, class T, class E, int I>
struct VectorEngineElem
{
  typedef VectorEngine<D,T,E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::ConstElementRef_t ConstElementRef_t;
  typedef typename V::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x(I); }
  static ElementRef_t get( V& x) { return x(I); }
};
template<int D, class T, class E, int I>
struct VectorElem< Vector<D,T,E> , I >
{
  typedef Vector<D,T,E> V;
  typedef VectorEngineElem<D,T,E,I> VE;
  typedef typename VE::Element_t Element_t;
  typedef typename VE::ConstElementRef_t ConstElementRef_t;
  typedef typename VE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return VE::get(x.engine()); }
  static ElementRef_t get(V& x) { return VE::get(x.engine()); }
};
template<class V1, class V2, class Op, int B, int L>
struct VectorAssign
{
  static void apply(V1& v1, const V2& v2, Op op)
    {
      PoomaCTAssert<(L>1)>::test();
      VectorAssign<V1,V2,Op,B,L/2>::apply(v1,v2,op);
      VectorAssign<V1,V2,Op,B+L/2,L-L/2>::apply(v1,v2,op);
    }
};
template<class V1, class V2, class Op, int B>
struct VectorAssign<V1,V2,Op,B,0>
{
  static void apply(V1&, const V2&, Op) {}
};
template<class V1, class V2, class Op, int B>
struct VectorAssign<V1,V2,Op,B,1>
{
  static void apply(V1& v1, const V2& v2, Op op)
    {
      op(VectorElem<V1,B>::get(v1),VectorElem<V2,B>::get(v2));
    }
};
template<class V1, class V2, class Op, int B>
struct VectorAssign<V1,V2,Op,B,2>
{
  static void apply(V1& v1, const V2& v2, Op op)
    {
      op(VectorElem<V1,B >::get(v1), VectorElem<V2,B >::get(v2));
      op(VectorElem<V1,B+1>::get(v1), VectorElem<V2,B+1>::get(v2));
    }
};
template<class V1, class V2, class Op, int B>
struct VectorAssign<V1,V2,Op,B,3>
{
  static void apply(V1& v1, const V2& v2, Op op)
    {
      op(VectorElem<V1,B >::get(v1), VectorElem<V2,B >::get(v2));
      op(VectorElem<V1,B+1>::get(v1), VectorElem<V2,B+1>::get(v2));
      op(VectorElem<V1,B+2>::get(v1), VectorElem<V2,B+2>::get(v2));
    }
};
template<class V1, class V2, class Op>
class BinaryVectorOp;
template<int D, class T, class V1, class V2, class Op>
class VectorEngine<D,T, BinaryVectorOp<V1,V2,Op> >
{
public:
  enum { dimensions=1 };
  enum { d1=D };
  typedef T Element_t;
  typedef BinaryVectorOp<V1,V2,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef VectorEngine<D,T, BinaryVectorOp<V1,V2,Op> > This_t;
  VectorEngine(const V1& v1, const V2& v2)
    : v1_m(v1), v2_m(v2) {}
  Element_t operator()(int i) const
  {
    return Op()(v1_m(i), v2_m(i));
  }
  template<int DD,class TT, class EE, int I>
    friend struct VectorEngineElem;
private:
  const V1& v1_m;
  const V2& v2_m;
};
template<int D, class T, class V1, class V2, class Op, int I>
struct VectorEngineElem<D,T,BinaryVectorOp<V1,V2,Op>, I >
{
  typedef VectorEngine<D,T,BinaryVectorOp<V1,V2,Op> > V;
  typedef typename VectorElem<V1,I>::Element_t T1;
  typedef typename VectorElem<V2,I>::Element_t T2;
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(
        VectorElem<V1,I>::get(x.v1_m),
        VectorElem<V2,I>::get(x.v2_m));
    }
};
template<class V1, class Op>
class UnaryVectorOp;
template<int D, class T, class V1, class Op>
class VectorEngine<D,T,UnaryVectorOp<V1,Op> >
{
public:
  enum { dimensions=1 };
  enum { d1 = D };
  typedef T Element_t;
  typedef UnaryVectorOp<V1,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef VectorEngine<D,T, UnaryVectorOp<V1,Op> > This_t;
  explicit VectorEngine(const V1& v1)
    : v1_m(v1) {}
  Element_t operator()(int i) const
  {
    return Op()(v1_m(i));
  }
  template<int DD,class TT, class EE, int I>
    friend struct VectorEngineElem;
private:
  const V1& v1_m;
};
template<int D, class T, class V1, class Op, int I>
struct VectorEngineElem<D,T,UnaryVectorOp<V1,Op>, I>
{
  typedef VectorEngine<D,T,UnaryVectorOp<V1,Op> > V;
  typedef typename VectorElem<V1,I>::Element_t T1;
  typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(VectorElem<V1,I>::get(x.v1_m));
    }
};
template<int D, class T, class E> class Vector;
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcCos > { typedef Vector< D, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcCos >::Type_t acos( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcSin > { typedef Vector< D, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcSin >::Type_t asin( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcTan > { typedef Vector< D, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcTan >::Type_t atan( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnCeil > { typedef Vector< D, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnCeil >::Type_t ceil( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnCos > { typedef Vector< D, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnCos >::Type_t cos( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypCos > { typedef Vector< D, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypCos >::Type_t cosh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnExp > { typedef Vector< D, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnExp >::Type_t exp( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnFabs > { typedef Vector< D, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnFabs >::Type_t fabs( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnFloor > { typedef Vector< D, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnFloor >::Type_t floor( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnLog > { typedef Vector< D, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnLog >::Type_t log( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnLog10 > { typedef Vector< D, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnLog10 >::Type_t log10( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnSin > { typedef Vector< D, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnSin >::Type_t sin( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypSin > { typedef Vector< D, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypSin >::Type_t sinh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnSqrt > { typedef Vector< D, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnSqrt >::Type_t sqrt( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnTan > { typedef Vector< D, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnTan >::Type_t tan( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypTan > { typedef Vector< D, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypTan >::Type_t tanh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpUnaryMinus > { typedef Vector< D, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpUnaryMinus >::Type_t operator-( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpUnaryPlus > { typedef Vector< D, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpUnaryPlus >::Type_t operator+( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpBitwiseNot > { typedef Vector< D, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpBitwiseNot >::Type_t operator~( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpAdd >::Type_t operator+( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpAdd >::Type_t operator+( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpAdd >::Type_t operator+( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpSubtract > { typedef Vector< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpSubtract >::Type_t operator-( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpSubtract > { typedef Vector< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpSubtract > { typedef Vector< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpSubtract >::Type_t operator-( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpMultiply > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpMultiply >::Type_t operator*( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpMultiply > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpMultiply > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpMultiply >::Type_t operator*( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpDivide >::Type_t operator/( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpDivide >::Type_t operator/( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpDivide >::Type_t operator/( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpMod >::Type_t operator%( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpMod> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpMod >::Type_t operator%( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpMod >::Type_t operator%( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpMod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseAnd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseAnd >::Type_t operator&( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseAnd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseAnd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseOr > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseOr >::Type_t operator|( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseOr > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseOr > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseXor > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseXor >::Type_t operator^( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseXor > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseXor > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnLdexp >::Type_t ldexp( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnLdexp >::Type_t ldexp( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnPow >::Type_t pow( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnPow> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnPow >::Type_t pow( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnPow >::Type_t pow( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnPow> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnFmod >::Type_t fmod( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnFmod >::Type_t fmod( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnFmod >::Type_t fmod( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnArcTan2 > { typedef Vector< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnArcTan2 >::Type_t atan2( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnArcTan2 > { typedef Vector< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnArcTan2 > { typedef Vector< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnArcTan2 >::Type_t atan2( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template<class V1, class V2, int B, int L>
struct VectorDotVector
{
  typedef typename VectorDotVector<V1,V2,B,L/2>::Type_t Left_t;
  typedef typename VectorDotVector<V1,V2,B+L/2,L-L/2>::Type_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
  static Type_t get(const V1& x, const V2& y)
    {
      return
        VectorDotVector<V1,V2,B,L/2>::get(x,y) +
        VectorDotVector<V1,V2,B+L/2,L-L/2>::get(x,y);
    }
};
template<class V1, class V2, int B>
struct VectorDotVector<V1,V2,B,1>
{
  typedef typename VectorElem<V1,B>::Element_t Left_t;
  typedef typename VectorElem<V2,B>::Element_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
  static Type_t get(const V1& x, const V2& y)
    {
      return VectorElem<V1,B>::get(x) * VectorElem<V2,B>::get(y);
    }
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , FnDot >
{
  typedef Vector<D,T1,E1> V1;
  typedef Vector<D,T2,E2> V2;
  typedef typename VectorDotVector<V1,V2,0,D>::Type_t T0;
  typedef T0 Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , FnDot >::Type_t
dot( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 )
{
  return VectorDotVector<Vector<D,T1,E1>,Vector<D,T2,E2>,0,D>::get(v1,v2);
}
template<int D, class T, class E>
struct UnaryReturn< Vector<D,T,E> , FnNorm >
{
  typedef T Type_t;
};
template<int D, class T, class E>
inline T
norm(const Vector<D,T,E>& x)
{
  return sqrt(dot(x,x));
}
template<int D, class T, class E>
inline T
norm2(const Vector<D,T,E>& x)
{
  return dot(x,x);
}
template<class V1, class V2, int B, int L>
struct VectorEqualsVector
{
  typedef typename VectorEqualsVector<V1,V2,B,L/2>::Type_t Left_t;
  typedef typename VectorEqualsVector<V1,V2,B+L/2,L-L/2>::Type_t Right_t;
  typedef bool Type_t;
  static Type_t get(const V1& x, const V2& y)
    {
      return
        VectorEqualsVector<V1,V2,B,L/2>::get(x,y) &&
        VectorEqualsVector<V1,V2,B+L/2,L-L/2>::get(x,y);
    }
};
template<class V1, class V2, int B>
struct VectorEqualsVector<V1,V2,B,1>
{
  typedef typename VectorElem<V1,B>::Element_t Left_t;
  typedef typename VectorElem<V2,B>::Element_t Right_t;
  typedef bool Type_t;
  static Type_t get(const V1& x, const V2& y)
    {
      return VectorElem<V1,B>::get(x) == VectorElem<V2,B>::get(y);
    }
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , OpEQ >
{
  typedef bool Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , OpNE >
{
  typedef bool Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , OpEQ >::Type_t
operator==(const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2)
{
  return VectorEqualsVector<Vector<D,T1,E1>,Vector<D,T2,E2>,0,D>::get(v1,v2);
}
template<int D, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , OpNE >::Type_t
operator!=(const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2)
{
  return !(v1 == v2);
}
template<int D, class T, class E>
inline typename
BinaryReturn<Vector<D, T, E>, Vector<D, T, E> , OpNE>::Type_t
operator!=(const Vector<D, T, E>& v1, const Vector<D, T, E>& v2)
{
  return !(v1 == v2);
}
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator+=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpAddAssign,0,D>::apply(v1,v2,OpAddAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator+=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpAddAssign,0,D>::apply(v1,v2,OpAddAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator-=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpSubtractAssign,0,D>::apply(v1,v2,OpSubtractAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator-=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpSubtractAssign,0,D>::apply(v1,v2,OpSubtractAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator*=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpMultiplyAssign,0,D>::apply(v1,v2,OpMultiplyAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator*=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpMultiplyAssign,0,D>::apply(v1,v2,OpMultiplyAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator/=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpDivideAssign,0,D>::apply(v1,v2,OpDivideAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator/=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpDivideAssign,0,D>::apply(v1,v2,OpDivideAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator%=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpModAssign,0,D>::apply(v1,v2,OpModAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator%=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpModAssign,0,D>::apply(v1,v2,OpModAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator|=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseOrAssign,0,D>::apply(v1,v2,OpBitwiseOrAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator|=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseOrAssign,0,D>::apply(v1,v2,OpBitwiseOrAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator&=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseAndAssign,0,D>::apply(v1,v2,OpBitwiseAndAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator&=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseAndAssign,0,D>::apply(v1,v2,OpBitwiseAndAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator^=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseXorAssign,0,D>::apply(v1,v2,OpBitwiseXorAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator^=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseXorAssign,0,D>::apply(v1,v2,OpBitwiseXorAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator<<=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpLeftShiftAssign,0,D>::apply(v1,v2,OpLeftShiftAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator<<=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpLeftShiftAssign,0,D>::apply(v1,v2,OpLeftShiftAssign()); return v1; }
template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator>>=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpRightShiftAssign,0,D>::apply(v1,v2,OpRightShiftAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator>>=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpRightShiftAssign,0,D>::apply(v1,v2,OpRightShiftAssign()); return v1; }
template<int D, class T, class E> class Vector;
template<int D, class T, class E> class VectorEngine;
template <class T>
void reverseBytes(T&);
template<int Dim, class T=double, class EngineTag=Full>
class Vector
{
public:
  enum { dimensions=1 };
  enum { d1 = Dim };
  typedef T Element_t;
  typedef EngineTag EngineTag_t;
  typedef VectorEngine<Dim,T,EngineTag> Engine_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
  typedef Vector<Dim,T,EngineTag> This_t;
  Vector() {}
  Vector(const This_t& x) : engine_m(x.engine_m) {}
  template<int D2, class T2, class EngineTag2>
  Vector(const Vector<D2, T2, EngineTag2>& x) : engine_m(x) {}
  template<class X>
  explicit Vector(const X& x) : engine_m(x) {}
  template<class X1, class X2>
  Vector(const X1& x, const X2& y)
    : engine_m(x,y) {}
  template<class X1, class X2, class X3>
  Vector(const X1& x, const X2& y, const X3& z)
    : engine_m(x,y,z) {}
  template<class X1, class X2, class X3, class X4>
  Vector(const X1& x, const X2& y, const X3& z, const X4& a)
    : engine_m(x,y,z,a) {}
  template<class X1, class X2, class X3, class X4, class X5>
  Vector(const X1& x, const X2& y, const X3& z, const X4& a,
  const X5& b)
    : engine_m(x,y,z,a,b) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  Vector(const X1& x, const X2& y, const X3& z, const X4& a,
  const X5& b, const X6& c)
    : engine_m(x,y,z,a,b,c) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6, class X7>
  Vector(const X1& x, const X2& y, const X3& z, const X4& a,
  const X5& b, const X6& c, const X7& d)
    : engine_m(x,y,z,a,b,c,d) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
      class X7, class X8, class X9, class X10>
  Vector(const X1& x, const X2& y, const X3& z, const X4& a,
  const X5& b, const X6& c, const X7& d, const X8& e,
  const X9& f, const X10& g)
    : engine_m(x,y,z,a,b,c,d,e,f,g) {}
  ~Vector() {}
  This_t& operator=(const This_t& x)
    {
      if ( this != &const_cast<This_t &>(x) )
        engine() = x.engine();
      return *this;
    }
  template<class V>
    This_t&
      operator=(const V& x)
        {
          engine() = x;
          return *this;
        }
  ConstElementRef_t operator()(int i) const
    {
      return engine()(i);
    }
  ElementRef_t operator()(int i)
    {
      return engine()(i);
    }
  const Engine_t& engine() const { return engine_m; }
  Engine_t& engine() { return engine_m; }
  template<class Out>
  void print(Out &out) const;
  inline void reverseBytes() { engine_m.reverseBytes(); }
private:
  Engine_t engine_m;
};
template<int Dim, class T, class EngineTag>
template<class Out>
void Vector<Dim, T, EngineTag>::print(Out &out) const
{
  std::ios::fmtflags incomingFormatFlags = out.flags();
  long width = out.width();
  long precision = out.precision();
  out.width(0);
  out << "(";
  out.flags(incomingFormatFlags);
  out.width(width);
  out.precision(precision);
  out << (*this)(0) ;
  for (int i = 1; i < Dim; i++) {
    out << ",";
    out.flags(incomingFormatFlags);
    out.width(width);
    out.precision(precision);
    out << (*this)(i);
  }
  out << ")";
}
template<int D, class T, class E>
std::ostream &operator<<(std::ostream &out, const Vector<D,T,E> &v)
{
  v.print(out);
  return out;
}
template <int D, class T, class E>
struct ElementProperties< Vector<D,T,E> >
  : public TrivialElementProperties< Vector<D,T,E> >
{ };
template<int D, class T>
class VectorEngine<D,T,Full>
{
public:
  enum { dimensions=1 };
  enum { d1 = D };
  typedef T Element_t;
  typedef Full EngineTag_t;
  typedef T& ElementRef_t;
  typedef const T& ConstElementRef_t;
  typedef VectorEngine<D,T,Full> This_t;
  VectorEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
    for (int i = 0; i < D; ++i)
      {
 ElementProperties<T>::construct(&x_m[i]);
      }
  }
  inline VectorEngine(const VectorEngine<D,T,Full>&);
  template<class X>
    inline explicit VectorEngine(const X& x)
      {
        VectorAssign< VectorEngine<D,T,Full> , X , OpAssign, 0, D >
          ::apply(*this,x,OpAssign());
      }
  template<class X1, class X2>
  inline VectorEngine(const X1& x, const X2& y)
  {
    PoomaCTAssert<(D == 2)>::test();
    x_m[0] = x;
    x_m[1] = y;
  }
  template<class X1, class X2, class X3>
  inline VectorEngine(const X1& x, const X2& y, const X3& z)
  {
    PoomaCTAssert<(D == 3)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
  }
  template<class X1, class X2, class X3, class X4>
  inline VectorEngine(const X1& x, const X2& y, const X3& z,
        const X4& a)
  {
    PoomaCTAssert<(D == 4)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
    x_m[3] = a;
  }
  template<class X1, class X2, class X3, class X4, class X5>
  inline VectorEngine(const X1& x, const X2& y, const X3& z,
        const X4& a, const X5& b)
  {
    PoomaCTAssert<(D == 5)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
    x_m[3] = a;
    x_m[4] = b;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  inline VectorEngine(const X1& x, const X2& y, const X3& z,
        const X4& a, const X5& b, const X6& c)
  {
    PoomaCTAssert<(D == 6)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
    x_m[3] = a;
    x_m[4] = b;
    x_m[5] = c;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6, class X7>
  inline VectorEngine(const X1& x, const X2& y, const X3& z,
        const X4& a, const X5& b, const X6& c, const X7& d)
  {
    PoomaCTAssert<(D == 7)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
    x_m[3] = a;
    x_m[4] = b;
    x_m[5] = c;
    x_m[6] = d;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
     class X7, class X8, class X9, class X10>
  inline VectorEngine(const X1& x, const X2& y, const X3& z,
        const X4& a, const X5& b, const X6& c,
        const X7& d, const X8& e, const X9& f,
        const X10& g)
  {
    PoomaCTAssert<(D == 10)>::test();
    x_m[0] = x;
    x_m[1] = y;
    x_m[2] = z;
    x_m[3] = a;
    x_m[4] = b;
    x_m[5] = c;
    x_m[6] = d;
    x_m[7] = e;
    x_m[8] = f;
    x_m[9] = g;
  }
  ~VectorEngine() {}
  This_t&
    operator=(const This_t& x)
      {
        if ( this != &x )
          VectorAssign<This_t,This_t,OpAssign,0,D>::apply(*this,x,OpAssign());
        return *this;
      }
  template<class V>
    This_t&
      operator=(const V& x)
        {
          VectorAssign<This_t,V,OpAssign,0,D>::apply(*this,x,OpAssign());
          return *this;
        }
  ConstElementRef_t operator()(int i) const
    {
      ;
      return x_m[i];
    }
  ElementRef_t operator()(int i)
    {
      ;
      return x_m[i];
    }
  inline void reverseBytes()
  {
    for (int d = 0; d < D; ++d) ::reverseBytes(x_m[d]);
  }
private:
  T x_m[D];
};
template<int D, class T, int I>
struct VectorElem< VectorEngine<D,T,Full> , I >
{
  typedef VectorEngine<D,T,Full> V;
  typedef VectorEngineElem<D,T,Full,I> VE;
  typedef typename VE::Element_t Element_t;
  typedef typename VE::ConstElementRef_t ConstElementRef_t;
  typedef typename VE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return VE::get(x); }
  static ElementRef_t get(V& x) { return VE::get(x); }
};
template<class T, class Components> struct ComponentAccess;
template<int D, class T, class E, int N>
struct ComponentAccess< Vector<D, T, E>, Loc<N> >
{
  typedef Vector<D, T, E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::ElementRef_t ElementRef_t;
  static inline ElementRef_t indexRef(V &v, const Loc<N> &l)
    {
      PoomaCTAssert<(N==1)>::test();
      return v(l[0].first());
    }
  static inline Element_t index(const V &v, const Loc<N> &l)
    {
      PoomaCTAssert<(N==1)>::test();
      return v(l[0].first());
    }
};
template<int D, class T>
inline
VectorEngine<D,T,Full>::VectorEngine(const VectorEngine<D,T,Full>& x)
{
  VectorAssign<This_t,This_t,OpAssign,0,D>::apply(*this,x,OpAssign());
}
template<class T>
class RemoteProxy
{
public:
  typedef RemoteProxy<T> This_t;
  RemoteProxy(T &val, int owningContext = 0)
  {
    if (Pooma::context() == owningContext)
    {
      value_m = &val;
    }
  }
  RemoteProxy(const RemoteProxy<T> &s)
  {
    if (s.value_m != &s.storedValue_m)
    {
      value_m = s.value_m;
    }
    else
    {
      storedValue_m = s.value();
      value_m = &storedValue_m;
    }
  }
  inline
  operator T() const { return *value_m; }
  inline
  T &value() { return *value_m; }
  inline
  const T &value() const { return *value_m; }
  template<class S>
  inline
  RemoteProxy<T> &operator=(const S &s)
  {
    *value_m = s;
    return *this;
  }
  template<class S>
  inline
  RemoteProxy<T> &operator=(const RemoteProxy<S> &s)
  {
    *value_m = s.value();
    return *this;
  }
  inline
  RemoteProxy<T> &operator=(const RemoteProxy<T> &s)
  {
    *value_m = s.value();
    return *this;
  }
  inline
  typename ComponentAccess<T, Loc<1> >::Element_t
  operator()(int i) const
  {
    return ComponentAccess<T, Loc<1> >::index(value(), Loc<1>(i));
  }
  inline
  typename ComponentAccess<T, Loc<1> >::ElementRef_t
  operator()(int i)
  {
    return ComponentAccess<T, Loc<1> >::indexRef(value(), Loc<1>(i));
  }
private:
  T *value_m;
  T storedValue_m;
};
template<class T, class S>
inline T
operator*(const RemoteProxy<T> &t, const S &s)
{
  return t.value() * s;
}
template<class T>
class ReductionValue
{
public:
  ReductionValue(bool valid, const T &val)
    : valid_m(valid)
    {
      if (valid_m)
 val_m = val;
    }
  ReductionValue(const ReductionValue<T> &model)
    {
      valid_m = model.valid();
      if (valid_m)
 val_m = model.value();
    }
  ReductionValue<T> &operator=(const ReductionValue<T> &rhs)
    {
      if (&rhs != this)
 {
   valid_m = rhs.valid();
   if (valid_m)
     val_m = rhs.value();
 }
      return *this;
    }
  bool valid() const { return valid_m; }
  const T &value() const { ; return val_m; }
  T &value() { ; return val_m; }
private:
  bool valid_m;
  T val_m;
};
template<class T, class ReductionOp>
class ReduceOverContexts
{
  typedef ReduceOverContexts<T, ReductionOp> This_t;
public:
  ReduceOverContexts(const T &val, int = 0, bool valid = true)
    {
      ;
      value_m = val;
    }
  void broadcast(T &val)
    {
      val = value_m;
    }
  inline operator T() const { return value_m; }
private:
  static void receive(This_t *me, ReductionValue<T> &v)
  {
    if (v.valid())
      {
 if (!me->valid_m)
   {
     me->value_m = v.value();
     me->valid_m = true;
   }
 else
   {
     ReductionOp()(me->value_m, v.value());
   }
      }
    me->toReceive_m--;
  }
  T value_m;
  bool valid_m;
  int toReceive_m;
  int toContext_m;
};
struct SendReceive
{
  template<class View>
  static
  void send(const View &view, int toContext)
  {
    ;
  }
};
template<class IncomingView>
struct Receive
{
  template<class View>
  static
  void receive(const View &view, int fromContext)
  {
    ;
  }
};
template<int Dim>
Interval<Dim> &
shrinkRightInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() - s[d].first();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
shrinkRightInPlace(Interval<Dim> &dom, int s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() - s;
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
growRightInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() + s[d].first();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
growRightInPlace(Interval<Dim> &dom, int s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() + s;
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
shrinkLeftInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s[d].first();
      int b = dom[d].last();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
shrinkLeftInPlace(Interval<Dim> &dom, int s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s;
      int b = dom[d].last();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
growLeftInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s[d].first();
      int b = dom[d].last();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
Interval<Dim> &
growLeftInPlace(Interval<Dim> &dom, int s)
{
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s;
      int b = dom[d].last();
      dom[d] = Interval<1>(a, b);
    }
  return dom;
}
template<int Dim>
inline Interval<Dim>
shrinkRight(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() - s[d].first();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrinkRight(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() - s;
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
growRight(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() + s[d].first();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
growRight(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first();
      int b = dom[d].last() + s;
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrinkLeft(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s[d].first();
      int b = dom[d].last();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrinkLeft(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s;
      int b = dom[d].last();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
growLeft(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s[d].first();
      int b = dom[d].last();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
growLeft(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s;
      int b = dom[d].last();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
grow(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s;
      int b = dom[d].last() + s;
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
grow(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() - s[d].first();
      int b = dom[d].last() + s[d].first();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrink(const Interval<Dim> &dom, int s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s;
      int b = dom[d].last() - s;
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template<int Dim>
inline Interval<Dim>
shrink(const Interval<Dim> &dom, const Loc<Dim> &s)
{
  Interval<Dim> ret = Pooma::NoInit();
  for (int d = 0; d < Dim; ++d)
    {
      int a = dom[d].first() + s[d].first();
      int b = dom[d].last() - s[d].first();
      ret[d] = Interval<1>(a, b);
    }
  return ret;
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
Engine()
  : pDirty_m(0)
{
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
Engine(const Layout_t &layout)
  : layout_m(layout),
    data_m(layout.sizeGlobal()),
    pDirty_m(new int)
{
  typedef typename Layout_t::Value_t Node_t;
  setDirty();
  int sz = data().size();
  typedef Pooma::CountingSemaphore CountingSemaphore_t;
  typedef typename Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
    template PatchAllocator<Node_t,CountingSemaphore_t> PatchAllocator_t;
  CountingSemaphore_t csem;
  csem.height(sz);
  typename Layout_t::const_iterator p = layout_m.beginGlobal();
  for (int i = 0; i < sz; ++i, ++p)
    {
      PatchAllocator_t *spot = new PatchAllocator_t(data()[i], *p, csem);
      Pooma::addRunnable(spot);
    }
  csem.wait();
  layout_m.attach(*this);
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
Engine(const Engine_t &modelEngine)
  : layout_m(modelEngine.layout_m),
    data_m(modelEngine.data_m),
    pDirty_m(modelEngine.pDirty_m)
{
  layout_m.attach(*this);
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
~Engine()
{
  if (initialized())
    {
      layout_m.detach(*this);
      if (!data().isShared())
 delete pDirty_m;
    }
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> > &
Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
operator=(const Engine_t &model)
{
  if (&model == this)
    return *this;
  if (!model.initialized())
    return *this;
  if (initialized())
    {
      if (!data().isShared())
 delete pDirty_m;
      layout_m.detach(*this);
    }
  data_m = model.data();
  pDirty_m = model.pDirty_m;
  layout_m = model.layout_m;
  layout_m.attach(*this);
  return *this;
}
template <int Dim, class T, class LayoutTag, class PatchTag>
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > &
Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
makeOwnCopy()
{
  if (data_m.isValid() && data_m.isShared()) {
    data_m.makeOwnCopy();
    pDirty_m = new int(*pDirty_m);
  }
  return *this;
}
template <int Dim, class T, class Tag>
static inline
void simpleAssign(const Array<Dim, T, Tag>& lhs,
    const Array<Dim, T, Tag>& rhs,
    const Interval<Dim>& domain)
{
  lhs(domain) = rhs(domain);
}
template <int Dim, class T, class Tag>
static inline
void simpleAssign(const Array<Dim, T, Remote<Tag> >& lhs,
    const Array<Dim, T, Remote<Tag> >& rhs,
    const Interval<Dim>& domain)
{
  if (lhs.engine().owningContext() == rhs.engine().owningContext())
    lhs(domain) = rhs(domain);
  else {
    typedef typename NewEngine<Engine<Dim, T, Tag>, Interval<Dim> >::Type_t ViewEngine_t;
    if (lhs.engine().engineIsLocal())
      Receive<ViewEngine_t>::receive(ViewEngine_t(lhs.engine().localEngine(), domain),
         rhs.engine().owningContext());
    else if (rhs.engine().engineIsLocal())
      SendReceive::send(ViewEngine_t(rhs.engine().localEngine(), domain),
   lhs.engine().owningContext());
  }
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
fillGuardsHandler(const GuardLayers<Dim>& g, const WrappedInt<true> &) const
{
  if (!isDirty()) return;
  int updated = 0;
  typename Layout_t::FillIterator_t p = layout_m.beginFillList();
  while (p != layout_m.endFillList())
    {
      int src = p->ownedID_m;
      int dest = p->guardID_m;
      if (isDirty(p->face_m)) {
 int d = p->face_m/2;
 int guardSizeNeeded = p->face_m & 1 ? g.upper(d) : g.lower(d);
        if (!(p->face_m != -1
       && guardSizeNeeded == 0)) {
          Array<Dim, T, PatchTag> lhs(data()[dest]), rhs(data()[src]);
          lhs(p->domain_m) = rhs(p->domain_m);
   updated |= 1<<p->face_m;
 }
      }
      ++p;
    }
  *pDirty_m &= ~updated;
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
setGuards(const T &val) const
{
  typename Layout_t::FillIterator_t p = layout_m.beginFillList();
  while (p != layout_m.endFillList())
    {
      int dest = p->guardID_m;
      Array<Dim, T, PatchTag> lhs(data()[dest]);
      lhs(p->domain_m) = val;
      ++p;
    }
  setDirty();
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
accumulateFromGuards() const
{
  typename Layout_t::FillIterator_t p = layout_m.beginFillList();
  while (p != layout_m.endFillList())
    {
      int dest = p->ownedID_m;
      int src = p->guardID_m;
      Array<Dim, T, PatchTag> lhs(data()[dest]), rhs(data()[src]);
      lhs(p->domain_m) += rhs(p->domain_m);
      ++p;
    }
  setDirty();
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
dynamicHandler(Observable_t &,
               const ObserverEvent &event,
               const WrappedInt<true> &)
{
  switch (event.event())
  {
    case DynamicEvents::create:
      {
        typedef const CreateEvent &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        performCreate(e.amount(), e.patch(), e.ID());
      }
      break;
    case DynamicEvents::destroyInterval:
      {
        typedef const DestroyEvent< Interval<1> > &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        switch (e.method())
        {
          case DynamicEvents::backfill:
            performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
     break;
   case DynamicEvents::shiftup:
     performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
     break;
   default:
     if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 455);
        }
      }
      break;
    case DynamicEvents::destroyRange:
      {
        typedef const DestroyEvent< Range<1> > &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        switch (e.method())
        {
          case DynamicEvents::backfill:
            performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
     break;
   case DynamicEvents::shiftup:
     performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
     break;
   default:
     if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 476);
        }
      }
      break;
    case DynamicEvents::destroyList:
      {
        typedef const DestroyEvent< IndirectionList<int> > &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        switch (e.method())
        {
          case DynamicEvents::backfill:
            performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
     break;
   case DynamicEvents::shiftup:
     performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
     break;
   default:
     if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 497);
        }
      }
      break;
    case DynamicEvents::destroyIterList:
      {
        using Pooma::IteratorPairDomain;
        typedef
          const DestroyEvent< IteratorPairDomain<const int*> > &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        switch (e.method())
        {
          case DynamicEvents::backfill:
            performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
     break;
   case DynamicEvents::shiftup:
     performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
     break;
   default:
     if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 520);
        }
      }
      break;
    case DynamicEvents::copyInterval:
      {
        typedef const CopyEvent< Interval<1> > &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
      }
      break;
    case DynamicEvents::copyRange:
      {
        typedef const CopyEvent< Range<1> > &EventRef_t;
 EventRef_t e = dynamic_cast<EventRef_t>(event);
 performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
      }
      break;
    case DynamicEvents::copyList:
      {
        typedef const CopyEvent< IndirectionList<int> > &EventRef_t;
 EventRef_t e = dynamic_cast<EventRef_t>(event);
 performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
      }
      break;
    case DynamicEvents::copyPatchList:
      {
        typedef const CopyPatchEvent &EventRef_t;
        EventRef_t e = dynamic_cast<EventRef_t>(event);
        performPatchCopy(e.domainLists(), e.fromPatch(), e.toPatch(),
                         e.create(), e.ID());
      }
      break;
    case DynamicEvents::sync:
      {
        for (int i=0; i < layout().sizeGlobal(); ++i)
   data()[i].sync(layout().nodeListGlobal()[i]->domain());
      }
      break;
    default:
      if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Invalid dynamic op???", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 567);
  }
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
notify(Observable_t &observed, const ObserverEvent &event)
{
  ;
  if(event.event() == Layout_t::repartitionEvent)
    {
      typedef typename Layout_t::Value_t Node_t;
      int sz = layout().sizeGlobal();
      PatchContainer_t newData(sz);
      typedef Pooma::CountingSemaphore CountingSemaphore_t;
      typedef typename Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
        template PatchAllocator<Node_t,CountingSemaphore_t> PatchAllocator_t;
      CountingSemaphore_t csem;
      csem.height(sz);
      typename Layout_t::const_iterator p = layout().beginGlobal();
      for (int i = 0; i < sz; ++i, ++p)
 {
          PatchAllocator_t *spot = new PatchAllocator_t(newData[i], *p, csem);
          Pooma::addRunnable(spot);
        }
      csem.wait();
      data_m = newData;
    }
  else
    {
      if (DynamicEvents::isDynamic(event.event()))
        {
          dynamicHandler(observed, event,
            WrappedInt<PatchEngine_t::dynamic>());
 }
      else
 {
 }
    }
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
performCreate(CreateSize_t num, PatchID_t localPatchID, DynamicID_t did)
{
  ;
  ;
  int globalID = layout().nodeListLocal()[localPatchID]->globalID();
  if (! checkDynamicID(data()[globalID], did))
    return;
  data()[globalID].create(num);
}
template <int Dim, class T, class LayoutTag, class PatchTag>
template <class Dom, class DeleteMethod>
void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
performDestroy(const Dom &killlist, PatchID_t localPatchID,
        const DeleteMethod &method, DynamicID_t did)
{
  ;
  int globalID = layout().nodeListLocal()[localPatchID]->globalID();
  if (! checkDynamicID(data()[globalID], did))
    return;
  data()[globalID].destroy(killlist, method, true);
}
template <int Dim, class T, class LayoutTag, class PatchTag>
template <class Dom>
void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
performCopy(const Dom &copylist, PatchID_t frompatch, PatchID_t topatch,
     DynamicID_t did)
{
  ;
  ;
  ;
  int from_gID = layout().nodeListLocal()[frompatch]->globalID();
  int to_gID = layout().nodeListLocal()[topatch]->globalID();
  bool chk1 = checkDynamicID(data()[from_gID], did);
  bool chk2 = chk1;
  if (frompatch != topatch)
    chk2 = checkDynamicID(data()[to_gID], did);
  ;
  if (!chk1 || !chk2)
    return;
  ;
  int offs = data()[from_gID].domain()[0].first();
  int i = data()[to_gID].domain()[0].last() + 1;
  int num = copylist.size();
  data()[to_gID].create(num);
  for (int n = 0; n < num; ++n, ++i)
  {
    localPatchEngine(data()[to_gID])(i) =
      localPatchEngine(data()[from_gID])(copylist[0](n) + offs);
  }
}
template <int Dim, class T, class LayoutTag, class PatchTag>
void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
performPatchCopy(const IndirectionList< IndirectionList<int> > &domlists,
   const IndirectionList< int > &fromlist,
   PatchID_t topatch,
   bool docreate,
   DynamicID_t did)
{
  ;
  ;
  int to_gID = layout().nodeListLocal()[topatch]->globalID();
  if (! checkDynamicID(data()[to_gID], did))
    return;
  int i, p, fill, created = 0;
  int np = domlists.size();
  ;
  for (p = 0; p < np; ++p)
    {
      int frompatch = fromlist(p);
      int from_gID = layout().nodeListLocal()[frompatch]->globalID();
      ;
      ;
      ;
      created += domlists(p).size();
    }
  if (docreate)
    {
      fill = data()[to_gID].domain()[0].last() + 1;
      data()[to_gID].create(created);
    }
  else
    {
      ;
      fill = data()[to_gID].domain()[0].last() + 1 - created;
    }
  for (p = 0; p < np; ++p)
    {
      int sz = domlists(p).size();
      int frompatch = fromlist(p);
      int from_gID = layout().nodeListLocal()[frompatch]->globalID();
      int offs = data()[from_gID].domain()[0].first();
      for (i = 0; i < sz; ++i, ++fill)
      {
 localPatchEngine(data()[to_gID])(fill) =
   localPatchEngine(data()[from_gID])(domlists(p)(i) + offs);
      }
    }
}
template<int Dim, class T, class LTag, class PatchTag>
long elementsCompressed(const Engine<Dim, T, MultiPatch<LTag, PatchTag> >
  &engine)
{
  int size = engine.layout().sizeLocal();
  bool distributed = true;
  if (size > 0 && engine.layout().beginLocal()->context() == -1)
    distributed = false;
  long num = 0L;
  for (int i = 0 ; i < size ; ++i )
    num += elementsCompressed(engine.localPatch(i));
  if (distributed)
    {
      ReduceOverContexts<long, OpAddAssign> total(num);
      total.broadcast(num);
    }
  return num;
}
template<int Dim, class T, class LTag, class PatchTag>
bool compressed(const Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
{
  int size = engine.layout().sizeLocal();
  bool distributed = true;
  if (size > 0 && engine.layout().beginLocal()->context() == -1)
    distributed = false;
  int com = 1;
  for (int i = 0 ; i < size ; ++i )
    com &= (compressed(engine.localPatch(i)) ? 1 : 0);
  if (distributed)
    {
      ReduceOverContexts<int, OpBitwiseAndAssign> total(com);
      total.broadcast(com);
    }
  return com ? true : false;
}
template<int Dim, class T, class LTag, class PatchTag, int Dim2>
long elementsCompressed(const
  Engine<Dim, T, MultiPatchView<LTag, PatchTag, Dim2> > &engine)
{
  typedef Engine<Dim, T, MultiPatchView<LTag, PatchTag, Dim2> > Engine_t;
  typedef typename Engine_t::Layout_t Layout_t;
  int size = engine.layout().sizeLocal();
  bool distributed = true;
  if (size > 0 && engine.layout().beginLocal()->context() == -1)
    distributed = false;
  typename Layout_t::const_iterator i = engine.layout().beginLocal();
  long num = 0L;
  while (i != engine.layout().endLocal())
    {
      num += elementsCompressed(engine.globalPatch(*i));
      ++i;
    }
  if (distributed)
    {
      ReduceOverContexts<long, OpAddAssign> total(num);
      total.broadcast(num);
    }
  return num;
}
template<int Dim, class T, class LTag, class PatchTag>
void compress(Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
{
  for (int i = 0; i < engine.layout().sizeLocal(); ++i)
    compress(engine.localPatch(i));
}
template<int Dim, class T, class LTag, class PatchTag>
void uncompress(Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
{
  for (int i = 0; i < engine.layout().sizeLocal(); ++i)
    uncompress(engine.localPatch(i));
}
template <int Dim> class GridLayoutData;
template <int Dim> class GridLayout;
template <int Dim, int Dim2> class GridLayoutViewData;
template <int Dim, int Dim2> class GridLayoutView;
struct GridTag { };
template <int Dim>
struct MultiPatchLayoutTraits<GridTag,Dim>
{
  typedef GridLayout<Dim> Layout_t;
  template <int ViewDim>
  struct View
  {
    typedef GridLayoutView<ViewDim,Dim> Layout_t;
  };
};
template<int Dim>
class GridLayoutData
  : public LayoutBaseData<Dim>,
    public RefCounted,
    public Observable< GridLayoutData<Dim> >
{
public:
  typedef GridLayoutData<Dim> This_t;
  typedef Observable<This_t> Observable_t;
  typedef Interval<Dim> Domain_t;
  typedef Interval<Dim> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef Node<Domain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef int AxisIndex_t;
  typedef typename DynamicEvents::PatchID_t PatchID_t;
  typedef typename DynamicEvents::CreateSize_t CreateSize_t;
  typedef typename LayoutBaseData<Dim>::GCFillInfo_t GCFillInfo_t;
  typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  enum { dimensions = Dim };
  enum { repartitionEvent = 1 };
  enum { dynamic = false };
  GridLayoutData();
  template <class Partitioner>
  GridLayoutData(const Domain_t &gdom,
   const Partitioner &gpar,
   const ContextMapper<Dim> & cmap);
  template <class Partitioner>
  GridLayoutData(const Grid<Dim> &gdom,
   const Partitioner &gpar,
                 const ContextMapper<Dim> &cmap);
  ~GridLayoutData();
  template <class Partitioner>
  void initialize(const Domain_t &gdom,
    const Partitioner &gpar,
    const ContextMapper<Dim> &cmap);
  template <class Partitioner>
  inline void initialize(const Grid<Dim> &gdom,
    const Partitioner &gpar,
                         const ContextMapper<Dim> &cmap);
  void initialize(const Domain_t& idom,
    const List_t& nodes,
    const Loc<Dim>& blocks,
    bool hasIG, bool hasEG,
    const GuardLayers_t& ig,
    const GuardLayers_t& eg);
  inline const Loc<Dim> &blocks() const
    {
      return this->blocks_m;
    }
  inline bool dirty() const
    {
      return dirtyLayout_m;
    }
  int globalID(const Loc<Dim> &loc) const;
  int globalID(int) const;
  int globalID(int,int) const;
  int globalID(int,int,int) const;
  int globalID(int,int,int,int) const;
  int globalID(int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int) const;
  int globalID(int,int,int,int,int,int,int) const;
  FillIterator_t beginFillList() const
    {
      return this->gcFillList_m.begin();
    }
  FillIterator_t endFillList() const
    {
      return this->gcFillList_m.end();
    }
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touches(const OtherDomain &fulld, OutIter o,
       const ConstructTag &ctag) const;
  template <class OtherDomain, class OutIter, class ConstructTag>
  int touchesAlloc(const OtherDomain &fulld, OutIter o,
     const ConstructTag &ctag) const;
  void sync();
  template<class Out>
  void print(Out & ostr);
private:
  void calcGCFillList();
  void calcDomains();
  void calcMaps() const;
  void calcAllocMaps() const;
  inline int blockIndex(const Loc<Dim> &loc) const
    {
      int pos = loc[0].first();
      for (int i=1; i < Dim; ++i)
 pos += loc[i].first() * blockStrides_m[i];
      return pos;
    }
  bool dirtyLayout_m;
  int blockStrides_m[Dim];
  mutable DomainMap<Interval<1>,AxisIndex_t> map_m[Dim];
  mutable DomainMap<Interval<1>,AxisIndex_t> mapAloc_m[Dim];
};
template <int Dim>
class GridLayout : public LayoutBase<Dim,GridLayoutData<Dim> >,
                   public Observable<GridLayout<Dim> >,
                   public Observer<GridLayoutData<Dim> >
{
public:
  typedef GridLayout<Dim> This_t;
  typedef Observable<This_t> Observable_t;
  typedef GridLayoutData<Dim> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef DynamicEvents::PatchID_t PatchID_t;
  typedef DynamicEvents::CreateSize_t CreateSize_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
  typedef typename
    std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
  enum { dimensions = Dim };
  enum { repartitionEvent = 1 };
  enum { dynamic = true };
  GridLayout();
  GridLayout(const Domain_t &,const DistributedTag &);
  GridLayout(const Domain_t &,const ReplicatedTag &);
  GridLayout(const Domain_t &,
             const GuardLayers_t &,const DistributedTag &);
  GridLayout(const Domain_t &,
             const GuardLayers_t &,const ReplicatedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,const DistributedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,
      const GuardLayers_t &,const DistributedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,
      const GuardLayers_t &,
      const GuardLayers_t &,const DistributedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,const ReplicatedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,
      const GuardLayers_t &,const ReplicatedTag &);
  GridLayout(const Domain_t &,
      const Loc<Dim> &,
      const GuardLayers_t &,
      const GuardLayers_t &,const ReplicatedTag &);
  GridLayout(const Grid<Dim> &,
      const DistributedTag &);
  GridLayout(const Grid<Dim> &,
      const GuardLayers_t &,
      const DistributedTag &);
  GridLayout(const Grid<Dim> &,
      const GuardLayers_t &,
      const GuardLayers_t &,
      const DistributedTag &);
  GridLayout(const Grid<Dim> &,
      const ReplicatedTag &);
  GridLayout(const Grid<Dim> &,
      const GuardLayers_t &,
      const ReplicatedTag &);
  GridLayout(const Grid<Dim> &,
      const GuardLayers_t &,
      const GuardLayers_t &,
      const ReplicatedTag &);
  template <class Partitioner>
  GridLayout(const Domain_t &,
      const Partitioner &,
      const DistributedTag &);
  template <class Partitioner>
  GridLayout(const Domain_t &,
      const Partitioner &,
      const ReplicatedTag &);
  template <class Partitioner>
  GridLayout(const Domain_t &,
      const Partitioner &,
      const ContextMapper<Dim> &);
  GridLayout(const This_t &);
  This_t &operator=(const This_t &);
  inline ~GridLayout()
    {
      this->pdata_m->detach(*this);
    }
  void initialize(const Domain_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Grid<Dim> &,
    const DistributedTag &);
  void initialize(const Grid<Dim> &,
    const GuardLayers_t &,
    const DistributedTag &);
  void initialize(const Grid<Dim> &,
    const GuardLayers_t &,
    const GuardLayers_t &,
    const DistributedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const DistributedTag &);
  void initialize(const Domain_t &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  void initialize(const Domain_t &,
    const Loc<Dim> &,
    const GuardLayers_t &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  void initialize(const Grid<Dim> &,
    const ReplicatedTag &);
  void initialize(const Grid<Dim> &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  void initialize(const Grid<Dim> &,
    const GuardLayers_t &,
    const GuardLayers_t &,
    const ReplicatedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const ReplicatedTag &);
  template <class Partitioner>
  void initialize(const Domain_t &,
    const Partitioner &,
    const ContextMapper<Dim> &);
  void initialize(const Domain_t& idom,
    const List_t& nodes,
    const Loc<Dim>& blocks,
    bool hasIG, bool hasEG,
    const GuardLayers_t& ig,
    const GuardLayers_t& eg);
  inline const Loc<Dim> &blocks() const
    {
      return this->pdata_m->blocks();
    }
  template <class Partitioner>
  inline bool repartition(const Partitioner &gp,const ContextMapper<Dim> &cm)
    {
      this->pdata_m->initialize(this->domain(),gp,cm);
      this->pdata_m->notify(repartitionEvent);
      return true;
    }
  inline void sync()
    {
      this->pdata_m->sync();
    }
  virtual void notify(LayoutData_t &d, const ObserverEvent &event)
    {
      ;
      Observable_t::notify(event);
    }
  template <class Ostream>
  void print(Ostream &ostr) const;
  template <int Dim1, int Dim2>
  friend class GridLayoutView;
  friend class GridLayoutData<Dim>;
};
template <int Dim, int Dim2>
class GridLayoutViewData :
                public LayoutBaseViewData<Dim, Dim2, GridLayout<Dim2> >,
                public RefCounted
{
public:
  typedef GridLayout<Dim2> Layout_t;
  typedef GridLayoutView<Dim, Dim2> ViewLayout_t;
  typedef Interval<Dim> Domain_t;
  typedef Range<Dim2> BaseDomain_t;
  typedef int Context_t;
  typedef Unique::Value_t ID_t;
  typedef typename Layout_t::Domain_t AllocatedDomain_t;
  typedef ViewIndexer<Dim,Dim2> Indexer_t;
  typedef Node<Domain_t,AllocatedDomain_t> Value_t;
  typedef std::vector<Value_t *> List_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef GridLayoutViewData<Dim,Dim2> LayoutData_t;
  enum { dim = Dim };
  enum { dim2 = Dim2 };
  GridLayoutViewData() { }
  template <class DT>
  inline GridLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(layout,dom)
  {
  }
  template <class DT>
  inline GridLayoutViewData(const Layout_t &layout,
                            const SliceDomain<DT> &dom)
  :LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(layout,dom)
  {
  }
  template <class DT>
  GridLayoutViewData(const ViewLayout_t &layout,
                     const Domain<Dim, DT> &dom)
  : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(
           layout.pdata_m->layout_m,
           layout,
           layout.pdata_m->indexer_m,
           dom,
           layout.internalGuards(),
           layout.externalGuards())
  {
  }
  template <int OrigDim, class DT>
  GridLayoutViewData(const GridLayoutView<OrigDim, Dim2> &layout,
                     const SliceDomain<DT> &dom)
    : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(
        layout.pdata_m->layout_m,
        layout,
        Indexer_t(layout.pdata_m->indexer_m,dom),
        dom)
  {
  }
  ~GridLayoutViewData()
  {
    typename List_t::iterator a;
    for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
      delete (*a);
  }
};
template <int Dim, int Dim2>
class GridLayoutView
: public LayoutBaseView<Dim, Dim2, GridLayoutViewData<Dim,Dim2> >
{
public:
  enum { dimensions = Dim };
  enum { dim = Dim };
  enum { dim2 = Dim2 };
  typedef GridLayoutViewData<Dim, Dim2> LayoutData_t;
  typedef typename LayoutData_t::Domain_t Domain_t;
  typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
  typedef typename LayoutData_t::Context_t Context_t;
  typedef typename LayoutData_t::ID_t ID_t;
  typedef typename LayoutData_t::Layout_t Layout_t;
  typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
  typedef typename LayoutData_t::Value_t Value_t;
  typedef typename LayoutData_t::List_t List_t;
  typedef typename LayoutData_t::Indexer_t Indexer_t;
  typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
  typedef GridLayoutView<Dim, Dim2> This_t;
  typedef GridLayoutView<Dim, Dim2> ViewLayout_t;
  typedef LayoutBaseView<Dim, Dim2, LayoutData_t> Base_t;
  typedef DerefIterator<Value_t> iterator;
  typedef ConstDerefIterator<Value_t> const_iterator;
  GridLayoutView()
    : Base_t(new LayoutData_t())
  { }
  template <class DT>
  GridLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
    : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
  (new GridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  GridLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
    : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
  (new GridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <class DT>
  GridLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
 : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
  (new GridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  template <int OldViewDim, class DT>
  GridLayoutView(const GridLayoutView<OldViewDim, Dim2> &layout,
                        const SliceDomain<DT> &dom)
  : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
  (new GridLayoutViewData<Dim,Dim2>(layout,dom))
  { }
  inline GridLayoutView(const This_t &model)
    : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >(model.pdata_m)
  { }
  inline This_t &operator=(const This_t &model)
  {
    if (this != &model)
      {
        this->pdata_m = model.pdata_m;
      }
    return *this;
  }
  inline ~GridLayoutView()
  { }
  template <class Ostream>
  void print(Ostream &ostr) const;
  template <int OtherDim, int OtherDim2>
  friend class GridLayoutView;
  template <int OtherDim, int OtherDim2>
  friend class GridLayoutViewData;
  void computeSubdomains() const { this->pdata_m->computeSubdomains(); }
};
template <int Dim>
struct NewDomain1<GridLayout<Dim> >
{
  typedef GridLayout<Dim> &Type_t;
  inline static Type_t combine(const GridLayout<Dim> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim, int Dim2>
struct NewDomain1<GridLayoutView<Dim, Dim2> >
{
  typedef GridLayoutView<Dim, Dim2> &Type_t;
  inline static Type_t combine(const GridLayoutView<Dim, Dim2> &a)
    {
      return const_cast<Type_t>(a);
    }
};
template <int Dim>
std::ostream &operator<<(std::ostream &ostr,
    const GridLayout<Dim> &layout)
{
  layout.print(ostr);
  return ostr;
}
template <int Dim, int Dim2>
std::ostream &operator<<(std::ostream &ostr,
    const GridLayoutView<Dim, Dim2> &layout)
{
  layout.print(ostr);
  return ostr;
}
template<int Dim>
GridLayoutData<Dim>::GridLayoutData()
 : LayoutBaseData<Dim>(false,false,
     GuardLayers_t(0),GuardLayers_t(0),
     Interval<Dim>(),Interval<Dim>()),
    Observable<GridLayoutData>(*this)
{
  for (int d=0; d < Dim; ++d)
    this->firsti_m[d] = this->firste_m[d] = blockStrides_m[d] = 0;
}
template<int Dim>
template<class Partitioner>
GridLayoutData<Dim>::GridLayoutData(const Grid<Dim> &gdom,
        const Partitioner &gpar,
        const ContextMapper<Dim> &cmap)
  : LayoutBaseData<Dim>(false,false,
   GuardLayers_t(0),GuardLayers_t(0),
   Interval<Dim>(), Interval<Dim>()),
    Observable<GridLayoutData>(*this)
{
  initialize(gdom, gpar, cmap);
}
template<int Dim>
template<class Partitioner>
GridLayoutData<Dim>::GridLayoutData(const Domain_t &gdom,
        const Partitioner &gpar,
        const ContextMapper<Dim> &cmap)
  : LayoutBaseData<Dim>(false,false,
   GuardLayers_t(0),GuardLayers_t(0),
   gdom,gdom),
    Observable<GridLayoutData>(*this)
{
  for (int d=0; d < Dim; ++d)
    this->firsti_m[d] = this->firste_m[d] = blockStrides_m[d] = 0;
  initialize(gdom, gpar, cmap);
}
template<int Dim>
GridLayoutData<Dim>::~GridLayoutData()
{
  for (typename List_t::iterator a = this->all_m.begin(); a != this->all_m.end(); ++a)
    delete (*a);
}
template<int Dim>
template <class Partitioner>
inline void GridLayoutData<Dim>::initialize(const Grid<Dim> &gdom,
         const Partitioner &gpar,
         const ContextMapper<Dim> &cmap)
{
  Domain_t idom = Pooma::NoInit();
  for (int d=0; d < Dim; ++d)
    idom[d] = Interval<1>(gdom[d].first(), gdom[d].last() - 1);
  initialize(idom, gpar, cmap);
}
template<int Dim>
template<class Partitioner>
inline void GridLayoutData<Dim>::initialize(const Domain_t &gdom,
         const Partitioner &gpar,
         const ContextMapper<Dim> &cmap)
{
  int i;
  PoomaCTAssert<(Partitioner::gridded)>::test();
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  dirtyLayout_m = true;
  this->domain_m = gdom;
  this->innerdomain_m = gdom;
  this->hasInternalGuards_m = (gpar.hasInternalGuards() && gpar.maxSize() > 1);
  if (this->hasInternalGuards_m)
    {
      this->internalGuards_m = gpar.internalGuards();
    }
  this->hasExternalGuards_m = (gpar.hasExternalGuards() && ! this->domain_m.empty());
  if (this->hasExternalGuards_m)
    {
      this->externalGuards_m = gpar.externalGuards();
      GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
    }
  this->blocks_m = gpar.blocks();
  for (i=0; i < Dim; ++i)
    {
      if (!this->domain_m[i].empty())
 this->firsti_m[i] = this->domain_m[i].first();
      blockStrides_m[i] = (i == 0 ? 1 :
      blockStrides_m[i-1] * this->blocks_m[i-1].first());
    }
  gpar.partition(this->innerdomain_m, this->all_m, cmap);
  typename List_t::iterator start = this->all_m.begin();
  typename List_t::iterator end = this->all_m.end();
  for ( ; start!=end ;++start )
    {
      if( (*start)->context() == Pooma::context()
   ||(*start)->context() == -1 )
 this->local_m.push_back(*start);
      else
 this->remote_m.push_back(*start);
    }
  calcMaps();
  calcAllocMaps();
  calcGCFillList();
}
template<int Dim>
void GridLayoutData<Dim>::initialize(const Domain_t& idom,
     const List_t& nodes,
     const Loc<Dim>& blocks,
     bool hasIG, bool hasEG,
     const GuardLayers_t& ig,
     const GuardLayers_t& eg)
{
  int i;
  if (this->all_m.size() > 0)
    {
      for (i=0; i < this->all_m.size(); ++i)
 delete this->all_m[i];
      this->all_m.clear();
      this->local_m.clear();
      this->remote_m.clear();
    }
  dirtyLayout_m = true;
  this->domain_m = idom;
  this->innerdomain_m = idom;
  this->hasInternalGuards_m = hasIG;
  if (this->hasInternalGuards_m)
    {
      this->internalGuards_m = ig;
    }
  this->hasExternalGuards_m = (hasEG && ! this->domain_m.empty());
  if (this->hasExternalGuards_m)
    {
      this->externalGuards_m = eg;
      GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
    }
  this->blocks_m = blocks;
  for (i=0; i < Dim; ++i)
    {
      if (!this->domain_m[i].empty())
 this->firsti_m[i] = this->domain_m[i].first();
      blockStrides_m[i] = (i == 0 ? 1 :
      blockStrides_m[i-1] * this->blocks_m[i-1].first());
    }
  this->all_m= nodes;
  typename List_t::iterator start = this->all_m.begin();
  typename List_t::iterator end = this->all_m.end();
  for ( ; start!=end ;++start )
    {
      if( (*start)->context() == Pooma::context() ||
   (*start)->context() == -1 )
 this->local_m.push_back(*start);
      else
 this->remote_m.push_back(*start);
    }
  calcMaps();
  calcAllocMaps();
  calcGCFillList();
}
template<int Dim>
void GridLayoutData<Dim>::sync()
{
  ;
  if (!this->initialized() || !dirty())
    return;
  calcDomains();
  calcMaps();
  this->notify(SyncEvent());
}
template<int Dim>
void GridLayoutData<Dim>::calcGCFillList()
{
  int d;
  if (!this->initialized() || !this->hasInternalGuards_m)
    return;
  this->gcFillList_m.clear();
  int numPatches = this->all_m.size();
  this->gcFillList_m.reserve(2*Dim*this->local_m.size());
  ;
  Interval<Dim> grid;
  for (d=0; d < Dim; ++d)
    grid[d] = Interval<1>(this->blocks_m[d].first() + 1);
  for (d=0; d < Dim; ++d)
    {
      if (this->internalGuards_m.lower(d) > 0)
 {
   typename Interval<Dim>::blockIterator start = grid.beginBlock();
   typename Interval<Dim>::blockIterator end = grid.endBlock();
   for (; start != end; ++start)
     {
       int sourceID = start.index();
       Loc<Dim> tmp = start.point();
       tmp[d] += 1;
       if (!(tmp[d] >= this->blocks_m[d] || tmp[d].first() < 0))
  {
    int destID = blockIndex(tmp);
    if (!(this->all_m[sourceID]->domain().empty() ||
   this->all_m[destID]->domain().empty()))
      {
        ;
        Domain_t gcdom(this->all_m[sourceID]->allocated());
        int max = this->all_m[sourceID]->domain()[d].last();
        int min = max - this->internalGuards_m.lower(d) + 1;
        gcdom[d] = Interval<1>(min, max);
        this->gcFillList_m.push_back(GCFillInfo_t(gcdom, sourceID, destID, d*2));
      }
  }
     }
 }
      if (this->internalGuards_m.upper(d) > 0)
 {
   typename Interval<Dim>::blockIterator start = grid.beginBlock();
   typename Interval<Dim>::blockIterator end = grid.endBlock();
   for (; start != end; ++start)
     {
       int sourceID = start.index();
       Loc<Dim> tmp = start.point();
       tmp[d] -= 1;
       if (!(tmp[d] >= this->blocks_m[d] || tmp[d].first() < 0))
  {
    int destID = blockIndex(tmp);
    if (!(this->all_m[sourceID]->domain().empty() ||
   this->all_m[destID]->domain().empty()))
      {
        ;
        Domain_t gcdom(this->all_m[sourceID]->allocated());
        int min = this->all_m[sourceID]->domain()[d].first();
        int max = min + this->internalGuards_m.upper(d) - 1;
        gcdom[d] = Interval<1>(min, max);
        this->gcFillList_m.push_back(GCFillInfo_t(gcdom, sourceID, destID, d*2+1));
      }
  }
     }
 }
    }
}
template<int Dim>
void GridLayoutData<Dim>::calcDomains()
{
  if (!this->initialized() || !dirty())
    return;
  ;
  ;
  CreateSize_t sizes = this->firsti_m[0];
  bool allempty = true;
  for (int i=0; i < this->all_m.size(); ++i)
    {
      Domain_t dom = this->all_m[i]->domain();
      if (!dom[0].empty())
 {
   dom[0] = Interval<1>(sizes, sizes + dom[0].length() - 1);
   sizes += dom[0].length();
   allempty = false;
 }
      this->all_m[i]->setDomain(dom);
      this->all_m[i]->setAllocated(dom);
    }
  if (allempty)
    this->domain_m = Domain_t();
  else
    this->domain_m = Interval<1>(this->firsti_m[0], sizes - 1);
  this->innerdomain_m = this->domain_m;
  dirtyLayout_m = false;
}
template<int Dim>
void GridLayoutData<Dim>::calcMaps() const
{
  int i, j;
  if (!this->initialized() || !dirty())
    return;
  for (i=0; i < Dim; ++i)
    {
      map_m[i].zap();
      if (this->domain_m[i].empty())
 continue;
      Loc<Dim> blockLoc(0);
      map_m[i].initialize(Interval<1>(this->domain_m[i].first() -
          this->externalGuards_m.lower(i),
          this->domain_m[i].last() +
          this->externalGuards_m.upper(i)));
      int b = this->blocks_m[i].first();
      for (j=0; j < b; ++j)
 {
   blockLoc[i] = Loc<1>(j);
   int k = blockIndex(blockLoc);
   Interval<1> blockDom = this->all_m[k]->domain()[i];
   if (!blockDom.empty())
     {
       int lo = (j == 0 ? this->externalGuards_m.lower(i) : 0);
       int hi = (j == (b - 1) ? this->externalGuards_m.upper(i) : 0);
       Interval<1> mval(blockDom.first() - lo, blockDom.last() + hi);
       typename DomainMap<Interval<1>,int>::Value_t val(mval, j);
       map_m[i].insert(val);
     }
 }
      map_m[i].update();
    }
}
template<int Dim>
void GridLayoutData<Dim>::calcAllocMaps() const
{
  int i, j;
  if (!this->initialized() || !dirty())
    return;
  for (i=0; i < Dim; ++i)
    {
      mapAloc_m[i].zap();
      if (this->domain_m[i].empty())
 continue;
      Loc<Dim> blockLoc(0);
      mapAloc_m[i].initialize(Interval<1>(this->domain_m[i].first() -
       this->externalGuards_m.lower(i),
       this->domain_m[i].last() +
       this->externalGuards_m.upper(i)));
      int b = this->blocks_m[i].first();
      for (j=0; j < b; ++j)
 {
   blockLoc[i] = Loc<1>(j);
   int k = blockIndex(blockLoc);
   Interval<1> blockDom = this->all_m[k]->domain()[i];
   if (!blockDom.empty())
     {
       int lo = (j==0 ?
   this->externalGuards_m.lower(i) :
   this->internalGuards_m.lower(i));
       int hi = (j == (b - 1) ?
   this->externalGuards_m.upper(i) :
   this->internalGuards_m.upper(i));
       Interval<1> ival(blockDom.first() - lo, blockDom.last() + hi);
       typename DomainMap<Interval<1>,int>::Value_t valAl(ival, j);
       mapAloc_m[i].insert(valAl);
     }
 }
      mapAloc_m[i].update();
    }
}
template<int Dim>
int GridLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
{
  ;
  Loc<Dim> point;
  for (int i=0; i < Dim; ++i)
    {
      DomainMapTouchIterator<Interval<1>,int> dmti =
 (map_m[i].touch(Interval<1>(loc[i]))).first;
      DomainMapTouchIterator<Interval<1>,int> baditerator;
      ;
     point[i] = *dmti;
    }
  return blockIndex(point);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1, int i2) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4, int i5) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  loc[5] = i5;
  return globalID(loc);
}
template <int Dim>
int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
      int i4, int i5, int i6) const
{
  ;
  Loc<Dim> loc;
  loc[0] = i0;
  loc[1] = i1;
  loc[2] = i2;
  loc[3] = i3;
  loc[4] = i4;
  loc[5] = i5;
  loc[6] = i6;
  return globalID(loc);
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int GridLayoutData<Dim>::touches(const OtherDomain &fulld, OutIter o,
     const ConstructTag &ctag) const
{
  int i;
  ;
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t d = intersect(this->domain_m, fulld);
  if (d.empty())
    return 0;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  int hiAxisIndex[Dim];
  int loAxisIndex[Dim];
  Loc<Dim> curnode;
  for (i=0;i < Dim; ++i)
    {
      loAxisIndex[i] =
 *((map_m[i].touch(Interval<1>(d[i].first(),d[i].first()))).first);
      ;
      hiAxisIndex[i] =
 *((map_m[i].touch(Interval<1>(d[i].last(),d[i].last() ))).first);
      ;
      if(loAxisIndex[i]>hiAxisIndex[i])
 {
   int tmp = hiAxisIndex[i];
   hiAxisIndex[i] = loAxisIndex[i];
   loAxisIndex[i] = tmp;
 }
      curnode[i] = loAxisIndex[i];
    }
  int count=0;
  while(1)
    {
      int nodeListIndex = blockIndex(curnode);
      if (!this->all_m[nodeListIndex]->domain().empty())
 {
   outDomain = intersect(fulld,this->all_m[nodeListIndex]->domain());
   ;
   *o = touchesConstruct(outDomain,
    this->all_m[nodeListIndex]->allocated(),
    this->all_m[nodeListIndex]->affinity(),
    this->all_m[nodeListIndex]->context(),
    this->all_m[nodeListIndex]->globalID(),
    this->all_m[nodeListIndex]->localID(),
    ctag);
   ++count;
 }
      curnode[0] += 1;
      for (i=0; i < Dim; ++i)
 {
   if (curnode[i] == (hiAxisIndex[i]+1))
     {
       if (i==(Dim-1))
  break;
       curnode[i] = loAxisIndex[i];
       curnode[i+1] += 1;
     }
 }
      if (curnode[Dim-1] == (hiAxisIndex[Dim-1]+1))
 break;
    }
  return count;
}
template <int Dim>
template <class OtherDomain, class OutIter, class ConstructTag>
int GridLayoutData<Dim>::touchesAlloc(const OtherDomain &fulld, OutIter o,
          const ConstructTag &ctag) const
{
  int i;
  ;
  typedef typename
    IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
  OutDomain_t d = intersect(this->domain_m, fulld);
  if (d.empty())
    return 0;
  OutDomain_t outDomain = Pooma::NoInit();
  typedef Node<OutDomain_t,Domain_t> OutNode_t;
  int hiAxisIndex[Dim];
  int loAxisIndex[Dim];
  Loc<Dim> curnode;
  for (i=0; i < Dim; ++i)
    {
      loAxisIndex[i] =
 *((mapAloc_m[i].touch(Interval<1>(d[i].first(),d[i].first()))).first);
      ;
      hiAxisIndex[i] =
 *((mapAloc_m[i].touch(Interval<1>(d[i].last(),d[i].last()))).first);
      ;
      if(loAxisIndex[i]>hiAxisIndex[i])
 {
   int tmp = hiAxisIndex[i];
   hiAxisIndex[i] = loAxisIndex[i];
   loAxisIndex[i] = tmp;
 }
      curnode[i] = loAxisIndex[i];
    }
  int count=0;
  while(1)
    {
      int nodeListIndex = blockIndex(curnode);
      if (!this->all_m[nodeListIndex]->domain().empty())
 {
   outDomain = intersect(fulld,this->all_m[nodeListIndex]->allocated());
   ;
   *o = touchesConstruct(outDomain,
    this->all_m[nodeListIndex]->allocated(),
    this->all_m[nodeListIndex]->affinity(),
    this->all_m[nodeListIndex]->context(),
    this->all_m[nodeListIndex]->globalID(),
    this->all_m[nodeListIndex]->localID(),
    ctag);
   ++count;
 }
      curnode[0] += 1;
      for (i=0; i < Dim; ++i)
 {
   if (curnode[i] == (hiAxisIndex[i]+1))
     {
       if (i == (Dim-1))
  break;
       curnode[i] = loAxisIndex[i];
       curnode[i+1] += 1;
     }
 }
      if (curnode[Dim-1] == (hiAxisIndex[Dim-1]+1))
 break;
    }
  return count;
}
template<int Dim>
template<class Out>
void GridLayoutData<Dim>::print(Out & ostr)
{
  int i;
  ostr << " hasInternalGuards_m, hasExternalGuards_m "
       << this->hasInternalGuards_m << ' ' << this->hasExternalGuards_m
       << "\n internalGuards_m ";
  for (i=0; i<Dim; ++i)
    ostr << this->internalGuards_m.upper(i) << '-'
  << this->internalGuards_m.lower(i) << ' ';
  ostr << "\n externalGuards_m ";
  for (i=0; i<Dim; ++i)
    ostr << this->externalGuards_m.upper(i) << '-'
  << this->externalGuards_m.lower(i) << ' ';
  ostr << '\n';
  FillIterator_t gstart = this->gcFillList_m.begin();
  FillIterator_t gend = this->gcFillList_m.end();
  ostr << " this->gcFillList_m\n";
  for(; gstart!=gend; ++gstart)
    ostr << "       "
  << gstart->domain_m << ' '
  << gstart->ownedID_m << ' '
  << gstart->guardID_m << '\n';
  ostr << std::flush;
}
template <int Dim>
GridLayout<Dim>::GridLayout()
  : LayoutBase<Dim,GridLayoutData<Dim> >(new LayoutData_t()),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,const DistributedTag & )
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(gdom,
    GridPartition<Dim>(Loc<Dim>(1)),
    DistributedMapper<Dim>(GridPartition<Dim>(Loc<Dim>(1))))),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(gdom,
    GridPartition<Dim>(Loc<Dim>(1)),
    LocalMapper<Dim>())),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const GuardLayers_t &gcs,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(gdom,
    GridPartition<Dim>(Loc<Dim>(1),gcs),
    DistributedMapper<Dim>(
    GridPartition<Dim>(Loc<Dim>(1),gcs)))),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const GuardLayers_t &gcs,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(gdom,
    GridPartition<Dim>(Loc<Dim>(1),gcs),
    LocalMapper<Dim>())),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m =
      new LayoutData_t( gdom,
   GridPartition<Dim>(makeRGrid(gdom,blocks)),
        DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks)))
   );
  else
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(blocks),
 DistributedMapper<Dim>(GridPartition<Dim>(blocks))
    );
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(makeRGrid(gdom,blocks)),
    LocalMapper<Dim>());
  else
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(blocks),
    LocalMapper<Dim>());
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const GuardLayers_t &gcs,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
       DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks),gcs)));
  else
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(blocks,gcs),
       DistributedMapper<Dim>(GridPartition<Dim>(blocks,gcs)));
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const GuardLayers_t &gcs,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m = new LayoutData_t(gdom,
          GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
          LocalMapper<Dim>());
  else
    this->pdata_m = new LayoutData_t(gdom,
          GridPartition<Dim>(blocks,gcs),
          LocalMapper<Dim>());
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const GuardLayers_t &igcs,
       const GuardLayers_t &egcs,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m = new LayoutData_t( gdom,
      GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
      DistributedMapper<Dim>(
       GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs)));
  else
    this->pdata_m = new LayoutData_t( gdom,
      GridPartition<Dim>(blocks,igcs,egcs),
      DistributedMapper<Dim>(GridPartition<Dim>(blocks,igcs,egcs)));
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Loc<Dim> &blocks,
       const GuardLayers_t &igcs,
       const GuardLayers_t &egcs,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
    Observable<This_t>(*this)
{
  if (!gdom.empty())
    this->pdata_m = new LayoutData_t(
     gdom,
     GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
     LocalMapper<Dim>() );
  else
    this->pdata_m = new LayoutData_t( gdom,
    GridPartition<Dim>(blocks,igcs,egcs),
    LocalMapper<Dim>() );
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >(
      new LayoutData_t( grid,
   GridPartition<Dim>(grid),
   DistributedMapper<Dim>(GridPartition<Dim>(grid)))),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >(
      new LayoutData_t( grid,
   GridPartition<Dim>(grid),
   LocalMapper<Dim>())),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const GuardLayers_t &gcs,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
( new LayoutData_t( grid,
      GridPartition<Dim>(grid,gcs),
      DistributedMapper<Dim>(GridPartition<Dim>(grid,gcs) )) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const GuardLayers_t &gcs,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
( new LayoutData_t( grid,
      GridPartition<Dim>(grid,gcs),
      LocalMapper<Dim>()) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const GuardLayers_t &igcs,
       const GuardLayers_t &egcs,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(grid,
    GridPartition<Dim>(grid,igcs,egcs),
    DistributedMapper<Dim>(GridPartition<Dim>(grid,igcs,egcs)))),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
       const GuardLayers_t &igcs,
       const GuardLayers_t &egcs,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t( grid,
     GridPartition<Dim>(grid,igcs,egcs),
     LocalMapper<Dim>() ) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Partitioner &gpar,
       const DistributedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
(new LayoutData_t(gdom,
    gpar,
    DistributedMapper<Dim>(gpar)) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Partitioner &gpar,
       const ReplicatedTag &)
  : LayoutBase<Dim,GridLayoutData<Dim> >
      (new LayoutData_t(gdom,
            gpar,
   LocalMapper<Dim>()) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
template <class Partitioner>
GridLayout<Dim>::GridLayout(const Domain_t &gdom,
       const Partitioner &gpar,
       const ContextMapper<Dim> &cmap)
  : LayoutBase<Dim,GridLayoutData<Dim> >(new LayoutData_t(gdom, gpar, cmap) ),
    Observable<This_t>(*this)
{
  this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim>::GridLayout(const This_t &model)
  : LayoutBase<Dim,GridLayoutData<Dim> >(model.pdata_m),
    Observable<This_t>(*this)
{
   this->pdata_m->attach(*this);
}
template <int Dim>
GridLayout<Dim> &GridLayout<Dim>::operator=(const This_t &model)
{
  if (this != &model)
    {
      this->pdata_m->detach(*this);
      this->pdata_m = model.pdata_m;
      this->pdata_m->attach(*this);
    }
  return *this;
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const DistributedTag &)
{
  this->pdata_m->initialize( gdom,
         GridPartition<Dim>(),
         DistributedMapper<Dim>(GridPartition<Dim>()) );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const GuardLayers_t &gcs,
     const DistributedTag &)
{
  this->pdata_m->initialize( gdom,
         GridPartition<Dim>(gcs),
         DistributedMapper<Dim>(GridPartition<Dim>(gcs)) );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const DistributedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize(
    gdom,
    GridPartition<Dim>(makeRGrid(gdom,blocks)),
    DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks))));
  else
    this->pdata_m->initialize( gdom,
    GridPartition<Dim>(blocks),
    DistributedMapper<Dim>(GridPartition<Dim>(blocks)) );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const GuardLayers_t &gcs,
     const DistributedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize(
       gdom,
       GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
       DistributedMapper<Dim>(
                GridPartition<Dim>(makeRGrid(gdom,blocks),gcs)));
  else
    this->pdata_m->initialize(
   gdom,
   GridPartition<Dim>(blocks,gcs),
   DistributedMapper<Dim>(
     GridPartition<Dim>(blocks,gcs)) );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const GuardLayers_t &igcs,
     const GuardLayers_t &egcs,
     const DistributedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize(
      gdom,
      GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
      DistributedMapper<Dim>(
 GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs)));
  else
    this->pdata_m->initialize(
   gdom,
   GridPartition<Dim>(blocks,igcs,egcs),
   DistributedMapper<Dim>(
     GridPartition<Dim>(blocks,igcs,egcs)));
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const DistributedTag &)
{
  this->pdata_m->initialize( grid,
         GridPartition<Dim>(grid),
         DistributedMapper<Dim>(GridPartition<Dim>(grid)));
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const GuardLayers_t &gcs,
     const DistributedTag &)
{
  this->pdata_m->initialize( grid,
         GridPartition<Dim>(grid,gcs),
         DistributedMapper<Dim>(GridPartition<Dim>(grid,gcs)) );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const GuardLayers_t &igcs,
     const GuardLayers_t &egcs,
     const DistributedTag &)
{
  this->pdata_m->initialize(
        grid,
        GridPartition<Dim>(grid,igcs,egcs),
        DistributedMapper<Dim>(
   GridPartition<Dim>(grid,igcs,egcs)) );
}
template <int Dim>
template <class Partitioner>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Partitioner &gpar,
     const DistributedTag &)
{
  this->pdata_m->initialize(gdom,
        gpar,
        DistributedMapper<Dim>(gpar));
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const ReplicatedTag &)
{
  this->pdata_m->initialize( gdom, GridPartition<Dim>(),LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const GuardLayers_t &gcs,
     const ReplicatedTag &)
{
  this->pdata_m->initialize( gdom, GridPartition<Dim>(gcs),LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const ReplicatedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize(
   gdom,
   GridPartition<Dim>(makeRGrid(gdom,blocks)),
   LocalMapper<Dim>() );
  else
    this->pdata_m->initialize(
   gdom,
   GridPartition<Dim>(blocks),
   LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const GuardLayers_t &gcs,
     const ReplicatedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize( gdom,
    GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
    LocalMapper<Dim>() );
  else
    this->pdata_m->initialize( gdom,
    GridPartition<Dim>(blocks,gcs),
    LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Loc<Dim> &blocks,
     const GuardLayers_t &igcs,
     const GuardLayers_t &egcs,
     const ReplicatedTag &)
{
  if (!gdom.empty())
    this->pdata_m->initialize(
       gdom,
       GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
       LocalMapper<Dim>() );
  else
    this->pdata_m->initialize(
   gdom,
   GridPartition<Dim>(blocks,igcs,egcs),
   LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const ReplicatedTag &)
{
  this->pdata_m->initialize( grid,
         GridPartition<Dim>(grid),
         LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const GuardLayers_t &gcs,
     const ReplicatedTag &)
{
  this->pdata_m->initialize(
        grid,
        GridPartition<Dim>(grid,gcs),
        LocalMapper<Dim>() );
}
template <int Dim>
void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
     const GuardLayers_t &igcs,
     const GuardLayers_t &egcs,
     const ReplicatedTag &)
{
  this->pdata_m->initialize(
        grid,
        GridPartition<Dim>(grid,igcs,egcs),
        LocalMapper<Dim>() );
}
template <int Dim>
template <class Partitioner>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Partitioner &gpar,
     const ReplicatedTag &)
{
  this->pdata_m->initialize(gdom,
        gpar,
        LocalMapper<Dim>());
}
template <int Dim>
void GridLayout<Dim>::initialize(const Domain_t& idom,
     const List_t& nodes,
     const Loc<Dim>& blocks,
     bool hasIG, bool hasEG,
     const GuardLayers_t& ig,
     const GuardLayers_t& eg)
{
  this->pdata_m->initialize(idom,nodes,blocks,hasIG,hasEG,ig,eg);
}
template <int Dim>
template <class Partitioner>
void GridLayout<Dim>::initialize(const Domain_t &gdom,
     const Partitioner &gpar,
     const ContextMapper<Dim> &cmap)
{
  this->pdata_m->initialize(gdom, gpar, cmap);
}
template <int Dim>
template <class Ostream>
void GridLayout<Dim>::print(Ostream &ostr) const
{
  ostr << "GridLayout " << this->ID() << " on global domain "
       << this->domain() << ":" << '\n';
  ostr << "   Total subdomains: " << this->sizeGlobal() << '\n';
  ostr << "   Local subdomains: " << this->sizeLocal() << '\n';
  ostr << "  Remote subdomains: " << this->sizeRemote() << '\n';
  ostr << "        Grid blocks: " << this->blocks() << '\n';
  typename GridLayout<Dim>::const_iterator a;
  for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
    ostr << "  Global subdomain = " << *a << '\n';
  for (a = this->beginLocal(); a != this->endLocal(); ++a)
    ostr << "   Local subdomain = " << *a << '\n';
  for (a = this->beginRemote(); a != this->endRemote(); ++a)
    ostr << "  Remote subdomain = " << *a << '\n';
  this->pdata_m->print(ostr);
}
template<int Dim, int Dim2>
template <class Ostream>
void GridLayoutView<Dim, Dim2>::print(Ostream &ostr) const
{
  ostr << "GridLayoutView " << this->ID() << " on global domain "
       << this->domain() << ':' << '\n';
  ostr << "   Base ID:          " << this->baseID() << '\n';
  ostr << "   Base domain:      " << this->baseDomain() << '\n';
  ostr << "   Total subdomains: " << this->sizeGlobal() << '\n';
  ostr << "   Local subdomains: " << this->sizeLocal() << '\n';
  ostr << "  Remote subdomains: " << this->sizeRemote() << '\n';
  const_iterator a;
  for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
    ostr << "  Global subdomain = " << *a << '\n';
  for (a = this->beginLocal(); a != this->endLocal(); ++a)
    ostr << "   Local subdomain = " << *a << '\n';
  for (a = this->beginRemote(); a != this->endRemote(); ++a)
    ostr << "  Remote subdomain = " << *a << '\n';
}
template<int OriginalDim, class ViewedEngineTag>
struct ViewEngine
{
  ViewEngine() {};
  ~ViewEngine() {};
 };
template<int Dim, class T, int OriginalDim, class ViewedEngineTag>
class Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> >
{
public:
  typedef ViewEngine<OriginalDim, ViewedEngineTag> Tag_t;
  typedef Engine<Dim, T, Tag_t> This_t;
  typedef This_t Engine_t;
  typedef Engine<OriginalDim, T, ViewedEngineTag> ViewedEngine_t;
  typedef ViewIndexer<Dim, OriginalDim> Indexer_t;
  typedef Interval<Dim> Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  enum { dimensions = Dim };
  enum { hasDataObject = ViewedEngine_t::hasDataObject };
  enum { dynamic = false };
  enum { zeroBased = true };
  enum { multiPatch = ViewedEngine_t::multiPatch };
  Engine()
    : eng_m()
  {
  }
  template<class DT>
  Engine(const Engine<Dim, T, ViewedEngineTag> &e, const Domain<Dim, DT> &dom)
    : eng_m(e), indexer_m(dom)
  {
    PoomaCTAssert<(OriginalDim == Dim)>::test();
  }
  template<class DT>
  Engine(const Engine<OriginalDim, T, ViewedEngineTag> &e,
  const SliceDomain<DT> &dom)
    : eng_m(e), indexer_m(dom)
  {
    PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<(DT::dimensions == OriginalDim)>::test();
  }
  template<class Domain>
  Engine(const Engine<Dim, T, ViewedEngineTag> &e, const Node<Domain> &node)
    : eng_m(e), indexer_m(node.domain())
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
  }
  Engine(const Engine<Dim, T, ViewedEngineTag> &e, const INode<Dim> &inode)
    : eng_m(e), indexer_m(inode.domain())
  { }
  template<class DT>
  Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
  const Domain<Dim, DT> &dom)
    : eng_m(e.viewedEngine()), indexer_m(e.indexer(), dom)
  {
  }
  template<int OrigDim, class DT>
  Engine(const Engine<OrigDim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
  const SliceDomain<DT> &dom)
    : eng_m(e.viewedEngine()), indexer_m(e.indexer(), dom)
  {
    PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
    PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
  }
  template<class Domain>
  Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
  const Node<Domain> &node)
    : eng_m(e.viewedEngine()), indexer_m(e.indexer(), node.domain())
  {
    PoomaCTAssert<(Domain::dimensions == Dim)>::test();
  }
  Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
  const INode<Dim> &inode)
    : eng_m(e.viewedEngine()), indexer_m(e.indexer(), inode.domain())
  { }
  Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> >
  &model)
    : eng_m(model.viewedEngine()), indexer_m(model.indexer())
  { }
  This_t &operator=(const This_t &rhs)
  {
    eng_m = rhs.viewedEngine();
    indexer_m = rhs.indexer();
    return *this;
  }
  inline Element_t read(int i0) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1, int i2) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, i2, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1, int i2, int i3) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, i2, i3, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, i2, i3, i4, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, i2, i3, i4, i5, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4,
   int i5, int i6) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(i0, i1, i2, i3, i4, i5, i6, oloc);
    return eng_m.read(oloc);
  }
  inline Element_t read(const Loc<Dim> &loc) const
  {
    Loc<OriginalDim> oloc;
    indexer_m.translate(loc, oloc);
    return eng_m.read(oloc);
  }
  inline const Domain_t &domain() const { return indexer_m.domain(); }
  inline Layout_t layout() const { return Layout_t(domain()); }
  inline int first(int i) const
  {
    ;
    return 0;
  }
  inline const ViewedEngine_t &viewedEngine() const { return eng_m; }
  inline const Indexer_t &indexer() const { return indexer_m; }
  template<class RequestType>
  inline
  typename DataObjectRequest<RequestType>::Type_t
  dataObjectRequest(const DataObjectRequest<RequestType>& f) const
  {
    return eng_m.dataObjectRequest(f);
  }
private:
  ViewedEngine_t eng_m;
  Indexer_t indexer_m;
};
template <int Dim, class T, int D2, class ViewedTag>
struct NewEngine< Engine<Dim,T,ViewEngine<D2,ViewedTag> >, Interval<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Type_t;
};
template <int Dim, class T, int D2, class ViewedTag>
struct NewEngine< Engine<Dim,T,ViewEngine<D2,ViewedTag> >, Range<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Type_t;
};
template <int Dim, class T, int D2, class ViewedTag, int SliceDim>
struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  SliceInterval<Dim, SliceDim> >
{
  typedef Engine<SliceDim, T, ViewEngine<D2, ViewedTag> > Type_t;
};
template <int Dim, class T, int D2, class ViewedTag, int SliceDim>
struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  SliceRange<Dim, SliceDim> >
{
  typedef Engine<SliceDim, T, ViewEngine<D2, ViewedTag> > Type_t;
};
template <int Dim, class T, int D2, class ViewedTag>
struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >, INode<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
  typedef typename Engine_t::ViewedEngine_t ViewedEngine_t;
  typedef typename NewEngine<ViewedEngine_t,
    INode<D2> >::Type_t NewViewedEngine_t;
  typedef typename NewEngine<NewViewedEngine_t,
    SliceRange<D2, Dim> >::Type_t Type_t;
};
template <int Dim, class T, int D2, class ViewedTag>
struct NewEngineEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  INode<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
  typedef typename NewEngine< Engine_t, INode<Dim> >::NewViewedEngine_t Type_t;
  static inline Type_t
  apply(const Engine_t &e, const INode<Dim> &inode)
  {
    Range<D2> base;
    e.indexer().localToBase(inode.domain(), base);
    Interval<D2> baseInt;
    int i;
    for (i = 0; i < D2; ++i)
    {
      baseInt[i] = Interval<1>(base[i].first(), base[i].last());
    }
    INode<D2> viewNode(inode, baseInt);
    return Type_t(e.viewedEngine(), viewNode);
  }
};
template <int Dim, class T, int D2, class ViewedTag>
struct NewEngineDomain< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  INode<Dim> >
{
  typedef SliceRange<D2, Dim> Type_t;
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
  static inline Type_t
  apply(const Engine_t &e, const INode<Dim> &inode)
  {
    SliceRange<D2, Dim> base;
    e.indexer().localToBase(inode.domain(), base);
    base.totalDomain() -= base.totalDomain().firsts();
    base.setSliceFromTotal();
    return base;
  }
};
template <int Dim, class T, class ViewedTag>
struct NewEngine<Engine<Dim, T, ViewEngine<Dim, ViewedTag> >, INode<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
  typedef typename Engine_t::ViewedEngine_t ViewedEngine_t;
  typedef typename NewEngine<ViewedEngine_t,
    INode<Dim> >::Type_t NewViewedEngine_t;
  typedef typename NewEngine<NewViewedEngine_t,
    Range<Dim> >::Type_t Type_t;
};
template <int Dim, class T, class ViewedTag>
struct NewEngineEngine<Engine<Dim, T, ViewEngine<Dim, ViewedTag> >,
  INode<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
  typedef typename NewEngine<Engine_t, INode<Dim> >::NewViewedEngine_t Type_t;
  static inline Type_t
  apply(const Engine_t &e, const INode<Dim> &inode)
  {
    Range<Dim> base;
    e.indexer().localToBase(inode.domain(), base);
    Interval<Dim> baseInt;
    int i;
    for (i = 0; i < Dim; ++i)
    {
      baseInt[i] = Interval<1>(base[i].first(), base[i].last());
    }
    INode<Dim> viewNode(inode, baseInt);
    return Type_t(e.viewedEngine(), viewNode);
  }
};
template <int Dim, class T, class ViewedTag>
struct NewEngineDomain< Engine<Dim, T, ViewEngine<Dim, ViewedTag> >,
  INode<Dim> >
{
  typedef Range<Dim> Type_t;
  typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
  static inline Type_t
  apply(const Engine_t &e, const INode<Dim> &inode)
  {
    Range<Dim> base;
    e.indexer().localToBase(inode.domain(), base);
    base -= base.firsts();
    return base;
  }
};
template<int OriginalDim, class ViewedEngineTag>
struct EvaluatorEngineTraits<ViewEngine<OriginalDim, ViewedEngineTag> >
{
  typedef typename EvaluatorEngineTraits<ViewedEngineTag>::Evaluator_t
  Evaluator_t;
};
template<int Dim, int ViewD1, int ViewD2>
class ViewIntersector
{
public:
  typedef IntersectorData<Dim> IntersectorData_t;
  typedef ViewIntersector<Dim, ViewD1, ViewD2> This_t;
  typedef typename IntersectorData_t::IDContainer_t IDContainer_t;
  typedef typename IntersectorData_t::BaseDomain_t BaseDomain_t;
  typedef typename IntersectorData_t::BaseDomainContainer_t
                                                        BaseDomainContainer_t;
  typedef typename IntersectorData_t::INode_t INode_t;
  typedef typename IntersectorData_t::INodeContainer_t INodeContainer_t;
  typedef typename IntersectorData_t::const_iterator const_iterator;
  typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
  typedef ViewIndexer<ViewD1, ViewD2> Indexer_t;
  enum { dimensions = Dim };
  ViewIntersector(const ViewIndexer<ViewD1, ViewD2> &indexer,
    const Intersector<Dim> &model)
    : pdata_m(model.data()), indexer_m(indexer)
  {
    PoomaCTAssert<(Dim == ViewD1)>::test();
  }
  This_t &operator=(const This_t &model)
  {
    if (this != &model)
    {
      indexer_m = model.indexer_m;
      pdata_m = model.pdata_m;
    }
    return *this;
  }
  ~ViewIntersector() { }
  inline DataPtr_t &data() { return pdata_m; }
  inline const DataPtr_t &data() const { return pdata_m; }
  inline const_iterator begin() const { return data()->inodes_m.begin(); }
  inline const_iterator end() const { return data()->inodes_m.end(); }
  template<class Engine>
  inline
  void intersect(const Engine &e)
  {
    int n = data()->ids_m.size();
    typedef INode<ViewD2> INode2_t;
    typedef std::vector<INode2_t> INode2Container_t;
    INode2Container_t inodes2;
    int id = e.layout().ID();
    if (n == 0)
    {
      Range<ViewD2> base = indexer_m.baseDomain();
      e.layout().touches(base,
    std::back_inserter(inodes2),
    TouchesConstructINode<ViewD2>(id, GlobalIDDataBase::
             nullNodeKey(),
             &(data()->gidStore_m))
    );
      int i;
      int ni = inodes2.size();
      for (i = 0; i < ni; i++)
      {
 Interval<Dim> ival1;
 indexer_m.baseToLocalInterval(inodes2[i].domain(), ival1);
 INode<Dim> inode(inodes2[i], ival1);
 data()->inodes_m.push_back(inode);
      }
    }
    else
    {
      int ni = data()->inodes_m.size();
      int i;
      for (i = 0; i < ni; i++)
      {
 Range<ViewD2> range;
 indexer_m.localToBase(data()->inodes_m[i].domain(), range);
 e.layout().touches(range,
      std::back_inserter(inodes2),
      INode<ViewD2>::touchesConstructINode(id,
         data()->inodes_m[i])
      );
      }
      data()->inodes_m.erase(data()->inodes_m.begin(),
        data()->inodes_m.begin() + ni);
      ni = inodes2.size();
      for (i = 0; i < ni; i++)
      {
 Interval<Dim> ival1;
 indexer_m.baseToLocalInterval(inodes2[i].domain(), ival1);
 INode<Dim> inode(inodes2[i], ival1);
 data()->inodes_m.push_back(inode);
      }
    }
  }
  template<class Engine, int Dim2>
  inline
  bool intersect(const Engine &l, const GuardLayers<Dim2> &guard)
  {
    return (data()->intersect(l,guard));
  }
private:
  DataPtr_t pdata_m;
  Indexer_t indexer_m;
};
template <int Dim, class T, int D2, class ViewedTag, class Intersect>
struct LeafFunctor< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  ExpressionApply<IntersectorTag<Intersect> > >
{
  typedef int Type_t;
  typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
  static Type_t
  apply(const Engine_t &,
 const ExpressionApply<IntersectorTag<Intersect> > &,
 const WrappedInt<false> &)
  {
    return 0;
  }
  static Type_t
  apply(const Engine_t &engine,
 const ExpressionApply<IntersectorTag<Intersect> > &tag,
 const WrappedInt<true> &)
  {
    enum { d1 = Intersect::dimensions };
    ViewIntersector<d1, Dim, D2> newIntersector(engine.indexer(),
      tag.tag().intersector_m);
    ExpressionApply<IntersectorTag<ViewIntersector<d1, Dim, D2> > >
      newTag(newIntersector);
    forEach(engine.viewedEngine(), newTag, NullCombine());
    return 0;
  }
  static Type_t
  apply(const Engine_t &engine,
 const ExpressionApply<IntersectorTag<Intersect> > &tag)
  {
    enum { multiPatch =
    Engine<Dim, T, ViewEngine<D2, ViewedTag> >::multiPatch };
    return apply(engine, tag, WrappedInt<multiPatch>());
  }
};
template<class RequestType> class DataObjectRequest;
template <int Dim, class T, int D2, class ViewedTag, class RequestType>
struct EngineFunctor< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
  DataObjectRequest<RequestType> >
{
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, ViewEngine<D2, ViewedTag> > &engine,
 const DataObjectRequest<RequestType> &tag)
  {
    return engineFunctor(engine.viewedEngine(), tag);
  }
};
template <int D, class T, int D2, class E, class Tag>
struct LeafFunctor<Engine<D, T, ViewEngine<D2, E> >, ExpressionApply<Tag> >
{
  typedef Engine<D, T, ViewEngine<D2, E> > Subject_t;
  typedef typename Subject_t::ViewedEngine_t Engine_t;
  typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  static
  Type_t apply(const Subject_t &engine, const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(engine.viewedEngine(), tag);
  }
};
template<class Functor>
struct IndexFunction
{
  typedef Functor Functor_t;
};
template<int Dim, class Functor>
struct IndexFunctionView
{ };
template<int Dim, class T, class Functor>
class Engine<Dim, T, IndexFunction<Functor> >
{
public:
  typedef IndexFunction<Functor> Tag_t;
  typedef Engine<Dim, T, Tag_t> This_t;
  typedef This_t Engine_t;
  typedef Interval<Dim> Domain_t;
  typedef DomainLayout<Dim> Layout_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  enum { dimensions = Dim };
  enum { hasDataObject = false };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = false };
  Engine() { }
  explicit Engine(const Domain_t &domain, const Functor &f = Functor())
  : funct_m(f), domain_m(domain)
  {
  }
  template<class Layout>
  explicit Engine(const Layout &layout, const Functor &f = Functor())
  : funct_m(f), domain_m(layout.domain())
  {
  }
  Engine(const This_t &model)
  : funct_m(model.functor()), domain_m(model.domain())
  {
  }
  This_t &operator=(const This_t &rhs)
  {
    domain_m = rhs.domain();
    funct_m = rhs.functor();
    return *this;
  }
  inline Element_t read(int i0) const
    {
      return funct_m(i0);
    }
  inline Element_t read(int i0, int i1) const
    {
      return funct_m(i0, i1);
    }
  inline Element_t read(int i0, int i1, int i2) const
    {
      return funct_m(i0, i1, i2);
    }
  inline Element_t read(int i0, int i1, int i2, int i3) const
    {
      return funct_m(i0, i1, i2, i3);
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
    {
      return funct_m(i0, i1, i2, i3, i4);
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4,
    int i5) const
    {
      return funct_m(i0, i1, i2, i3, i4, i5);
    }
  inline Element_t read(int i0, int i1, int i2, int i3, int i4,
    int i5, int i6) const
    {
      return funct_m(i0, i1, i2, i3, i4, i5, i6);
    }
  inline Element_t read(const Loc<1> &loc) const
    {
      return funct_m(loc[0].first());
    }
  inline Element_t read(const Loc<2> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first());
    }
  inline Element_t read(const Loc<3> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first(), loc[2].first());
    }
  inline Element_t read(const Loc<4> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
        loc[3].first());
    }
  inline Element_t read(const Loc<5> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
        loc[3].first(), loc[4].first());
    }
  inline Element_t read(const Loc<6> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
        loc[3].first(), loc[4].first(), loc[5].first());
    }
  inline Element_t read(const Loc<7> &loc) const
    {
      return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
        loc[3].first(), loc[4].first(), loc[5].first(), loc[6].first());
    }
  inline const Domain_t &domain() const { return domain_m; }
  void setDomain(const Domain_t &dom) { domain_m = dom; }
  inline int first(int i) const
  {
    ;
    return domain_m[i].first();
  }
  Layout_t layout() const
  {
    return Layout_t(domain_m);
  }
  const Functor &functor() const { return funct_m; }
  void setFunctor(const Functor &f) { funct_m = f; }
private:
  Functor funct_m;
  Domain_t domain_m;
};
template <int Dim, class T, class Functor>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Interval<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
template <int Dim, class T, class Functor>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Range<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
template <int Dim, class T, class Functor, int SliceDim>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >,
  SliceInterval<Dim, SliceDim> >
{
  typedef Engine<SliceDim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
template <int Dim, class T, class Functor, int SliceDim>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >,
  SliceRange<Dim, SliceDim> >
{
  typedef Engine<SliceDim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
template <int Dim, class T, class Functor, class Domain>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Node<Domain> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
template <int Dim, class T, class Functor>
struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, INode<Dim> >
{
  typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
};
class IotaFunctor
{
public:
  inline IotaFunctor() { }
  inline IotaFunctor(const IotaFunctor &) { }
  inline IotaFunctor &operator=(const IotaFunctor &) { return *this; }
  inline
  Vector<1, int> operator()(int i1) const
  {
    return Vector<1, int>(i1);
  }
  inline
  Vector<2, int> operator()(int i1, int i2) const
  {
    return Vector<2, int>(i1, i2);
  }
  inline
  Vector<3, int> operator()(int i1, int i2, int i3) const
  {
    return Vector<3, int>(i1, i2, i3);
  }
};
template<int Dim>
struct Iota
{
  typedef Array<Dim, Vector<Dim, int>, IndexFunction<IotaFunctor> >
    Iota_t;
  typedef typename ComponentView<Loc<1>, Iota_t>::Type_t Index_t;
};
template<int Dim>
inline
typename Iota<Dim>::Iota_t
iota(const Interval<Dim> &domain)
{
  typedef typename Iota<Dim>::Iota_t Iota_t;
  return Iota_t(domain);
}
template<int Dim>
inline
typename Iota<Dim>::Index_t
iotaIndex(const Interval<Dim> &domain, int i)
{
  typedef typename Iota<Dim>::Iota_t Iota_t;
  return Iota_t(domain).comp(i);
}
inline
Array<1, Vector<1, int>, IndexFunction<IotaFunctor> >
iota(int i1);
inline
Array<1, Vector<1, int>, IndexFunction<IotaFunctor> >
iota(int i1)
{
  return Array<1, Vector<1, int>,
    IndexFunction<IotaFunctor> >(Interval<1>(i1));
}
inline
Array<2, Vector<2, int>, IndexFunction<IotaFunctor> >
iota(int i1, int i2);
inline
Array<2, Vector<2, int>, IndexFunction<IotaFunctor> >
iota(int i1, int i2)
{
  return Array<2, Vector<2, int>,
    IndexFunction<IotaFunctor> >(Interval<2>(i1, i2));
}
inline
Array<3, Vector<3, int>, IndexFunction<IotaFunctor> >
iota(int i1, int i2, int i3);
inline
Array<3, Vector<3, int>, IndexFunction<IotaFunctor> >
iota(int i1, int i2, int i3)
{
  return Array<3, Vector<3, int>,
    IndexFunction<IotaFunctor> >(Interval<3>(i1, i2, i3));
}
template<class Functor, class ArgumentType>
struct FunctorResult
{
  typedef ArgumentType Type_t;
};
template<int D, class T, class E> class Array;
template<class UserFunction, class Expression>
struct UserFunctionEngine
{ };
template<int D, class T, class UserFunction, class Expression>
class Engine< D, T, UserFunctionEngine<UserFunction,Expression> >
{
public:
  typedef UserFunctionEngine<UserFunction,Expression> Tag_t;
  typedef Engine<D,T,Tag_t> This_t;
  typedef This_t Engine_t;
  typedef typename Expression::Domain_t Domain_t;
  typedef typename Expression::Layout_t Layout_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  typedef typename Expression::Engine_t ExprEngine_t;
  enum { dimensions = D };
  enum { hasDataObject = ExprEngine_t::hasDataObject };
  enum { dynamic = false };
  enum { zeroBased = ExprEngine_t::zeroBased };
  enum { multiPatch = ExprEngine_t::multiPatch };
  Engine(const UserFunction& s, const Expression& e)
    : userFunction_m(s), expression_m(e) {}
  template<class OtherE, class Domain>
  Engine(const Engine<D,T,UserFunctionEngine<UserFunction,OtherE> >& e,
  const Domain& d)
    : userFunction_m(e.userFunction()),
      expression_m( e.expression(), d ) {}
  inline Element_t read(const Loc<D> &loc) const
  {
    return userFunction_m(expression_m.read(loc));
  }
  inline Element_t read(int i) const
  {
    return userFunction_m(expression_m.read(i));
  }
  inline Element_t read(int i, int j) const
  {
    return userFunction_m(expression_m.read(i,j));
  }
  inline Element_t read(int i, int j, int k) const
  {
    return userFunction_m(expression_m.read(i,j,k));
  }
  inline Element_t read(int i, int j, int k, int l) const
  {
    return userFunction_m(expression_m.read(i,j,k,l));
  }
  inline Element_t read(int i, int j, int k, int l,int m) const
  {
    return userFunction_m(expression_m.read(i,j,k,l,m));
  }
  inline Element_t read(int i, int j, int k, int l,int m,int n) const
  {
    return userFunction_m(expression_m.read(i,j,k,l,m,n));
  }
  inline Element_t read(int i, int j, int k, int l,int m,int n,int o) const
  {
    return userFunction_m(expression_m.read(i,j,k,l,m,n,o));
  }
  inline Element_t operator()(const Loc<D> &loc) const
  {
    return userFunction_m(expression_m(loc));
  }
  inline Element_t operator()(int i) const
  {
    return userFunction_m(expression_m(i));
  }
  inline Element_t operator()(int i, int j) const
  {
    return userFunction_m(expression_m(i,j));
  }
  inline Element_t operator()(int i, int j, int k) const
  {
    return userFunction_m(expression_m(i,j,k));
  }
  inline Element_t operator()(int i, int j, int k, int l) const
  {
    return userFunction_m(expression_m(i,j,k,l));
  }
  inline Element_t operator()(int i, int j, int k, int l,int m) const
  {
    return userFunction_m(expression_m(i,j,k,l,m));
  }
  inline Element_t operator()(int i, int j, int k, int l,int m,int n) const
  {
    return userFunction_m(expression_m(i,j,k,l,m,n));
  }
  inline Element_t operator()(int i, int j, int k, int l,int m,int n,int o)
    const
  {
    return userFunction_m(expression_m(i,j,k,l,m,n,o));
  }
  inline const Domain_t& domain() const { return expression_m.domain(); }
  inline int first(int d) const
  {
    return expression_m.first(d);
  }
  const UserFunction& userFunction() const { return userFunction_m; }
  const Expression& expression() const { return expression_m; }
  template<class RequestType>
  inline
  typename DataObjectRequest<RequestType>::Type_t
  dataObjectRequest(const DataObjectRequest<RequestType>& f) const
  {
    return engineFunctor(expression_m.engine(),f);
  }
private:
  UserFunction userFunction_m;
  Expression expression_m;
};
template<class Func> class UserFunction;
template<class Func,int D,class T,class E>
struct View1<UserFunction<Func>,Array<D,T,E> >
{
  typedef Array<D,T,E> Expr_t;
  typedef UserFunctionEngine<Func,Expr_t> NewTag_t;
  typedef typename FunctorResult<Func,T>::Type_t NewT_t;
  typedef Engine<D,NewT_t,NewTag_t> NewEngine_t;
  typedef Array<D,NewT_t,NewTag_t> Type_t;
};
template<class Func>
class UserFunction
{
public:
  UserFunction()
  { }
  UserFunction(const Func &func)
    : function_m(func)
  { }
  template<class Init>
  UserFunction(const Init &init)
    : function_m(init)
  { }
  template<class I1, class I2>
  UserFunction(const I1 &i1, const I2 &i2)
    : function_m(i1,i2)
  { }
  template<class I1, class I2, class I3>
  UserFunction(const I1 &i1, const I2 &i2, const I3 &i3)
    : function_m(i1,i2,i3)
  { }
  template<class I1, class I2, class I3, class I4>
  UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4)
    : function_m(i1,i2,i3,i4)
  { }
  template<class I1, class I2, class I3, class I4, class I5>
  UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
        const I5 &i5)
    : function_m(i1,i2,i3,i4,i5)
  { }
  template<class I1, class I2, class I3, class I4, class I5, class I6>
  UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
        const I5 &i5, const I6 &i6)
    : function_m(i1,i2,i3,i4,i5,i6)
  { }
  template<class I1, class I2, class I3, class I4, class I5, class I6,
    class I7>
  UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
        const I5 &i5, const I6 &i6, const I7 &i7)
    : function_m(i1,i2,i3,i4,i5,i6,i7)
  { }
  template<int D, class T, class E>
  typename View1<UserFunction<Func>,Array<D,T,E> >::Type_t
  operator()(const Array<D,T,E>& expr) const
  {
    typedef typename View1<UserFunction<Func>,Array<D,T,E> >::NewEngine_t
      NewEngine_t;
    typedef typename View1<UserFunction<Func>,Array<D,T,E> >::Type_t
      Type_t;
    return Type_t(NewEngine_t(function(),expr));
  }
  inline Func &function() { return function_m; }
  inline const Func &function() const { return function_m; }
private:
  Func function_m;
};
template <int Dim, class T, class S, class E, class Domain>
struct NewEngine< Engine<Dim,T,UserFunctionEngine<S,E> >, Domain >
{
  typedef typename View1<E,Domain>::Type_t NewExpr_t;
  typedef UserFunctionEngine<S,NewExpr_t> NewTag_t;
  typedef typename NewExpr_t::Element_t OldElement_t;
  typedef typename FunctorResult<S,OldElement_t>::Type_t NewElement_t;
  typedef Engine<Dim,NewElement_t,NewTag_t> Type_t;
};
template<class UserFunction,class Expression>
struct EvaluatorEngineTraits<UserFunctionEngine<UserFunction,Expression> >
{
  typedef typename Expression::Engine_t Engine_t;
  typedef typename Engine_t::Tag_t Tag_t;
  typedef typename EvaluatorEngineTraits<Tag_t>::Evaluator_t Evaluator_t;
};
template <int Dim, class T, class S, class E, class EFTag>
struct EngineFunctor<Engine<Dim, T, UserFunctionEngine<S, E> >, EFTag>
{
  typedef typename EngineFunctor<E, EFTag>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, UserFunctionEngine<S, E> > &engine,
 const EFTag &tag)
  {
    return engineFunctor(engine.expression(), tag);
  }
};
template <int D, class T, class Func, class Expr, class Tag>
struct LeafFunctor<Engine<D, T, UserFunctionEngine<Func, Expr> >,
  EngineView<Tag> >
{
  typedef LeafFunctor<Expr, EngineView<Tag> > LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t NewViewed_t;
  typedef Engine<D, T, UserFunctionEngine<Func, NewViewed_t> > Type_t;
  static
  Type_t apply(const Engine<D, T, UserFunctionEngine<Func, Expr> > &engine,
        const EngineView<Tag> &tag)
  {
    return Type_t(engine.userFunction(),
    LeafFunctor_t::apply(engine.expression(), tag));
  }
};
template <int D, class T, class Func, class Expr, class Tag>
struct LeafFunctor<Engine<D, T, UserFunctionEngine<Func, Expr> >,
  ExpressionApply<Tag> >
{
  typedef LeafFunctor<Expr, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  static
  Type_t apply(const Engine<D, T, UserFunctionEngine<Func, Expr> > &engine,
        const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(engine.expression(), tag);
  }
};
template<int D, class T, class E> class Array;
template<class M, class T, class E> class Field;
template<class ST> class Stencil;
template<class Function, class Expression>
struct StencilEngine
{
  typedef typename Expression::Element_t ViewedElement_t;
  typedef typename FunctorResult<Function,ViewedElement_t>::Type_t Element_t;
};
template<class Function, int D>
inline
Interval<D> insetDomain(const Function &f, const Interval<D> &domain)
{
  Interval<D> ret;
  int d;
  for (d = 0; d < D; ++d)
  {
    ret[d] = Interval<1>(domain[d].first() + f.lowerExtent(d),
    domain[d].last() - f.upperExtent(d));
  }
  return ret;
}
template<int D, class T, class Function, class Expression>
class Engine<D, T, StencilEngine<Function, Expression> >
{
public:
  typedef StencilEngine<Function, Expression> Tag_t;
  typedef Engine<D, T, Tag_t> This_t;
  typedef This_t Engine_t;
  typedef Interval<D> Domain_t;
  typedef DomainLayout<D> Layout_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  typedef typename Expression::Engine_t ExprEngine_t;
  enum { dimensions = D };
  enum { hasDataObject = ExprEngine_t::hasDataObject };
  enum { dynamic = false };
  enum { multiPatch = ExprEngine_t::multiPatch };
  enum { zeroBased = true };
  Engine()
    : function_m(), expression_m(), domain_m(Pooma::NoInit())
  {
  }
  template <class Layout2>
  explicit Engine(const Layout2 &layout)
    : function_m(), expression_m(), domain_m(layout.domain())
  {
  }
  Engine(const Function &f, const Expression &e)
    : function_m(f), expression_m(e), domain_m(Pooma::NoInit())
  {
    Interval<D> inset = insetDomain(f, e.domain());
    int d;
    for (d = 0; d < D; ++d)
    {
      domain_m[d] = Interval<1>(inset[d].length());
      offset_m[d] = function().lowerExtent(d);
    }
  }
  Engine(const Function &f, const Expression &e, const Interval<D> &domain)
    : function_m(f), expression_m(e), domain_m(Pooma::NoInit())
  {
    int d;
    for (d = 0; d < D; ++d)
    {
      domain_m[d] = Interval<1>(domain[d].length());
      offset_m[d] = domain[d].first();
    }
  }
  template<class OtherE>
  Engine(const Engine<D, T, StencilEngine<Function, OtherE> > &e,
  const INode<D> &node)
    : function_m(e.function()),
      expression_m(e.expression()(e.viewDomain(node))),
      domain_m(Pooma::NoInit())
  {
    int d;
    for (d = 0; d < D; ++d)
    {
      domain_m[d] = Interval<1>(node.domain()[d].length());
      offset_m[d] = function().lowerExtent(d);
    }
  }
  Engine(const Engine_t &e,
  const Interval<D> &domain)
    : function_m(e.function()),
      expression_m(e.expression()),
      domain_m(Pooma::NoInit())
  {
    int d;
    for (d = 0; d < D; ++d)
    {
      domain_m[d] = Interval<1>(domain[d].length());
      offset_m[d] = e.offset_m[d] + domain[d].first();
    }
  }
  template <int Dim, class Tx, class EngineTag>
  void initExpressionFromModel(const Array<Dim, Tx, EngineTag>& model)
  {
    expression_m.engine() = model.engine();
  }
  template <class Mesh, class Tx, class EngineTag>
  void initExpressionFromModel(const Field<Mesh, Tx, EngineTag>& model)
  {
    expression_m.fieldEngine() = model.fieldEngine();
  }
  This_t &operator=(const This_t &model)
  {
    domain_m = model.domain();
    function_m = model.function();
    initExpressionFromModel(model.expression());
    for (int d = 0; d < D; ++d)
    {
      domain_m[d] = model.domain()[d];
      offset_m[d] = model.offset(d);
    }
    return *this;
  }
  inline Element_t read(int i) const
  {
    return function()(expression_m,
        i + offset_m[0]);
  }
  inline Element_t read(int i, int j) const
  {
    return function()(expression_m,
        i + offset_m[0],
        j + offset_m[1]);
  }
  inline Element_t read(int i, int j, int k) const
  {
    return function()(expression_m,
        i + offset_m[0],
        j + offset_m[1],
        k + offset_m[2]);
  }
  inline Element_t read(const Loc<1> &loc) const
  {
    return function()(expression_m,
        loc[0].first() + offset_m[0]);
  }
  inline Element_t read(const Loc<2> &loc) const
  {
    return function()(expression_m,
        loc[0].first() + offset_m[0],
        loc[1].first() + offset_m[1]);
  }
  inline Element_t read(const Loc<3> &loc) const
  {
    return function()(expression_m,
        loc[0].first() + offset_m[0],
        loc[1].first() + offset_m[1],
        loc[2].first() + offset_m[2]);
  }
  inline Element_t operator()(int i) const
  {
    return read(i);
  }
  inline Element_t operator()(int i, int j) const
  {
    return read(i, j);
  }
  inline Element_t operator()(int i, int j, int k) const
  {
    return read(i, j, k);
  }
  inline const Domain_t &domain() const { return domain_m; }
  inline Layout_t layout() const { return Layout_t(domain_m); }
  inline int first(int i) const
  {
    return 0;
  }
  inline
  Interval<D> viewDomain(const Interval<D> &domain) const
  {
    Interval<D> ret;
    int d;
    for (d = 0; d < D; ++d)
    {
      ret[d] =
 Interval<1>(
      domain[d].first() + offset_m[d]
      - function().lowerExtent(d),
      domain[d].last() + offset_m[d] + function().upperExtent(d)
      );
    }
    return ret;
  }
  inline
  INode<D> viewDomain(const INode<D> &inode) const
  {
    return INode<D>(inode, viewDomain(inode.domain()));
  }
  inline
  Interval<D> intersectDomain() const
  {
    Interval<D> ret;
    int d;
    for (d = 0; d < D; ++d)
    {
      ret[d] =
 Interval<1>(
      domain_m[d].first() + offset_m[d],
      domain_m[d].last() + offset_m[d]
      );
    }
    return ret;
  }
  inline const Function &function() const { return function_m; }
  inline const Expression &expression() const { return expression_m; }
  int offset(int d) const { return offset_m[d]; }
private:
  Function function_m;
  Expression expression_m;
  Interval<D> domain_m;
  int offset_m[D];
};
template<class Function, int D, class T, class E>
struct View1<Stencil<Function>, Array<D, T, E> >
{
  typedef Array<D,T,E> ArrayIn_t;
  typedef StencilEngine<Function, ArrayIn_t> NewTag_t;
  typedef typename NewTag_t::Element_t NewT_t;
  typedef Engine<D, NewT_t, NewTag_t> NewEngine_t;
  typedef Array<D, NewT_t, NewTag_t> Type_t;
  static inline
  Type_t make(const Stencil<Function> &s, const ArrayIn_t &a)
  {
    return Type_t(NewEngine_t(s.function(), a,
         insetDomain(s.function(), a.domain())
         ));
  }
};
template<class Function, class ArrayIn, int Dim>
struct View2<Stencil<Function>,ArrayIn,Interval<Dim> >
{
  enum { dim = ArrayIn::dimensions };
  typedef Interval<Dim> ViewDom_t;
  typedef typename View1<ArrayIn,ViewDom_t>::Type_t Expression_t;
  typedef StencilEngine<Function, Expression_t> NewTag_t;
  typedef typename NewTag_t::Element_t NewT_t;
  typedef Engine<dim,NewT_t,NewTag_t> NewEngine_t;
  typedef Array<dim,NewT_t,NewTag_t> Type_t;
  static inline
  Type_t make(const Stencil<Function> &s, const ArrayIn &a,
       const Interval<Dim> &d)
  {
    return Type_t(NewEngine_t(s.function(), a(s.inputDomain(d))));
  }
};
template<class Function, class ArrayIn, class Dom>
struct View2<Stencil<Function>, ArrayIn, Dom>
{
  enum { dim2 = ArrayIn::dimensions };
  enum { dim = Dom::dimensions };
  typedef Interval<dim2> ViewDom_t;
  typedef typename View1<ArrayIn, ViewDom_t>::Type_t Expression_t;
  typedef StencilEngine<Function, Expression_t> StencilTag_t;
  typedef typename StencilTag_t::Element_t NewT_t;
  typedef ViewEngine<dim2, StencilTag_t> NewTag_t;
  typedef Engine<dim,NewT_t,NewTag_t> NewEngine_t;
  typedef Array<dim,NewT_t,NewTag_t> Type_t;
  static inline
  Type_t make(const Stencil<Function> &s, const ArrayIn &a, const Dom &dom)
  {
    ViewDom_t viewDom = s.inputDomain(dom);
    ViewDom_t insetDom = insetDomain(s.function(), viewDom);
    ViewIndexer<dim,dim2> indexer(insetDom);
    Dom stView;
    indexer.baseToLocal(dom,stView);
    typedef typename NewEngine_t::ViewedEngine_t ViewedEngine_t;
    ViewedEngine_t viewed(s.function(),a(viewDom));
    return Type_t(NewEngine_t(viewed,stView));
  }
};
template<class Function>
class Stencil
{
public:
  Stencil()
  { }
  Stencil(const Stencil<Function> &model)
    : function_m(model.function_m)
  { }
  ~Stencil() {}
  template<class Init>
  Stencil(const Init &init)
    : function_m(init)
  { }
  template<int D, class T, class E>
  typename View1<Stencil<Function>,Array<D,T,E> >::Type_t
  operator()(const Array<D,T,E>& expr) const
  {
    typedef View1<Stencil<Function>,Array<D,T,E> > Ret_t;
    return Ret_t::make(*this,expr);
  }
  template<int D, class T, class E,class Dom>
  typename View2<Stencil<Function>,Array<D,T,E>,Dom>::Type_t
  operator()(const Array<D,T,E>& expr,const Dom &domain) const
  {
    PoomaCTAssert<(D==Dom::dimensions)>::test();
    typedef View2<Stencil<Function>,Array<D,T,E>,Dom> Ret_t;
    return Ret_t::make(*this,expr,domain);
  }
  template<int D>
  inline
  Interval<D> insetDomain(const Interval<D> &domain)
  {
    return ::insetDomain(function(), domain);
  }
  template<int D, class DT>
  inline
  Interval<D> inputDomain(const Domain<D,DT> &domain) const
  {
    Interval<D> ret;
    int d;
    for (d = 0; d < D; ++d)
    {
      ret[d] =
 Interval<1>(
      domain[d].first() - function().lowerExtent(d),
      domain[d].last() + function().upperExtent(d)
      );
    }
    return ret;
  }
  inline Function &function() { return function_m; }
  inline const Function &function() const { return function_m; }
private:
  Function function_m;
};
template <int Dim, class T, class S, class E>
struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, Interval<Dim> >
{
  typedef Engine<Dim, T, StencilEngine<S, E> > Type_t;
};
template <int Dim, class T, class S, class E>
struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, INode<Dim> >
{
  typedef typename View1<E, INode<Dim> >::Type_t NewExpr_t;
  typedef StencilEngine<S, NewExpr_t> NewTag_t;
  typedef Engine<Dim, T, NewTag_t> Type_t;
};
template <int Dim, class T, class S, class E>
struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, Range<Dim> >
{
  typedef StencilEngine<S,E> SETag_t;
  typedef ViewEngine<Dim,SETag_t> NewTag_t;
  typedef Engine<Dim,T,NewTag_t> Type_t;
};
template <int Dim, class T, class S, class E, int SliceDim>
struct NewEngine< Engine<Dim,T,StencilEngine<S,E> >,
  SliceInterval<Dim,SliceDim> >
{
  typedef StencilEngine<S,E> SETag_t;
  typedef ViewEngine<Dim,SETag_t> NewTag_t;
  typedef Engine<SliceDim,T,NewTag_t> Type_t;
};
template <int Dim, class T, class S, class E, int SliceDim>
struct NewEngine< Engine<Dim,T,StencilEngine<S,E> >,
  SliceRange<Dim,SliceDim> >
{
  typedef StencilEngine<S,E> SETag_t;
  typedef ViewEngine<Dim,SETag_t> NewTag_t;
  typedef Engine<SliceDim,T,NewTag_t> Type_t;
};
template<class UserFunction,class Expression>
struct EvaluatorEngineTraits<StencilEngine<UserFunction,Expression> >
{
  typedef typename Expression::Engine_t Engine_t;
  typedef typename Engine_t::Tag_t Tag_t;
  typedef typename EvaluatorEngineTraits<Tag_t>::Evaluator_t Evaluator_t;
};
template<int Dim, class Intersect>
class StencilIntersector
{
public:
  typedef typename Intersect::IntersectorData_t IntersectorData_t;
  typedef StencilIntersector<Dim, Intersect> This_t;
  typedef typename IntersectorData_t::const_iterator const_iterator;
  typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
  enum { dimensions = Intersect::dimensions };
  StencilIntersector(const This_t &model)
    : domain_m(model.domain_m),
      stencilExtent_m(model.stencilExtent_m),
      intersector_m(model.intersector_m)
  { }
  StencilIntersector(const Interval<Dim> &domain, const Intersect &intersect,
    const GuardLayers<Dim> &stencilExtent)
    : domain_m(domain),
      stencilExtent_m(stencilExtent),
      intersector_m(intersect)
  { }
  This_t &operator=(const This_t &model)
  {
    if (this != &model)
    {
      intersector_m = model.intersector_m;
      domain_m = model.domain_m;
      stencilExtent_m = model.stencilExtent_m;
    }
    return *this;
  }
  ~StencilIntersector() { }
  inline DataPtr_t &data() { return intersector_m.data(); }
  inline const DataPtr_t &data() const { return intersector_m.data(); }
  inline const_iterator begin() const { return data()->inodes_m.begin(); }
  inline const_iterator end() const { return data()->inodes_m.end(); }
  template<class Engine>
  inline
  void intersect(const Engine &engine)
  {
    typedef typename NewEngine<Engine,Interval<Dim> >::Type_t NewEngine_t;
    NewEngine_t newEngine(engine, domain_m);
    intersector_m.intersect(newEngine);
    data()->shared(engine.layout().ID(),newEngine.layout().ID());
  }
  template<class Engine, int Dim2>
  inline
  bool intersect(const Engine &engine, const GuardLayers<Dim2> &g,
    GuardLayers<Dim> &usedGuards)
  {
    intersect(engine);
    usedGuards = stencilExtent_m;
    return true;
  }
private:
  Interval<Dim> domain_m;
  GuardLayers<Dim> stencilExtent_m;
  Intersect intersector_m;
};
template <int D, class T, class S, class E, class Intersect>
struct LeafFunctor<Engine<D,T,StencilEngine<S,E> >,
  ExpressionApply<IntersectorTag<Intersect> > >
{
  typedef int Type_t;
  static
  Type_t apply(const Engine<D,T,StencilEngine<S,E> > &engine,
        const ExpressionApply<IntersectorTag<Intersect> > &tag)
  {
    typedef StencilIntersector<D, Intersect> NewIntersector_t;
    GuardLayers<D> stencilExtent;
    for (int i=0; i<D; ++i) {
      stencilExtent.lower(i) = engine.function().lowerExtent(i);
      stencilExtent.upper(i) = engine.function().upperExtent(i);
    }
    NewIntersector_t newIntersector(engine.intersectDomain(),
        tag.tag().intersector_m,
        stencilExtent);
    expressionApply(engine.expression(),
      IntersectorTag<NewIntersector_t>(newIntersector));
    return 0;
  }
};
template<class RequestType> class DataObjectRequest;
template <int D, class T, class S, class E, class RequestType>
struct EngineFunctor<Engine<D, T, StencilEngine<S, E> >,
  DataObjectRequest<RequestType> >
{
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  static Type_t
  apply(const Engine<D, T, StencilEngine<S, E> > &engine,
 const DataObjectRequest<RequestType> &tag)
  {
    return engineFunctor(engine.expression(), tag);
  }
};
template <int D, class T, class S, class E, class Tag>
struct LeafFunctor<Engine<D, T, StencilEngine<S, E> >, EngineView<Tag> >
{
  typedef LeafFunctor<E, EngineView<Tag> > LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t NewViewed_t;
  typedef Engine<D, T, StencilEngine<S, NewViewed_t> > Type_t;
  static
  Type_t apply(const Engine<D, T, StencilEngine<S, E> > &engine,
        const EngineView<Tag> &tag)
  {
    return Type_t(engine.function(),
    LeafFunctor_t::apply(engine.expression(), tag));
  }
};
template <int D, class T, class S, class E, class Tag>
struct LeafFunctor<Engine<D, T, StencilEngine<S, E> >, ExpressionApply<Tag> >
{
  typedef LeafFunctor<E, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  static
  Type_t apply(const Engine<D, T, StencilEngine<S, E> > &engine,
        const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(engine.expression(), tag);
  }
};
namespace Pooma {
namespace Algorithms {
template <bool type>
struct IsConcrete
{
inline IsConcrete() { }; inline IsConcrete(const IsConcrete &) { }; inline IsConcrete &operator=(const IsConcrete &) { return *this; };
};
template <class It, class It2>
inline It2 copy(It begin, It end, It2 dest)
{
  ;
  ;
  typedef typename std::iterator_traits<It>::value_type Value_t;
  typedef ElementProperties<Value_t> EP_t;
  typedef IsConcrete<EP_t::concrete> ConcreteType_t;
  return copy_special(begin, end, dest, ConcreteType_t());
}
template <class It, class It2>
inline It2 copy_special(It begin, It end, It2 dest, IsConcrete<true>)
{
  typedef std::iterator_traits<It> DataTraits_t;
  typedef typename DataTraits_t::difference_type Diff_t;
  typedef typename DataTraits_t::value_type Value_t;
  return std::copy(begin, end, dest);
}
template <class It, class It2>
inline It2 copy_special(It begin, It end, It2 dest, IsConcrete<false>)
{
  typedef typename std::iterator_traits<It>::value_type Value_t;
  while (begin < end)
    {
      ElementProperties<Value_t>::construct(dest++, *begin++);
    }
  return dest;
}
template <class DataIterator, class KillIterator>
inline
typename std::iterator_traits<DataIterator>::difference_type
delete_backfill(DataIterator data_begin, DataIterator data_end,
  const KillIterator kill_begin, const KillIterator kill_end,
  typename std::iterator_traits<DataIterator>::difference_type offset = 0)
{
  ;
  ;
  std::reverse_iterator<KillIterator> rk_pos(kill_end);
  std::reverse_iterator<KillIterator> rk_end(kill_begin);
  typedef std::iterator_traits<DataIterator> DataTraits_t;
  typedef typename DataTraits_t::difference_type Diff_t;
  Diff_t last = data_end - data_begin - 1;
  while (!(rk_pos == rk_end))
    {
      if ((*rk_pos - offset) != last) break;
      --last;
      ++rk_pos;
    }
  DataIterator last_pos = data_begin + last;
  while (!(rk_pos == rk_end))
    {
      *(data_begin + (*rk_pos++ - offset)) = *last_pos--;
    }
  return kill_end - kill_begin;
}
template <class DataIterator, class KillIterator>
inline
typename std::iterator_traits<DataIterator>::difference_type
delete_shiftup(DataIterator data_begin, DataIterator data_end,
  KillIterator kill_begin, KillIterator kill_end,
  typename std::iterator_traits<DataIterator>::difference_type offset = 0)
{
  DataIterator insert_pos = data_begin + (*kill_begin - offset);
  KillIterator kill_pos = kill_begin;
  typedef std::iterator_traits<DataIterator> DataTraits_t;
  typedef typename DataTraits_t::value_type Value_t;
  typedef typename DataTraits_t::difference_type Diff_t;
  while (kill_pos < kill_end)
  {
    Diff_t copy_index = *kill_pos + 1;
    while ( (kill_pos + 1) < kill_end && copy_index == *(kill_pos + 1) )
    {
      ++copy_index;
      ++kill_pos;
    }
    DataIterator copy_begin = data_begin + (copy_index - offset);
    DataIterator copy_end;
    if (copy_begin < data_end)
    {
      if (kill_pos + 1 < kill_end)
        copy_end = data_begin + (*(kill_pos + 1) - offset);
      else
        copy_end = data_end;
      const Diff_t length = copy_end - copy_begin;
      Pooma::Algorithms::copy(copy_begin, copy_end, insert_pos);
      insert_pos += length;
    }
    ++kill_pos;
  }
  return kill_end - kill_begin;
}
template<class DataIterator>
inline DataIterator
find_most_common(DataIterator dataBegin, DataIterator dataEnd)
{
  DataIterator checkValue, mostCommonValue = dataEnd;
  int checkCount, count = 0;
  while (dataBegin != dataEnd)
    {
      checkValue = dataBegin++;
      checkCount = 1;
      while (dataBegin != dataEnd && *dataBegin == *checkValue)
 {
   ++checkCount;
   ++dataBegin;
 }
      if (checkCount > count)
        {
   mostCommonValue = checkValue;
   count = checkCount;
 }
    }
  return mostCommonValue;
}
}
}
template<class Tag>
struct Remote
{ };
template <int Dim, class T, class Tag>
class Engine<Dim, T, Remote<Tag> >
{
public:
  typedef Engine<Dim, T, Remote<Tag> > This_t;
  typedef Engine<Dim, T, Remote<Tag> > Engine_t;
  typedef Engine<Dim, T, Tag> LocalEngine_t;
  typedef Interval<Dim> Domain_t;
  typedef T Element_t;
  typedef RemoteProxy<T> ElementRef_t;
  typedef Remote<Tag> Tag_t;
  typedef DomainLayout<Dim> Layout_t;
  enum { dimensions = Dim };
  enum { hasDataObject = true };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = false };
  typedef Shared<LocalEngine_t> LocalShared_t;
  typedef RefCountedPtr<LocalShared_t> LocalPtr_t;
  Engine();
  explicit
  Engine(const Domain_t &domain);
  Engine(int owningContext, const Domain_t &domain);
  Engine(const Domain_t &domain, const T &elementModel);
  explicit
  Engine(const Node<Domain_t> &node);
  explicit
  Engine(const Layout_t &layout);
  Engine(const Engine_t &model);
  Engine(const Engine_t &, const EngineConstructTag &);
  template<class OtherEngine, class Domain>
  Engine(const OtherEngine &otherEngine, const Domain &domain);
  template<class OtherEngine, int D2>
  Engine(const OtherEngine &otherEngine,
  const SliceRange<D2, Dim> &domain);
  ~Engine();
  Engine_t &operator=(const Engine_t &model);
  Element_t read(const Loc<Dim> &) const;
  ElementRef_t operator()(const Loc<Dim> &) const;
  Element_t read(int) const;
  Element_t read(int, int) const;
  Element_t read(int, int, int) const;
  Element_t read(int, int, int, int) const;
  Element_t read(int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int) const;
  Element_t read(int, int, int, int, int, int, int) const;
  ElementRef_t operator()(int) const;
  ElementRef_t operator()(int, int) const;
  ElementRef_t operator()(int, int, int) const;
  ElementRef_t operator()(int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int) const;
  ElementRef_t operator()(int, int, int, int, int, int, int) const;
  inline const Domain_t &domain() const
  {
    return domain_m;
  }
  inline
  bool engineIsLocal() const
  {
    return (Pooma::context() == owningContext_m);
  }
  inline
  int owningContext() const
  {
    return owningContext_m;
  }
  inline
  const LocalEngine_t &localEngine() const
  {
    ;
    ;
    return (*localEnginePtr_m).data();
  }
  inline
  LocalEngine_t &localEngine()
  {
    ;
    ;
    return (*localEnginePtr_m).data();
  }
  inline int first(int i) const
  {
    return domain_m[i].first();
  }
  inline
  Engine_t &makeOwnCopy()
  {
    if (engineIsLocal() && localEnginePtr_m.isValid())
    {
      LocalEngine_t engine(localEngine());
      engine.makeOwnCopy();
      localEnginePtr_m = LocalPtr_t(new LocalShared_t(engine));
    }
    return *this;
  }
protected:
  Domain_t domain_m;
private:
  int owningContext_m;
  LocalPtr_t localEnginePtr_m;
};
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(const Loc<Dim> &loc) const
{
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(loc);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2, int i3) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2, i3);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2, int i3, int i4) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2, i3, i4);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2, i3, i4, i5);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2, i3, i4, i5, i6);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline T Engine<Dim, T, Remote<Tag> >::
read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  T value;
  if (engineIsLocal())
  {
    value = localEngine().read(i1, i2, i3, i4, i5, i6, i7);
  }
  return ElementRef_t(value, owningContext());
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(const Loc<Dim> &loc) const
{
  if (engineIsLocal())
  {
    T &value = localEngine()(loc);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2, int i3) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2, i3);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2, int i3, int i4) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2, i3, i4);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2, int i3, int i4, int i5) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2, i3, i4, i5);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2, i3, i4, i5, i6);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
{
  ;
  if (engineIsLocal())
  {
    T &value = localEngine()(i1, i2, i3, i4, i5, i6, i7);
    return ElementRef_t(value, owningContext());
  }
  else
  {
    T val;
    return ElementRef_t(val, owningContext());
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine()
  : owningContext_m(0)
{
  ;
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine(const Node<Domain_t> &node)
  : domain_m(node.allocated()),
    owningContext_m(node.context())
{
  ;
  if (engineIsLocal())
  {
    localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(node)));
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine(const Layout_t &layout)
  : domain_m(layout.node().allocated()),
    owningContext_m(0)
{
  ;
  if (engineIsLocal())
  {
    localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(layout.
          node())));
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine(const Domain_t &dom)
  : domain_m(dom), owningContext_m(0)
{
  if (engineIsLocal())
  {
    localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m)));
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine(int owningContext, const Domain_t &dom)
  : domain_m(dom),
    owningContext_m(owningContext)
{
  if (engineIsLocal())
  {
    localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m)));
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::Engine(const Domain_t &dom, const T& model)
  : domain_m(dom), owningContext_m(0)
{
  if (engineIsLocal())
  {
    localEnginePtr_m =
      LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m, model)));
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::
Engine(const Engine<Dim, T, Remote<Tag> > &modelEngine)
  : domain_m(modelEngine.domain()),
    owningContext_m(modelEngine.owningContext()),
    localEnginePtr_m(modelEngine.localEnginePtr_m)
{
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::
Engine(const Engine<Dim, T, Remote<Tag> > &modelEngine,
       const EngineConstructTag &)
  : domain_m(modelEngine.domain()),
    owningContext_m(modelEngine.owningContext()),
    localEnginePtr_m(modelEngine.localEnginePtr_m)
{
}
template <int Dim, class T, class Tag>
template<class OtherEngine, class Domain>
Engine<Dim, T, Remote<Tag> >::
Engine(const OtherEngine &otherEngine, const Domain &domain)
  : owningContext_m(otherEngine.owningContext())
{
  if (engineIsLocal())
  {
    localEnginePtr_m =
      LocalPtr_t(new LocalShared_t(LocalEngine_t(otherEngine.localEngine(),
       domain)));
  }
  int i;
  for (i = 0; i < Dim; ++i)
  {
    domain_m[i] = Interval<1>(domain[i].length());
  }
}
template <int Dim, class T, class Tag>
template<class OtherEngine, int D2>
Engine<Dim, T, Remote<Tag> >::
Engine(const OtherEngine &otherEngine, const SliceRange<D2, Dim> &domain)
  : owningContext_m(otherEngine.owningContext())
{
  if (engineIsLocal())
  {
    localEnginePtr_m =
      LocalPtr_t(new LocalShared_t(LocalEngine_t(otherEngine.localEngine(),
       domain)));
  }
  int i;
  for (i = 0; i < Dim; ++i)
  {
    domain_m[i] = Interval<1>(domain.totalDomain()[i].length());
  }
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> > &
Engine<Dim, T, Remote<Tag> >::
operator=(const Engine<Dim, T, Remote<Tag> > &modelEngine)
{
  if (this == &modelEngine)
    return *this;
  owningContext_m = modelEngine.owningContext_m;
  domain_m = modelEngine.domain_m;
  localEnginePtr_m = modelEngine.localEnginePtr_m;
  return *this;
}
template <int Dim, class T, class Tag>
Engine<Dim, T, Remote<Tag> >::~Engine()
{
}
template<int Dim, class T, class Tag, class Domain>
struct NewEngine<Engine<Dim, T, Remote<Tag> >, Domain>
{
  typedef typename NewEngine<Engine<Dim, T, Tag>, Domain>::Type_t Local_t;
  typedef typename Local_t::Tag_t NewTag_t;
  enum { newDim = Local_t::dimensions };
  typedef Engine<newDim, T, Remote<NewTag_t> > Type_t;
};
template<int Dim, class T, class Tag>
struct NewEngineDomain<Engine<Dim, T, Remote<Tag> >, INode<Dim> >
{
  typedef const Interval<Dim> &Type_t;
  static inline const Interval<Dim> &
  apply(const Engine<Dim, T, Remote<Tag> > &,
 const INode<Dim> &i)
  {
    return i.domain();
  }
};
struct RemoteView { };
template<>
struct EngineView<RemoteView>
{
  typedef TreeCombine Combine_t;
};
struct RemoteSend
{
  RemoteSend(int n) : toContext_m(n) { }
  inline int toContext() const { return toContext_m; }
  int toContext_m;
};
template<class Engine>
struct DefaultExpressionApply<Engine, RemoteSend >
{
  typedef Engine Subject_t;
  typedef int Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const ExpressionApply<RemoteSend> &)
  {
    return 0;
  }
};
template<class Engine>
struct DefaultEngineView<Engine, RemoteView>
{
  typedef Engine Subject_t;
  typedef Engine Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const EngineView<RemoteView> &)
  {
    return engine;
  }
};
template<int Dim, class T, class Tag>
struct LeafFunctor<Engine<Dim, T, Remote<Tag> >, ExpressionApply<RemoteSend> >
{
  typedef Engine<Dim, T, Remote<Tag> > Subject_t;
  typedef int Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const ExpressionApply<RemoteSend> &sendTag)
  {
    if (engine.engineIsLocal())
    {
      if (sendTag.tag().toContext() == -1)
      {
 for (int i = 0; i < Pooma::contexts(); i++)
   if (i != Pooma::context())
     SendReceive::send(engine.localEngine(), i);
      }
      else
      {
 if (Pooma::context() != sendTag.tag().toContext())
   SendReceive::send(engine.localEngine(), sendTag.tag().toContext());
      }
    }
    return 0;
  }
};
template<int Dim, class T, class Tag>
struct LeafFunctor<Engine<Dim, T, Remote<Tag> >, EngineView<RemoteView> >
{
};
template<int Dim, class T>
struct LeafFunctor<Engine<Dim, T, Remote<Brick> >, EngineView<RemoteView> >
{
  typedef Engine<Dim, T, Remote<Brick> > Subject_t;
  typedef Engine<Dim, T, Brick> Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const EngineView<RemoteView> &)
  {
    if (engine.engineIsLocal())
    {
      return engine.localEngine();
    }
    else
    {
      Type_t local(engine.domain());
      Receive<Type_t>::receive(local, engine.owningContext());
      return local;
    }
  }
};
template<int Dim, class T>
struct LeafFunctor<Engine<Dim, T, Remote<BrickView> >,
  EngineView<RemoteView> >
{
  typedef Engine<Dim, T, Remote<BrickView> > Subject_t;
  typedef Engine<Dim, T, Brick> IncomingView_t;
  typedef Engine<Dim, T, Brick> Brick_t;
  typedef Engine<Dim, T, BrickView> Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const EngineView<RemoteView> &)
  {
    if (engine.engineIsLocal())
    {
      return engine.localEngine();
    }
    else
    {
      Interval<Dim> dom = engine.domain();
      Brick_t local(dom);
      Type_t view(local, dom);
      Receive<IncomingView_t>::receive(view, engine.owningContext());
      return view;
    }
  }
};
template<int Dim, class T>
struct LeafFunctor<Engine<Dim, T, Remote<BrickViewU> >,
  EngineView<RemoteView> >
{
  typedef Engine<Dim, T, Remote<BrickViewU> > Subject_t;
  typedef Engine<Dim, T, Brick> IncomingView_t;
  typedef Engine<Dim, T, Brick> Brick_t;
  typedef Engine<Dim, T, BrickViewU> Type_t;
  static inline
  Type_t apply(const Subject_t &engine,
        const EngineView<RemoteView> &)
  {
    if (engine.engineIsLocal())
    {
      return engine.localEngine();
    }
    else
    {
      Interval<Dim> dom = engine.domain();
      Brick_t local(dom);
      Type_t view(local, dom);
      Receive<IncomingView_t>::receive(view, engine.owningContext());
      return view;
    }
  }
};
template<int Dim, class T>
struct LeafFunctor<Engine<Dim, T, Remote<CompressibleBrick> >,
  EngineView<RemoteView> >
{
  typedef Engine<Dim, T, Remote<CompressibleBrick> > Subject_t;
  typedef Engine<Dim, T, CompressibleBrick> Type_t;
  static inline
  Type_t apply(const Subject_t &engine, const EngineView<RemoteView> &)
  {
    if (engine.engineIsLocal())
    {
      return engine.localEngine();
    }
    else
    {
      Type_t local(engine.domain());
      Receive<Type_t>::receive(local, engine.owningContext());
      return local;
    }
  }
};
template<int Dim, class T>
struct LeafFunctor<Engine<Dim, T, Remote<CompressibleBrickView> >,
  EngineView<RemoteView> >
{
  typedef Engine<Dim, T, Remote<CompressibleBrickView> > Subject_t;
  typedef Engine<Dim, T, CompressibleBrick> CompBrick_t;
  typedef Engine<Dim, T, CompressibleBrickView> Type_t;
  static inline
  Type_t apply(const Subject_t &engine, const EngineView<RemoteView> &)
  {
    if (engine.engineIsLocal())
    {
      return engine.localEngine();
    }
    else
    {
      Interval<Dim> dom = engine.domain();
      CompBrick_t local(dom);
      Type_t view(local, dom);
      Receive<Type_t>::receive(view, engine.owningContext());
      return view;
    }
  }
};
struct EngineBlockSerialize
{
  template<class Op, class Eng>
  inline static /*__attribute__((leafify))*/
  int apply(Op &op, const Eng &engine)
    {
      typedef typename Eng::Domain_t Domain_t;
      return apply(op, engine, engine.domain(),
     WrappedInt<Domain_t::dimensions>());
    }
  template<class Op, class Eng, class Dom>
  inline static /*__attribute__((leafify))*/
  int apply(Op &op, const Eng &engine, const Dom &domain)
    {
      return apply(op, engine, domain,
     WrappedInt<Dom::dimensions>());
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain, WrappedInt<1>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int e0 = domain[0].last();
      for (int i0 = f0; i0<=e0; ++i0)
 op(engine(i0));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<2>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int f1 = domain[1].first();
      int e0 = domain[0].last();
      int e1 = domain[1].last();
      for (int i1 = f1; i1<=e1; ++i1)
 for (int i0 = f0; i0<=e0; ++i0)
   op(engine(i0,i1));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<3>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int f1 = domain[1].first();
      int f2 = domain[2].first();
      int e0 = domain[0].last();
      int e1 = domain[1].last();
      int e2 = domain[2].last();
      for (int i2 = f2; i2<=e2; ++i2)
 for (int i1 = f1; i1<=e1; ++i1)
   for (int i0 = f0; i0<=e0; ++i0)
     op(engine(i0,i1,i2));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<4>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int f1 = domain[1].first();
      int f2 = domain[2].first();
      int f3 = domain[3].first();
      int e0 = domain[0].last();
      int e1 = domain[1].last();
      int e2 = domain[2].last();
      int e3 = domain[3].last();
      for (int i3 = f3; i3<=e3; ++i3)
 for (int i2 = f2; i2<=e2; ++i2)
   for (int i1 = f1; i1<=e1; ++i1)
     for (int i0 = f0; i0<=e0; ++i0)
       op(engine(i0,i1,i2,i3));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<5>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int f1 = domain[1].first();
      int f2 = domain[2].first();
      int f3 = domain[3].first();
      int f4 = domain[4].first();
      int e0 = domain[0].last();
      int e1 = domain[1].last();
      int e2 = domain[2].last();
      int e3 = domain[3].last();
      int e4 = domain[4].last();
      for (int i4 = f4; i4<=e4; ++i4)
 for (int i3 = f3; i3<=e3; ++i3)
   for (int i2 = f2; i2<=e2; ++i2)
     for (int i1 = f1; i1<=e1; ++i1)
       for (int i0 = f0; i0<=e0; ++i0)
  op(engine(i0,i1,i2,i3,i4));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<6>)
    {
      PoomaCTAssert<(Domain::unitStride == 1)>::test();
      int f0 = domain[0].first();
      int f1 = domain[1].first();
      int f2 = domain[2].first();
      int f3 = domain[3].first();
      int f4 = domain[4].first();
      int f5 = domain[5].first();
      int e0 = domain[0].last();
      int e1 = domain[1].last();
      int e2 = domain[2].last();
      int e3 = domain[3].last();
      int e4 = domain[4].last();
      int e5 = domain[5].last();
      for (int i5 = f5; i5<=e5; ++i5)
 for (int i4 = f4; i4<=e4; ++i4)
   for (int i3 = f3; i3<=e3; ++i3)
     for (int i2 = f2; i2<=e2; ++i2)
       for (int i1 = f1; i1<=e1; ++i1)
  for (int i0 = f0; i0<=e0; ++i0)
    op(engine(i0,i1,i2,i3,i4,i5));
      return op.total_m;
    }
  template<class Op,class Eng,class Domain>
  inline static int apply(Op &op,const Eng &engine,
     const Domain &domain,WrappedInt<7>)
{
  PoomaCTAssert<(Domain::unitStride == 1)>::test();
  int f0 = domain[0].first();
  int f1 = domain[1].first();
  int f2 = domain[2].first();
  int f3 = domain[3].first();
  int f4 = domain[4].first();
  int f5 = domain[5].first();
  int f6 = domain[6].first();
  int e0 = domain[0].last();
  int e1 = domain[1].last();
  int e2 = domain[2].last();
  int e3 = domain[3].last();
  int e4 = domain[4].last();
  int e5 = domain[5].last();
  int e6 = domain[6].last();
  for (int i6 = f6; i6<=e6; ++i6)
    for (int i5 = f5; i5<=e5; ++i5)
      for (int i4 = f4; i4<=e4; ++i4)
 for (int i3 = f3; i3<=e3; ++i3)
   for (int i2 = f2; i2<=e2; ++i2)
     for (int i1 = f1; i1<=e1; ++i1)
       for (int i0 = f0; i0<=e0; ++i0)
  op(engine(i0,i1,i2,i3,i4,i5,i6));
  return op.total_m;
}
private:
};
template <int Dim, class T, class Tag>
long elementsCompressed(const Engine<Dim, T, Remote<Tag> > &engine)
{
  return elementsCompressed(engine.localEngine());
}
template <int Dim, class T, class Tag>
void compress(Engine<Dim, T, Remote<Tag> > &engine)
{
  compress(engine.localEngine());
}
template <int Dim, class T, class Tag>
void uncompress(Engine<Dim, T, Remote<Tag> > &engine)
{
  uncompress(engine.localEngine());
}
template <int Dim, class T, class Tag>
bool compressed(const Engine<Dim, T, Remote<Tag> > &engine)
{
  return compressed(engine.localEngine());
}
class GatherContexts
{
private:
  class GatherContextsData : public RefCounted
  {
  public:
    inline GatherContextsData() {}
    inline GatherContextsData(const GatherContextsData &model)
    : contexts_m(model.contexts_m) {}
    inline ~GatherContextsData() {}
    void addContext(int c) const
      {
        if (c != -1)
          {
            if (contexts_m.empty())
              contexts_m.reserve(4);
     contexts_m.push_back(c);
   }
      }
    int mostCommonContext() const
      {
        if (contexts_m.size() != 0)
          {
            std::sort(contexts_m.begin(), contexts_m.end());
            return
       *Pooma::Algorithms::find_most_common(contexts_m.begin(),
                    contexts_m.end());
     }
        else
          {
            return -1;
          }
      }
  private:
    mutable std::vector<int> contexts_m;
  };
public:
  typedef NullCombine Combine_t;
  inline GatherContexts()
  : data_m(new GatherContextsData) {}
  inline GatherContexts(const GatherContexts &model)
  : data_m(model.data_m) { }
  GatherContexts &operator=(const GatherContexts &rhs)
    {
      data_m = rhs.data_m;
      return *this;
    }
  inline ~GatherContexts() {}
  inline void addContext(int c) const
    { data_m->addContext(c); }
  inline int mostCommonContext() const
    { return data_m->mostCommonContext(); }
private:
  RefCountedPtr<GatherContextsData> data_m;
};
template<class T>
struct EngineFunctorScalar<T, GatherContexts>
{
  typedef int Type_t;
  static inline
  Type_t apply(const T &, const GatherContexts &)
    {
      return 0;
    }
};
template<class Engine>
struct EngineFunctorDefault<Engine, GatherContexts>
{
  typedef Engine Subject_t;
  typedef int Type_t;
  static inline
  Type_t apply(const Subject_t &, const GatherContexts &)
    {
      return 0;
    }
};
template<int Dim, class T, class Tag>
struct EngineFunctor<Engine<Dim, T, Remote<Tag> >, GatherContexts>
{
  typedef Engine<Dim, T, Remote<Tag> > Subject_t;
  typedef int Type_t;
  static inline
  Type_t apply(const Subject_t &engine, const GatherContexts &tag)
    {
      tag.addContext(engine.owningContext());
      return 0;
    }
};
template <>
struct Evaluator<RemoteSinglePatchEvaluatorTag>
{
  Evaluator() { }
  ~Evaluator() { }
  template <class LHS, class RHS, class Op>
  void evaluate(const LHS &lhs, const Op &op, const RHS &rhs) const
  {
    GatherContexts gtag;
    engineFunctor(lhs.engine(), gtag);
    int lhsContext = gtag.mostCommonContext();
    expressionApply(rhs, RemoteSend(lhsContext));
    if (lhsContext == -1 || Pooma::context() == lhsContext)
      {
 EngineView<RemoteView> view;
        Evaluator<SinglePatchEvaluatorTag>().
   evaluate(forEach(lhs, view, TreeCombine()), op,
     forEach(rhs, view, TreeCombine()));
      }
    else
      {
      }
  }
};
template <>
struct Evaluator<RemoteMultiPatchEvaluatorTag>
{
  Evaluator() { }
  ~Evaluator() { }
  template <class LHS, class RHS, class Op>
  void evaluate(const LHS &lhs, const Op &op, const RHS &rhs) const
  {
    typedef Intersector<LHS::dimensions> Inter_t;
    Inter_t inter;
    expressionApply(lhs, IntersectorTag<Inter_t>(inter));
    expressionApply(rhs, IntersectorTag<Inter_t>(inter));
    typename Inter_t::const_iterator i = inter.begin();
    while (i != inter.end())
      {
        Evaluator<RemoteSinglePatchEvaluatorTag>().
          evaluate(lhs(*i), op, rhs(*i));
        ++i;
      }
  }
};
template <>
struct Reduction<RemoteSinglePatchEvaluatorTag>
{
  Reduction() { }
  ~Reduction() { }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e) const
  {
    GatherContexts gtag;
    engineFunctor(e.engine(), gtag);
    int computationContext = gtag.mostCommonContext();
    Pooma::CountingSemaphore csem;
    csem.height(1);
    if (Pooma::context() != computationContext)
    {
      expressionApply(e, RemoteSend(computationContext));
      csem.incr();
    }
    else
    {
      EngineView<RemoteView> view;
      Reduction<SinglePatchEvaluatorTag>().
 evaluate(ret, op,
   forEach(e, view, TreeCombine()), csem);
    }
    csem.wait();
    Pooma::scheduler().endGeneration();
    Pooma::blockAndEvaluate();
    Pooma::scheduler().beginGeneration();
    RemoteProxy<T> globalRet(ret, computationContext);
    ret = globalRet;
  }
};
template <>
struct Reduction<RemoteMultiPatchEvaluatorTag>
{
  Reduction() { }
  ~Reduction() { }
  template<class T, class Op, class Expr>
  void evaluate(T &ret, const Op &op, const Expr &e) const
  {
    typedef Intersector<Expr::dimensions> Inter_t;
    Inter_t inter;
    expressionApply(e, IntersectorTag<Inter_t>(inter));
    std::vector<bool> present(inter.size());
    std::vector<int> computationalContext(inter.size());
    typename Inter_t::const_iterator i = inter.begin();
    int j, k, n = 0;
    for (j = 0; j < inter.size(); j++)
      {
        present[j] = i->contextParticipates(Pooma::context());
 if (present[j])
          {
            computationalContext[j] = i->context();
            if (computationalContext[j] == Pooma::context())
              ++n;
          }
 ++i;
      }
    Pooma::CountingSemaphore csem;
    csem.height(n);
    T *vals = new T[n];
    i = inter.begin();
    k = 0;
    for (j = 0; j < inter.size(); j++)
      {
 if (present[j])
   {
     if (computationalContext[j] == Pooma::context())
       {
  EngineView<RemoteView> view;
  Reduction<SinglePatchEvaluatorTag>().
    evaluate(vals[k++], op,
      forEach(e(*i).engine(), view, TreeCombine()), csem);
       }
     else
       {
         expressionApply(e(*i), RemoteSend(computationalContext[j]));
       }
   }
 ++i;
      }
    ;
    csem.wait();
    Pooma::scheduler().endGeneration();
    Pooma::blockAndEvaluate();
    Pooma::scheduler().beginGeneration();
    if (n > 0)
      {
 ret = vals[0];
 for (j = 1; j < n; j++)
   op(ret, vals[j]);
      }
    delete [] vals;
    ReduceOverContexts<T, Op> finalReduction(ret, 0, n > 0);
    if (Pooma::context() == 0)
      ret = finalReduction;
    RemoteProxy<T> broadcast(ret, 0);
    ret = broadcast;
  }
};
template <int Dim, class T, class LayoutTag, class Tag>
struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag, Remote<Tag> > >,
  EnginePatch >
{
  typedef Engine<Dim, T, MultiPatch<LayoutTag, Remote<Tag> > > Subject_t;
  typedef Engine<Dim, T, Tag> Type_t;
  static inline
  Type_t apply(const Subject_t &engine, const EnginePatch &tag)
  {
    return engine.localPatch(tag.patch_m).localEngine();
  }
};
template <int Dim, class T, class Eng>
struct ElementProperties<Engine<Dim, T, Remote<Eng> > >
  : public MakeOwnCopyProperties<Engine<Dim, T, Remote<Eng> > >
{ };
class Full;
template<int D1, int D2, class T, class E> class TinyMatrix;
template<int D1, int D2, class T, class E> class TinyMatrixEngine;
template<class V, int I, int J>
struct TinyMatrixElem
{
  typedef V Element_t;
  typedef const V& ConstElementRef_t;
  typedef V& ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x; }
  static ElementRef_t get( V& x) { return x; }
};
template<int D1, int D2, class T, class E, int I, int J>
struct TinyMatrixEngineElem
{
  typedef TinyMatrixEngine<D1,D2,T,E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::ConstElementRef_t ConstElementRef_t;
  typedef typename V::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x(I,J); }
  static ElementRef_t get( V& x) { return x(I,J); }
};
template<int D1, int D2, class T, class E, int I, int J>
struct TinyMatrixElem< TinyMatrix<D1,D2,T,E> , I , J>
{
  typedef TinyMatrix<D1,D2,T,E> V;
  typedef TinyMatrixEngineElem<D1,D2,T,E,I,J> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x.engine()); }
  static ElementRef_t get(V& x) { return TE::get(x.engine()); }
};
template<class T1, class T2, class Op, int B1, int L1, int B2, int L2>
struct TinyMatrixAssign
{
  enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
  enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TinyMatrixAssign<T1,T2,Op,B11,L11,B21,L21>::apply(x,y,op);
      TinyMatrixAssign<T1,T2,Op,B12,L12,B21,L21>::apply(x,y,op);
      TinyMatrixAssign<T1,T2,Op,B11,L11,B22,L22>::apply(x,y,op);
      TinyMatrixAssign<T1,T2,Op,B12,L12,B22,L22>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int L1, int B2>
struct TinyMatrixAssign<T1,T2,Op,B1,L1,B2,1>
{
  enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TinyMatrixAssign<T1,T2,Op,B11,L11,B2,1>::apply(x,y,op);
      TinyMatrixAssign<T1,T2,Op,B12,L12,B2,1>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int B2, int L2>
struct TinyMatrixAssign<T1,T2,Op,B1,1,B2,L2>
{
  enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TinyMatrixAssign<T1,T2,Op,B1,1,B21,L21>::apply(x,y,op);
      TinyMatrixAssign<T1,T2,Op,B1,1,B22,L22>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TinyMatrixAssign<T1,T2,Op,B1,1,B2,1>
{
  static void apply(T1& x, const T2& y,Op op=Op())
    {
      op(TinyMatrixElem<T1,B1,B2>::get(x), TinyMatrixElem<T2,B1,B2>::get(y));
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TinyMatrixAssign<T1,T2,Op,B1,2,B2,2>
{
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      op(TinyMatrixElem<T1,B1 ,B2 >::get(x), TinyMatrixElem<T2,B1 ,B2 >::get(y));
      op(TinyMatrixElem<T1,B1+1,B2 >::get(x), TinyMatrixElem<T2,B1+1,B2 >::get(y));
      op(TinyMatrixElem<T1,B1 ,B2+1>::get(x), TinyMatrixElem<T2,B1 ,B2+1>::get(y));
      op(TinyMatrixElem<T1,B1+1,B2+1>::get(x), TinyMatrixElem<T2,B1+1,B2+1>::get(y));
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TinyMatrixAssign<T1,T2,Op,B1,3,B2,3>
{
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      op(TinyMatrixElem<T1,B1 ,B2 >::get(x), TinyMatrixElem<T2,B1 ,B2 >::get(y));
      op(TinyMatrixElem<T1,B1+1,B2 >::get(x), TinyMatrixElem<T2,B1+1,B2 >::get(y));
      op(TinyMatrixElem<T1,B1+2,B2 >::get(x), TinyMatrixElem<T2,B1+2,B2 >::get(y));
      op(TinyMatrixElem<T1,B1 ,B2+1>::get(x), TinyMatrixElem<T2,B1 ,B2+1>::get(y));
      op(TinyMatrixElem<T1,B1+1,B2+1>::get(x), TinyMatrixElem<T2,B1+1,B2+1>::get(y));
      op(TinyMatrixElem<T1,B1+2,B2+1>::get(x), TinyMatrixElem<T2,B1+2,B2+1>::get(y));
      op(TinyMatrixElem<T1,B1 ,B2+2>::get(x), TinyMatrixElem<T2,B1 ,B2+2>::get(y));
      op(TinyMatrixElem<T1,B1+1,B2+2>::get(x), TinyMatrixElem<T2,B1+1,B2+2>::get(y));
      op(TinyMatrixElem<T1,B1+2,B2+2>::get(x), TinyMatrixElem<T2,B1+2,B2+2>::get(y));
    }
};
template<class V1, class V2, class Op>
class BinaryTinyMatrixOp;
template<int D1, int D2, class T, class V1, class V2, class Op>
class TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op> >
{
public:
  enum { dimensions=2 };
  typedef T Element_t;
  typedef BinaryTinyMatrixOp<V1,V2,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef TinyMatrixEngine<D1,D2,T, BinaryTinyMatrixOp<V1,V2,Op> > This_t;
  TinyMatrixEngine(const V1& v1, const V2& v2)
    : v1_m(v1), v2_m(v2) {}
  Element_t operator()(int i, int j) const
  {
    return Op()(v1_m(i,j), v2_m(i,j));
  }
  template<int DD1,int DD2, class TT, class EE, int I, int J>
    friend struct TinyMatrixEngineElem;
private:
  const V1& v1_m;
  const V2& v2_m;
};
template<int D1, int D2, class T, class V1, class V2, class Op, int I, int J>
struct TinyMatrixEngineElem<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op>, I, J >
{
  typedef TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op> > V;
  typedef typename TinyMatrixElem<V1,I,J>::Element_t T1;
  typedef typename TinyMatrixElem<V2,I,J>::Element_t T2;
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(
        TinyMatrixElem<V1,I,J>::get(x.v1_m),
        TinyMatrixElem<V2,I,J>::get(x.v2_m));
    }
};
template<class V1, class Op>
class UnaryTinyMatrixOp;
template<int D1, int D2, class T, class V1, class Op>
class TinyMatrixEngine<D1,D2,T,UnaryTinyMatrixOp<V1,Op> >
{
public:
  enum { dimensions=2 };
  typedef T Element_t;
  typedef UnaryTinyMatrixOp<V1,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef TinyMatrixEngine<D1,D2,T, UnaryTinyMatrixOp<V1,Op> > This_t;
  explicit TinyMatrixEngine(const V1& v1)
    : v1_m(v1) {}
  Element_t operator()(int i, int j) const
  {
    return Op()(v1_m(i,j));
  }
  template<int DD1, int DD2, class TT, class EE, int I, int J>
    friend struct TinyMatrixEngineElem;
private:
  const V1& v1_m;
};
template<int D1, int D2, class T, class V1, class Op, int I, int J>
struct TinyMatrixEngineElem<D1,D2,T,UnaryTinyMatrixOp<V1,Op>, I, J >
{
  typedef TinyMatrixEngine<D1,D2,T,UnaryTinyMatrixOp<V1,Op> > V;
  typedef typename TinyMatrixElem<V1,I,J>::Element_t T1;
  typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(TinyMatrixElem<V1,I,J>::get(x.v1_m));
    }
};
template<int D1, int D2, class T, class E> class TinyMatrix;
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcCos >::Type_t acos( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcSin >::Type_t asin( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcTan >::Type_t atan( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCeil > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCeil >::Type_t ceil( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCos >::Type_t cos( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypCos >::Type_t cosh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnExp > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnExp >::Type_t exp( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFabs > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFabs >::Type_t fabs( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFloor > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFloor >::Type_t floor( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog >::Type_t log( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog10 > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog10 >::Type_t log10( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSin >::Type_t sin( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypSin >::Type_t sinh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSqrt > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSqrt >::Type_t sqrt( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnTan >::Type_t tan( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypTan >::Type_t tanh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryMinus > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryMinus >::Type_t operator-( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryPlus > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryPlus >::Type_t operator+( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpBitwiseNot > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpBitwiseNot >::Type_t operator~( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpAdd >::Type_t operator+( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpAdd>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpAdd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpAdd >::Type_t operator+( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpAdd >::Type_t operator+( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpSubtract >::Type_t operator-( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpSubtract>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpSubtract> > Expr_t; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpSubtract >::Type_t operator-( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpMultiply >::Type_t operator*( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpMultiply> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMultiply >::Type_t operator*( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpDivide >::Type_t operator/( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpDivide>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpDivide> > Expr_t; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpDivide >::Type_t operator/( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpDivide >::Type_t operator/( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpMod >::Type_t operator%( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMod>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpMod> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMod >::Type_t operator%( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMod >::Type_t operator%( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpMod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseAnd >::Type_t operator&( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseAnd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseOr >::Type_t operator|( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseOr> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseXor >::Type_t operator^( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseXor> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnLdexp >::Type_t ldexp( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnLdexp>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnLdexp> > Expr_t; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnLdexp >::Type_t ldexp( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnPow >::Type_t pow( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnPow>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnPow> > Expr_t; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnPow >::Type_t pow( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnPow >::Type_t pow( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,FnPow> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnFmod >::Type_t fmod( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnFmod>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnFmod> > Expr_t; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnFmod >::Type_t fmod( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnFmod >::Type_t fmod( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnArcTan2 >::Type_t atan2( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnArcTan2>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnArcTan2> > Expr_t; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnArcTan2 >::Type_t atan2( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template<int D1, int D2, class T, class V1, class V2>
class TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,FnDot> >
{
public:
  enum { dimensions=2 };
  typedef T Element_t;
  typedef FnDot Op;
  typedef BinaryTinyMatrixOp<V1,V2,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef TinyMatrixEngine<D1,D2,T, BinaryTinyMatrixOp<V1,V2,Op> > This_t;
  TinyMatrixEngine(const V1& v1, const V2& v2, Op op)
    : v1_m(v1), v2_m(v2), op_m(op) {}
  TinyMatrixEngine(const V1& v1, const V2& v2)
    : v1_m(v1), v2_m(v2) {}
  TinyMatrixEngine(const This_t& x)
    : v1_m(x.v1_m), v2_m(x.v2_m), op_m(x.op_m) {}
  ~TinyMatrixEngine() {}
  template<int DD1,int DD2, class TT, class EE, int I, int J>
    friend struct TinyMatrixEngineElem;
private:
  const V1& v1_m;
  const V2& v2_m;
  Op op_m;
};
template<class T1, class T2, int I, int J, int K, int L>
struct TinyMatrixDotTinyMatrix
{
  typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,K,L/2>::Type_t Left_t;
  typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,K+L/2,L-L/2>::Type_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
  static Type_t get(const T1& x, const T2& y)
    {
      return
        TinyMatrixDotTinyMatrix<T1,T2,I,J,K,L/2>::get(x,y) +
        TinyMatrixDotTinyMatrix<T1,T2,I,J,K+L/2,L-L/2>::get(x,y);
    }
};
template<class T1, class T2, int I, int J, int K>
struct TinyMatrixDotTinyMatrix<T1,T2,I,J,K,1>
{
  typedef typename TinyMatrixElem<T1,I,K>::Element_t Left_t;
  typedef typename TinyMatrixElem<T2,K,J>::Element_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
  static Type_t get(const T1& x, const T2& y)
    {
      return TinyMatrixElem<T1,I,K>::get(x) * TinyMatrixElem<T2,K,J>::get(y);
    }
};
template<int D1, int D2, class T, class T1, class T2, int I, int J>
struct TinyMatrixEngineElem<D1,D2,T,BinaryTinyMatrixOp<T1,T2,FnDot>, I, J >
{
  typedef BinaryTinyMatrixOp<T1,T2,FnDot> E;
  typedef TinyMatrixEngine<D1,D2,T,E> T0;
  typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,0,T1::d1>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const T0& x)
    {
      return TinyMatrixDotTinyMatrix<T1,T2,I,J,0,T1::d2>::get(x.v1_m,x.v2_m);
    }
};
template<int D1, int D2, int D3, class T1, class T2, class E1, class E2>
struct BinaryReturn< TinyMatrix<D1,D2,T1,E1> , TinyMatrix<D2,D3,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef TinyMatrix<D1,D3,T0,Full> Type_t;
};
template<int D1, int D2, int D3, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D2,D3,T2,E2> , FnDot >::Type_t
dot( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D2,D3,T2,E2>& v2 )
{
  typedef TinyMatrix<D1,D2,T1,E1> V1;
  typedef TinyMatrix<D2,D3,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef TinyMatrix<D1,D3,T3,BinaryTinyMatrixOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<int D1, int D2, class T1, class T2, class E1, class E2>
struct BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpEQ >
{
  typedef bool Type_t;
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
struct BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpNE >
{
  typedef bool Type_t;
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpEQ >::Type_t
operator==(const TinyMatrix<D1,D2,T1,E1>& t1, const TinyMatrix<D1,D2,T2,E2>& t2)
{
  for (int i = 0; i < D1; i++)
    for (int j = 0; j < D2; j++)
      if (t1(i,j) != t2(i,j)) return false;
  return true;
}
template<int D1, int D2, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpNE >::Type_t
operator!=(const TinyMatrix<D1,D2,T1,E1>& t1, const TinyMatrix<D1,D2,T2,E2>& t2)
{
  return !(t1 == t2);
}
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator+=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpAddAssign,0,D1,0,D2>::apply(v1,v2,OpAddAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator+=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpAddAssign,0,D1,0,D2>:: apply(v1,v2,OpAddAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator-=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpSubtractAssign,0,D1,0,D2>::apply(v1,v2,OpSubtractAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator-=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpSubtractAssign,0,D1,0,D2>:: apply(v1,v2,OpSubtractAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator*=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpMultiplyAssign,0,D1,0,D2>::apply(v1,v2,OpMultiplyAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator*=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpMultiplyAssign,0,D1,0,D2>:: apply(v1,v2,OpMultiplyAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator/=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpDivideAssign,0,D1,0,D2>::apply(v1,v2,OpDivideAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator/=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpDivideAssign,0,D1,0,D2>:: apply(v1,v2,OpDivideAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator%=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpModAssign,0,D1,0,D2>::apply(v1,v2,OpModAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator%=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpModAssign,0,D1,0,D2>:: apply(v1,v2,OpModAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator|=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseOrAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseOrAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator|=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseOrAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseOrAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator&=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseAndAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseAndAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator&=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseAndAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseAndAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator^=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseXorAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseXorAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator^=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseXorAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseXorAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator<<=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpLeftShiftAssign,0,D1,0,D2>::apply(v1,v2,OpLeftShiftAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator<<=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpLeftShiftAssign,0,D1,0,D2>:: apply(v1,v2,OpLeftShiftAssign()); return v1; }
template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator>>=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpRightShiftAssign,0,D1,0,D2>::apply(v1,v2,OpRightShiftAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator>>=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpRightShiftAssign,0,D1,0,D2>:: apply(v1,v2,OpRightShiftAssign()); return v1; }
template<int D1, int D2, class T, class E> class TinyMatrix;
template<int D1, int D2, class T, class E> class TinyMatrixEngine;
template <class T>
void reverseBytes(T&);
template<int D1, int D2=D1, class T=double, class EngineTag=Full>
class TinyMatrix
{
public:
  enum { dimensions=2 };
  enum { d1=D1, d2=D2 };
  typedef T Element_t;
  typedef EngineTag EngineTag_t;
  typedef TinyMatrixEngine<D1,D2,T,EngineTag> Engine_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
  typedef TinyMatrix<D1,D2,T,EngineTag> This_t;
  TinyMatrix() {}
  TinyMatrix(const This_t& x) : engine_m(x.engine_m) {}
  template<int D3, int D4, class T2, class EngineTag2>
  TinyMatrix(const TinyMatrix<D3, D4, T2, EngineTag2>& x) : engine_m(x) {}
  template<class X>
  explicit TinyMatrix(const X& x) : engine_m(x) {}
  template<class X1, class X2>
    TinyMatrix(const X1& x1, const X2& x2) : engine_m(x1,x2) {}
  template<class X1, class X2, class X3>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3)
    : engine_m(x1,x2,x3) {}
  template<class X1, class X2, class X3, class X4>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
    : engine_m(x1,x2,x3,x4) {}
  template<class X1, class X2, class X3, class X4, class X5>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5)
    : engine_m(x1,x2,x3,x4,x5) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6)
    : engine_m(x1,x2,x3,x4,x5,x6) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7)
    : engine_m(x1,x2,x3,x4,x5,x6,x7) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7, class X8>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7, const X8& x8)
    : engine_m(x1,x2,x3,x4,x5,x6,x7,x8) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7, class X8, class X9>
    TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
    : engine_m(x1,x2,x3,x4,x5,x6,x7,x8,x9) {}
  ~TinyMatrix() {}
  This_t& operator=(const This_t& x)
    {
      if ( this != &x )
        engine() = x.engine();
      return *this;
    }
  template<class V>
    This_t& operator=(const V& x)
        {
          engine() = x;
          return *this;
        }
  ConstElementRef_t operator()(int i,int j) const
    {
      return engine()(i,j);
    }
  ElementRef_t operator()(int i,int j)
    {
      return engine()(i,j);
    }
  ConstElementRef_t operator()(int i) const { return engine()(i); }
  ElementRef_t operator()(int i) { return engine()(i); }
  const Engine_t& engine() const { return engine_m; }
  Engine_t& engine() { return engine_m; }
  template<class Out>
  void print(Out &out) const;
  inline void reverseBytes() { engine_m.reverseBytes(); }
private:
  Engine_t engine_m;
};
template<int D1, int D2, class T, class EngineTag>
template<class Out>
void TinyMatrix<D1, D2, T, EngineTag>::print(Out &out) const
{
  std::ios::fmtflags incomingFormatFlags = out.flags();
  long width = out.width();
  long precision = out.precision();
  out.width(0);
  out << "(";
  for (int i = 0; i < D1; i++) {
    out << "(";
    out.flags(incomingFormatFlags);
    out.width(width);
    out.precision(precision);
    out << (*this)(i, 0);
    for (int j = 1; j < D2; j++) {
      out << " ";
      out.flags(incomingFormatFlags);
      out.width(width);
      out.precision(precision);
      out << (*this)(i, j);
    }
    out << ")";
  }
  out << ")";
}
template<int D1, int D2, class T, class E>
std::ostream &operator<<(std::ostream &out, const TinyMatrix<D1,D2,T,E> &t)
{
  t.print(out);
  return out;
}
template <int D1, int D2, class T, class E>
struct ElementProperties< TinyMatrix<D1,D2,T,E> >
  : public TrivialElementProperties< TinyMatrix<D1,D2,T,E> >
{ };
template<int D1, int D2, class T>
class TinyMatrixEngine<D1,D2,T,Full>
{
public:
  enum { dimensions=2 };
  enum { d1=D1, d2=D2 };
  typedef T Element_t;
  typedef Full EngineTag_t;
  typedef T& ElementRef_t;
  typedef const T& ConstElementRef_t;
  typedef TinyMatrixEngine<D1,D2,T,Full> This_t;
  TinyMatrixEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
  }
  TinyMatrixEngine(const TinyMatrixEngine<D1,D2,T,Full>& x)
    {
      TinyMatrixAssign<This_t,This_t,OpAssign,0,D1,0,D2>
 ::apply(*this,x,OpAssign());
    }
  template<class X>
  explicit TinyMatrixEngine(const X& x)
      {
        TinyMatrixAssign<This_t,X,OpAssign,0,D1,0,D2>::apply(*this,x,OpAssign());
      }
  template<class X1, class X2>
    TinyMatrixEngine(const X1& x1, const X2& x2)
      {
        PoomaCTAssert<(D1*D2 == 2)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
      }
  template<class X1, class X2, class X3>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3)
      {
        PoomaCTAssert<(D1*D2 == 3)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
      }
  template<class X1, class X2, class X3, class X4>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
      {
        PoomaCTAssert<(D1*D2 == 4)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
      }
  template<class X1, class X2, class X3, class X4, class X5>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5)
      {
        PoomaCTAssert<(D1*D2 == 5)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
        (*this)(4) = x5;
      }
  template<class X1, class X2, class X3, class X4, class X5, class X6>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6)
      {
        PoomaCTAssert<(D1*D2 == 6)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
        (*this)(4) = x5;
        (*this)(5) = x6;
      }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7)
      {
        PoomaCTAssert<(D1*D2 == 7)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
        (*this)(4) = x5;
        (*this)(5) = x6;
        (*this)(6) = x7;
      }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7, class X8>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7, const X8& x8)
      {
        PoomaCTAssert<(D1*D2 == 8)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
        (*this)(4) = x5;
        (*this)(5) = x6;
        (*this)(6) = x7;
        (*this)(7) = x8;
      }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
           class X7, class X8, class X9>
    TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
           const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
      {
        PoomaCTAssert<(D1*D2 == 9)>::test();
        (*this)(0) = x1;
        (*this)(1) = x2;
        (*this)(2) = x3;
        (*this)(3) = x4;
        (*this)(4) = x5;
        (*this)(5) = x6;
        (*this)(6) = x7;
        (*this)(7) = x8;
        (*this)(8) = x9;
      }
  ~TinyMatrixEngine() {}
  const This_t&
    operator=(const This_t& x)
      {
        if ( this != &x )
          TinyMatrixAssign<This_t,This_t,OpAssign,0,D1,0,D2>
     ::apply(*this,x,OpAssign());
        return *this;
      }
  template<class V>
    const This_t&
      operator=(const V& x)
        {
          TinyMatrixAssign<This_t,V,OpAssign,0,D1,0,D2>::apply(*this,x,OpAssign());
          return *this;
        }
  ConstElementRef_t operator()(int i,int j) const
    {
      ;
      return x_m[i+D1*j];
    }
  ElementRef_t operator()(int i,int j)
    {
      ;
      return x_m[i+D1*j];
    }
  ConstElementRef_t operator()(int i) const
    {
      ;
      return x_m[i];
    }
  ElementRef_t operator()(int i)
    {
      ;
      return x_m[i];
    }
  inline void reverseBytes()
  {
    for (int d = 0; d < D1*D2; ++d) ::reverseBytes(x_m[d]);
  }
private:
  T x_m[D1*D2];
};
template<class T, class Components> struct ComponentAccess;
template<int D1, int D2, class T, class E, int N>
struct ComponentAccess< TinyMatrix<D1, D2, T, E>, Loc<N> >
{
  typedef TinyMatrix<D1, D2, T, E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::ElementRef_t ElementRef_t;
  static inline ElementRef_t indexRef(V &t, const Loc<N> &l)
    {
      PoomaCTAssert<(N==2)>::test();
      return t(l[0].first(), l[1].first());
    }
  static inline Element_t index(const V &t, const Loc<N> &l)
    {
      PoomaCTAssert<(N==2)>::test();
      return t(l[0].first(), l[1].first());
    }
};
template<int D1, int D2, class T, int I, int J>
struct TinyMatrixElem< TinyMatrixEngine<D1,D2,T,Full> , I , J>
{
  typedef TinyMatrixEngine<D1,D2,T,Full> V;
  typedef TinyMatrixEngineElem<D1,D2,T,Full,I,J> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x); }
  static ElementRef_t get(V& x) { return TE::get(x); }
};
template<int D, class T, class E> class Tensor;
template<int D, class T, class E> class TensorEngine;
class Antisymmetric;
class Symmetric;
class Diagonal;
struct Unwritable
{
public:
  template<class T>
  void operator=(const T&) { }
  void operator=(const Unwritable&) { }
};
template<int D, class E, int I, int J>
class Writable
{
public:
  enum { value = 1 };
};
template<int D, int I, int J>
class Writable<D, Antisymmetric, I, J>
{
public:
  enum { value = (I > J) };
};
template<int D, int I, int J>
class Writable<D, Symmetric, I, J>
{
public:
  enum { value = (I >= J) };
};
template<int D, int I, int J>
class Writable<D, Diagonal, I, J>
{
public:
  enum { value = (I == J) };
};
template<int D, class T, class E, int I, int J, int B=1>
struct TensorEngineElem;
template<int D, class T, class E, int I, int J>
struct TensorEngineElem<D, T, E, I, J, 1>
{
  typedef TensorEngine<D,T,E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::CTConstElementRef_t ConstElementRef_t;
  typedef typename V::CTElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x.template getIJ<I,J>(); }
  static ElementRef_t get( V& x) { return x.template getIJ<I,J>(); }
};
template<int D, class T, class E, int I, int J>
struct TensorEngineElem<D, T, E, I, J, 0>
{
  typedef TensorEngine<D,T,E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::CTConstElementRef_t ConstElementRef_t;
  typedef Unwritable ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x.template getIJ<I,J>(); }
  static ElementRef_t get( V& x) { return Unwritable(); }
};
template<class V, int I, int J>
struct TensorElem
{
  typedef V Element_t;
  typedef const V& ConstElementRef_t;
  typedef V& ElementRef_t;
  static ConstElementRef_t get(const V& x) { return x; }
  static ElementRef_t get( V& x) { return x; }
};
template<int D, class T, class E, int I, int J>
struct TensorElem< Tensor<D,T,E> , I , J>
{
  typedef Tensor<D,T,E> V;
  typedef TensorEngineElem<D,T,E,I,J,Writable<D,E,I,J>::value> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x.engine()); }
  static ElementRef_t get(V& x) { return TE::get(x.engine()); }
};
template<int D, class T, class E, int I, int J>
struct TensorElem< TensorEngine<D,T,E> , I , J>
{
};
template<class T1, class T2, class Op, int B1, int L1, int B2, int L2>
struct TensorAssign
{
  enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
  enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TensorAssign<T1,T2,Op,B11,L11,B21,L21>::apply(x,y,op);
      TensorAssign<T1,T2,Op,B12,L12,B21,L21>::apply(x,y,op);
      TensorAssign<T1,T2,Op,B11,L11,B22,L22>::apply(x,y,op);
      TensorAssign<T1,T2,Op,B12,L12,B22,L22>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int L1, int B2>
struct TensorAssign<T1,T2,Op,B1,L1,B2,1>
{
  enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TensorAssign<T1,T2,Op,B11,L11,B2,1>::apply(x,y,op);
      TensorAssign<T1,T2,Op,B12,L12,B2,1>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int B2, int L2>
struct TensorAssign<T1,T2,Op,B1,1,B2,L2>
{
  enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      TensorAssign<T1,T2,Op,B1,1,B21,L21>::apply(x,y,op);
      TensorAssign<T1,T2,Op,B1,1,B22,L22>::apply(x,y,op);
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TensorAssign<T1,T2,Op,B1,1,B2,1>
{
  static void apply(T1& x, const T2& y,Op op=Op())
    {
      op(TensorElem<T1,B1,B2>::get(x), TensorElem<T2,B1,B2>::get(y));
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TensorAssign<T1,T2,Op,B1,2,B2,2>
{
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      op(TensorElem<T1,B1 ,B2 >::get(x), TensorElem<T2,B1 ,B2 >::get(y));
      op(TensorElem<T1,B1+1,B2 >::get(x), TensorElem<T2,B1+1,B2 >::get(y));
      op(TensorElem<T1,B1 ,B2+1>::get(x), TensorElem<T2,B1 ,B2+1>::get(y));
      op(TensorElem<T1,B1+1,B2+1>::get(x), TensorElem<T2,B1+1,B2+1>::get(y));
    }
};
template<class T1, class T2, class Op, int B1, int B2>
struct TensorAssign<T1,T2,Op,B1,3,B2,3>
{
  static void apply(T1& x, const T2& y, Op op=Op())
    {
      op(TensorElem<T1,B1 ,B2 >::get(x), TensorElem<T2,B1 ,B2 >::get(y));
      op(TensorElem<T1,B1+1,B2 >::get(x), TensorElem<T2,B1+1,B2 >::get(y));
      op(TensorElem<T1,B1+2,B2 >::get(x), TensorElem<T2,B1+2,B2 >::get(y));
      op(TensorElem<T1,B1 ,B2+1>::get(x), TensorElem<T2,B1 ,B2+1>::get(y));
      op(TensorElem<T1,B1+1,B2+1>::get(x), TensorElem<T2,B1+1,B2+1>::get(y));
      op(TensorElem<T1,B1+2,B2+1>::get(x), TensorElem<T2,B1+2,B2+1>::get(y));
      op(TensorElem<T1,B1 ,B2+2>::get(x), TensorElem<T2,B1 ,B2+2>::get(y));
      op(TensorElem<T1,B1+1,B2+2>::get(x), TensorElem<T2,B1+1,B2+2>::get(y));
      op(TensorElem<T1,B1+2,B2+2>::get(x), TensorElem<T2,B1+2,B2+2>::get(y));
    }
};
template<class V1, class V2, class Op>
class BinaryTensorOp;
template<int D, class T, class V1, class V2, class Op>
class TensorEngine<D,T,BinaryTensorOp<V1,V2,Op> >
{
public:
  enum { dimensions=2 };
  typedef T Element_t;
  typedef BinaryTensorOp<V1,V2,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef TensorEngine<D,T, BinaryTensorOp<V1,V2,Op> > This_t;
  TensorEngine(const V1& v1, const V2& v2)
    : v1_m(v1), v2_m(v2) {}
  Element_t operator()(int i, int j) const
  {
    return Op()(v1_m(i,j), v2_m(i,j));
  }
  template<int DD, class TT, class EE, int I, int J, int BB>
  friend struct TensorEngineElem;
private:
  const V1& v1_m;
  const V2& v2_m;
};
template<int D, class T, class V1, class V2, class Op, int I, int J>
struct TensorEngineElem<D,T,BinaryTensorOp<V1,V2,Op>, I, J, 1>
{
  typedef TensorEngine<D,T,BinaryTensorOp<V1,V2,Op> > V;
  typedef typename TensorElem<V1,I,J>::Element_t T1;
  typedef typename TensorElem<V2,I,J>::Element_t T2;
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(
        TensorElem<V1,I,J>::get(x.v1_m),
        TensorElem<V2,I,J>::get(x.v2_m));
    }
};
template<class V1, class Op>
class UnaryTensorOp;
template<int D, class T, class V1, class Op>
class TensorEngine<D,T,UnaryTensorOp<V1,Op> >
{
public:
  enum { dimensions=2 };
  typedef T Element_t;
  typedef UnaryTensorOp<V1,Op> EngineTag_t;
  typedef T ConstElementRef_t;
  typedef T ElementRef_t;
  typedef TensorEngine<D,T, UnaryTensorOp<V1,Op> > This_t;
  explicit TensorEngine(const V1& v1)
    : v1_m(v1) {}
  Element_t operator()(int i, int j) const
  {
    return Op()(v1_m(i, j));
  }
  template<int DD, class TT, class EE, int I, int J, int BB>
  friend struct TensorEngineElem;
private:
  const V1& v1_m;
};
template<int D, class T, class V1, class Op, int I, int J>
struct TensorEngineElem<D,T,UnaryTensorOp<V1,Op>, I, J, 1>
{
  typedef TensorEngine<D,T,UnaryTensorOp<V1,Op> > V;
  typedef typename TensorElem<V1,I,J>::Element_t T1;
  typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const V& x)
    {
      return Op()(TensorElem<V1,I,J>::get(x.v1_m));
    }
};
template<int D, class T, class E> class Tensor;
class Full;
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcCos > { typedef Tensor< D, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcCos >::Type_t acos( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcSin > { typedef Tensor< D, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcSin >::Type_t asin( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcTan > { typedef Tensor< D, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcTan >::Type_t atan( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnCeil > { typedef Tensor< D, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnCeil >::Type_t ceil( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnCos > { typedef Tensor< D, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnCos >::Type_t cos( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypCos > { typedef Tensor< D, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypCos >::Type_t cosh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnExp > { typedef Tensor< D, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnExp >::Type_t exp( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnFabs > { typedef Tensor< D, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnFabs >::Type_t fabs( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnFloor > { typedef Tensor< D, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnFloor >::Type_t floor( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnLog > { typedef Tensor< D, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnLog >::Type_t log( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnLog10 > { typedef Tensor< D, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnLog10 >::Type_t log10( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnSin > { typedef Tensor< D, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnSin >::Type_t sin( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypSin > { typedef Tensor< D, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypSin >::Type_t sinh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnSqrt > { typedef Tensor< D, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnSqrt >::Type_t sqrt( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnTan > { typedef Tensor< D, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnTan >::Type_t tan( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypTan > { typedef Tensor< D, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypTan >::Type_t tanh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpUnaryMinus > { typedef Tensor< D, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpUnaryMinus >::Type_t operator-( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpUnaryPlus > { typedef Tensor< D, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpUnaryPlus >::Type_t operator+( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpBitwiseNot > { typedef Tensor< D, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpBitwiseNot >::Type_t operator~( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpAdd >::Type_t operator+( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpAdd>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpAdd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpAdd >::Type_t operator+( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpAdd >::Type_t operator+( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpSubtract >::Type_t operator-( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpSubtract>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpSubtract> > Expr_t; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpSubtract >::Type_t operator-( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMultiply >::Type_t operator*( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpMultiply> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpMultiply >::Type_t operator*( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpDivide >::Type_t operator/( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpDivide>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpDivide> > Expr_t; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpDivide >::Type_t operator/( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpDivide >::Type_t operator/( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMod >::Type_t operator%( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMod>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpMod> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpMod >::Type_t operator%( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpMod >::Type_t operator%( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpMod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseAnd >::Type_t operator&( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseAnd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseOr >::Type_t operator|( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseOr> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseXor >::Type_t operator^( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseXor> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnLdexp >::Type_t ldexp( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnLdexp>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnLdexp> > Expr_t; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnLdexp >::Type_t ldexp( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnPow >::Type_t pow( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnPow>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnPow> > Expr_t; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnPow >::Type_t pow( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnPow >::Type_t pow( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnPow> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnFmod >::Type_t fmod( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnFmod>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnFmod> > Expr_t; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnFmod >::Type_t fmod( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnFmod >::Type_t fmod( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnArcTan2 >::Type_t atan2( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnArcTan2>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnArcTan2> > Expr_t; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnArcTan2 >::Type_t atan2( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(x,v2) ); }
template<class T1, class T2, int I, int J, int K, int L>
struct TensorDotTensor
{
  typedef typename TensorDotTensor<T1,T2,I,J,K,L/2>::Type_t Left_t;
  typedef typename TensorDotTensor<T1,T2,I,J,K+L/2,L-L/2>::Type_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
  static Type_t get(const T1& x, const T2& y)
    {
      return
        TensorDotTensor<T1,T2,I,J,K,L/2>::get(x,y) +
        TensorDotTensor<T1,T2,I,J,K+L/2,L-L/2>::get(x,y);
    }
};
template<class T1, class T2, int I, int J, int K>
struct TensorDotTensor<T1,T2,I,J,K,1>
{
  typedef typename TensorElem<T1,I,K>::Element_t Left_t;
  typedef typename TensorElem<T2,K,J>::Element_t Right_t;
  typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
  static Type_t get(const T1& x, const T2& y)
    {
      return TensorElem<T1,I,K>::get(x) * TensorElem<T2,K,J>::get(y);
    }
};
template<int D, class T, class T1, class T2, int I, int J>
struct TensorEngineElem<D,T,BinaryTensorOp<T1,T2,FnDot>, I, J,
  1>
{
  typedef BinaryTensorOp<T1,T2,FnDot> E;
  typedef TensorEngine<D,T,E> T0;
  typedef typename TensorDotTensor<T1,T2,I,J,0,T1::d>::Type_t Element_t;
  typedef Element_t ElementRef_t;
  typedef Element_t ConstElementRef_t;
  static Element_t get(const T0& x)
    {
      return TensorDotTensor<T1,T2,I,J,0,T1::d>::get(x.v1_m,x.v2_m);
    }
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Tensor<D,T1,E1> , Tensor<D,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef Tensor<D,T0,Full> Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , FnDot >::Type_t
dot( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 )
{
  typedef Tensor<D,T1,E1> V1;
  typedef Tensor<D,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef Tensor<D,T3,BinaryTensorOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<int D, class T, class E>
struct UnaryReturn< Tensor<D,T,E> , FnTrace >
{
  typedef T Type_t;
};
template<int D, class T, class E>
inline T
trace(const Tensor<D,T,E>& t)
{
  T result(0.0);
  for (int d = 0; d < D; d++) {
    result += t(d,d);
  }
  return result;
}
template<int D, class T>
inline T
trace(const Tensor<D,T,Diagonal>& t)
{
  T result(0.0);
  for (int d = 0; d < D; d++) {
    result += t(d);
  }
  return result;
}
template<int D, class T>
inline T
trace(const Tensor<D,T,Antisymmetric>& t)
{
  return T(0.0);
}
template<int D, class T, class E>
struct UnaryReturn< Tensor<D,T,E> , FnDet >
{
  typedef T Type_t;
};
template<int D, class T, class E>
inline T
det(const Tensor<D,T,E>& t)
{
  if (__builtin_expect(!!(D<4), true)) {} else Pooma::toss_cookies("Tensor det() function not implemented for D>3!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Tiny/TensorOperators.h", 405);
  return T(-999999.999999);
}
template<class T, class E>
inline T
det(const Tensor<3,T,E>& t)
{
  T result;
  result =
    t(0,0)*(t(1,1)*t(2,2) - t(1,2)*t(2,1)) +
    t(0,1)*(t(1,2)*t(2,0) - t(1,0)*t(2,2)) +
    t(0,2)*(t(1,0)*t(2,1) - t(1,1)*t(2,0));
  return result;
}
template<class T, class E>
inline T
det(const Tensor<2,T,E>& t)
{
  T result;
  result = t(0,0)*t(1,1) - t(0,1)*t(1,0);
  return result;
}
template<class T, class E>
inline T
det(const Tensor<1,T,E>& t)
{
  T result = t(0,0);
  return result;
}
template<class T>
inline T
det(const Tensor<3,T,Diagonal>& t)
{
  T result;
  result = t(0)*t(1)*t(2);
  return result;
}
template<class T>
inline T
det(const Tensor<2,T,Diagonal>& t)
{
  T result;
  result = t(0)*t(1);
  return result;
}
template<class T>
inline T
det(const Tensor<1,T,Diagonal>& t)
{
  T result = t(0);
  return result;
}
template<class T>
inline T
det(const Tensor<3,T,Antisymmetric>& t)
{
  return T(0.0);
}
template<class T>
inline T
det(const Tensor<2,T,Antisymmetric>& t)
{
  T result;
  result = t(0)*t(0);
  return result;
}
template<class T>
inline T
det(const Tensor<1,T,Antisymmetric>& t)
{
  return T(0.0);
}
template<int D, class T, class E>
struct UnaryReturn< Tensor<D,T,E> , FnTranspose >
{
  typedef Tensor<D,T,E> Type_t;
};
template<int D, class T, class E>
inline Tensor<D,T,E>
transpose(const Tensor<D,T,E>& t)
{
  Tensor<D,T,E> result;
  for (int i = 0; i < D; i++) {
    for (int j = 0; j < D; j++) {
      result(i,j) = t(j,i);
    }
  }
  return result;
}
template<int D, class T>
inline Tensor<D,T,Symmetric>
transpose(const Tensor<D,T,Symmetric>& t)
{
  Tensor<D,T,Symmetric> result;
  result = t;
  return result;
}
template<int D, class T>
inline Tensor<D,T,Antisymmetric>
transpose(const Tensor<D,T,Antisymmetric>& t)
{
  Tensor<D,T,Antisymmetric> result;
  result = -t;
  return result;
}
template<int D, class T>
inline Tensor<D,T,Diagonal>
transpose(const Tensor<D,T,Diagonal>& t)
{
  Tensor<D,T,Diagonal> result;
  result = t;
  return result;
}
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , OpEQ >
{
  typedef bool Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , OpNE >
{
  typedef bool Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpEQ >::Type_t
operator==(const Tensor<D,T1,E1>& t1, const Tensor<D,T2,E2>& t2)
{
  for (int i = 0; i < D; i++)
    for (int j = 0; j < D; j++)
      if (t1(i,j) != t2(i,j)) return false;
  return true;
}
template<int D, class T1, class T2, class E1, class E2>
inline typename
BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpNE >::Type_t
operator!=(const Tensor<D,T1,E1>& t1, const Tensor<D,T2,E2>& t2)
{
  return !(t1 == t2);
}
template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator+=( Tensor<D,T1,E1>& v1, const Tensor<D,T2,E1>& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename Tensor<D,T2,E1>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator+=( Tensor<D,T1,Symmetric>& v1, const Tensor<D,T2,Symmetric>& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Symmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator+=( Tensor<D,T1,Antisymmetric>& v1, const Tensor<D,T2,Antisymmetric>& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Antisymmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator+=( Tensor<D,T1,Diagonal>& v1, const Tensor<D,T2,Diagonal>& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename Tensor<D,T2,Diagonal>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator+=( Tensor<D,T1,E1>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator+=( Tensor<D,T1,Symmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator+=( Tensor<D,T1,Antisymmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator+=( Tensor<D,T1,Diagonal>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; }
template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator-=( Tensor<D,T1,E1>& v1, const Tensor<D,T2,E1>& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename Tensor<D,T2,E1>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator-=( Tensor<D,T1,Symmetric>& v1, const Tensor<D,T2,Symmetric>& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Symmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator-=( Tensor<D,T1,Antisymmetric>& v1, const Tensor<D,T2,Antisymmetric>& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Antisymmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator-=( Tensor<D,T1,Diagonal>& v1, const Tensor<D,T2,Diagonal>& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename Tensor<D,T2,Diagonal>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator-=( Tensor<D,T1,E1>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator-=( Tensor<D,T1,Symmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator-=( Tensor<D,T1,Antisymmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator-=( Tensor<D,T1,Diagonal>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; }
template<int D, class T, class EngineTag> class Tensor;
template<int D, class T, class EngineTag> class TensorEngine;
template <class T>
void reverseBytes(T&);
class Full;
class Antisymmetric;
class Symmetric;
class Diagonal;
template<int D, class EngineTag>
class TensorStorageSize {};
template<int D>
class TensorStorageSize<D, Full>
{
public:
  enum { Size = D*D };
};
template<int D>
class TensorStorageSize<D, Antisymmetric>
{
public:
  enum { Size = (D*D - D)/2 + 1/D };
};
template<int D>
class TensorStorageSize<D, Symmetric>
{
public:
  enum { Size = (D*D - D)/2 + D };
};
template<int D>
class TensorStorageSize<D, Diagonal>
{
public:
  enum { Size = D };
};
template<int D, class T=double, class EngineTag=Full>
class Tensor
{
public:
  enum { dimensions=2 };
  enum { d=D };
  typedef T Element_t;
  typedef EngineTag EngineTag_t;
  typedef TensorEngine<D,T,EngineTag> Engine_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
  typedef Tensor<D,T,EngineTag> This_t;
  Tensor() {}
  Tensor(const This_t& x) : engine_m(x.engine_m) {}
  template<int D2, class T2, class EngineTag2>
  Tensor(const Tensor<D2, T2, EngineTag2>& x) : engine_m(x) {}
  template<class X>
  explicit Tensor(const X& x) : engine_m(x) {}
  template<class X1, class X2>
  Tensor(const X1& x, const X2& y) : engine_m(x,y) {}
  template<class X1, class X2, class X3>
  Tensor(const X1& x, const X2& y, const X3& z) : engine_m(x,y,z) {}
  template<class X1, class X2, class X3, class X4>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
    : engine_m(x1,x2,x3,x4) {}
  template<class X1, class X2, class X3, class X4, class X5>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
         const X5& x5)
    : engine_m(x1,x2,x3,x4,x5) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
         const X5& x5, const X6& x6)
    : engine_m(x1,x2,x3,x4,x5,x6) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
    class X7>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
         const X5& x5, const X6& x6, const X7& x7)
    : engine_m(x1,x2,x3,x4,x5,x6,x7) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
    class X7, class X8>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
         const X5& x5, const X6& x6, const X7& x7, const X8& x8)
    : engine_m(x1,x2,x3,x4,x5,x6,x7,x8) {}
  template<class X1, class X2, class X3, class X4, class X5, class X6,
    class X7, class X8, class X9>
  Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
         const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
    : engine_m(x1,x2,x3,x4,x5,x6,x7,x8,x9) {}
  ~Tensor() {}
  This_t& operator=(const This_t& x)
  {
    if ( this != &x )
      engine() = x.engine();
    return *this;
  }
  template<class T1, class EngineTag1>
  This_t& operator=(const Tensor<d,T1,EngineTag1> &x)
  {
    engine() = x.engine();
    return *this;
  }
  template<class V>
  This_t&
  operator=(const V& x)
  {
    engine() = x;
    return *this;
  }
  ConstElementRef_t operator()(int i, int j) const
  {
    return engine()(i,j);
  }
  ElementRef_t operator()(int i, int j)
  {
    return engine()(i,j);
  }
  ConstElementRef_t operator()(int i) const { return engine()(i); }
  ElementRef_t operator()(int i) { return engine()(i); }
  const Engine_t& engine() const { return engine_m; }
  Engine_t& engine() { return engine_m; }
  template<class Out>
  void print(Out &out) const;
  inline void reverseBytes() { engine_m.reverseBytes(); }
private:
  Engine_t engine_m;
};
template<int D, class T, class EngineTag>
template<class Out>
void Tensor<D, T, EngineTag>::print(Out &out) const
{
  std::ios::fmtflags incomingFormatFlags = out.flags();
  long width = out.width();
  long precision = out.precision();
  out.width(0);
  out << "(";
  for (int i = 0; i < D; i++) {
    out << "(";
    out.flags(incomingFormatFlags);
    out.width(width);
    out.precision(precision);
    out << (*this)(i,0);
    for (int j = 1; j < D; j++) {
      out << " ";
      out.flags(incomingFormatFlags);
      out.width(width);
      out.precision(precision);
      out << (*this)(i,j);
    }
    out << ")";
  }
  out << ")";
}
template<int D, class T, class E>
std::ostream &operator<<(std::ostream &out, const Tensor<D,T,E> &t)
{
  t.print(out);
  return out;
}
template <int D, class T, class E>
struct ElementProperties< Tensor<D,T,E> >
  : public TrivialElementProperties< Tensor<D,T,E> >
{ };
template<int D, class T>
class TensorEngine<D, T, Full>
{
public:
  enum { dimensions=2 };
  enum { d=D };
  typedef T Element_t;
  typedef Full EngineTag_t;
  typedef T& ElementRef_t;
  typedef const T& ConstElementRef_t;
  typedef T& CTElementRef_t;
  typedef const T& CTConstElementRef_t;
  typedef TensorEngine<D,T,Full> This_t;
  TensorEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
  }
  TensorEngine(const TensorEngine<D,T,Full>& x)
  {
    TensorAssign<This_t,This_t,OpAssign,0,D,0,D>
      ::apply(*this,x,OpAssign());
  }
  template<class X>
  explicit TensorEngine(const X& x)
  {
    TensorAssign<This_t,X,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
  }
  explicit TensorEngine(const T& x)
  {
    for (int i = 0 ; i < D*D ; i++) {
      (*this)(i) = x;
    }
  }
  template<class X1, class X2, class X3, class X4>
  TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
  {
    PoomaCTAssert<(D == 2)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
    class X7, class X8, class X9>
  TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
               const X5& x5, const X6& x6, const X7& x7, const X8& x8,
               const X9& x9)
  {
    PoomaCTAssert<(D == 3)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
    (*this)(5) = x6;
    (*this)(6) = x7;
    (*this)(7) = x8;
    (*this)(8) = x9;
  }
  ~TensorEngine() {}
  This_t&
  operator=(const This_t& x)
  {
    if (this != &x) {
      TensorAssign<This_t,This_t,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
    }
    return *this;
  }
  template<class V>
  This_t&
  operator=(const V& x)
  {
    TensorAssign<This_t,V,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
    return *this;
  }
  template<int I, int J>
  CTConstElementRef_t getIJ() const
  {
    PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
    return x_m[I + D*J];
  }
  template<int I, int J>
  CTElementRef_t getIJ()
  {
    PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
    return x_m[I + D*J];
  }
  ConstElementRef_t operator()(int i,int j) const
  {
    ;
    return x_m[i + D*j];
  }
  ElementRef_t operator()(int i,int j)
  {
    ;
    return x_m[i + D*j];
  }
  ConstElementRef_t operator()(int i) const
  {
    ;
    return x_m[i];
  }
  ElementRef_t operator()(int i)
  {
    ;
    return x_m[i];
  }
  const T* data() const{
    return (const T*) &x_m[0];
  }
  T* data(){
    return (T*) &x_m[0];
  }
  inline void reverseBytes()
  {
    const int sz = TensorStorageSize<d, EngineTag_t>::Size;
    for (int i = 0; i < sz; ++i)
      ::reverseBytes(x_m[i]);
  }
private:
  T x_m[TensorStorageSize<d, EngineTag_t>::Size];
};
template<int D, class T>
class TensorEngine<D, T, Antisymmetric>
{
public:
  enum { dimensions=2 };
  enum { d=D };
  typedef T Element_t;
  typedef Antisymmetric EngineTag_t;
  class AssignProxy {
  public:
    AssignProxy(Element_t &elem, int where)
      : elem_m(elem), where_m(where) { }
    AssignProxy(const AssignProxy &model)
      // LLVM: Initialize where_m with model.where_m
      : elem_m(model.elem_m), where_m(model.where_m) { }
    AssignProxy &operator=(const AssignProxy &a) const
    {
      ;
      elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
      return const_cast<AssignProxy &>(*this);
    }
    AssignProxy &operator=(const Element_t &e) const
    {
      ;
      elem_m = where_m < 0 ? -e : e;
      return const_cast<AssignProxy &>(*this);
    }
    operator Element_t() const
    {
      return (where_m < 0 ? -elem_m : elem_m);
    }
  private:
    // LLVM: Remove 'mutable' keyword from elem_m.
    Element_t &elem_m;
    mutable int where_m;
  };
  typedef AssignProxy ElementRef_t;
  typedef T ConstElementRef_t;
  typedef T& CTElementRef_t;
  typedef T CTConstElementRef_t;
  typedef TensorEngine<d,T,Antisymmetric> This_t;
  TensorEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
  }
  TensorEngine(const TensorEngine<d,T,Antisymmetric> &x)
  {
    TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
  }
  template<class X>
  explicit TensorEngine(const X& x)
  {
    TensorAssign<This_t,X,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
  }
  explicit TensorEngine(const T &x) {
    for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
      x_m[i] = x;
    }
  }
  template<class X1, class X2, class X3>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
  {
    PoomaCTAssert<(D == 3)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
               const X5& x5, const X6& x6)
  {
    PoomaCTAssert<(D == 4)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
    (*this)(5) = x6;
  }
  ~TensorEngine() {}
  This_t&
  operator=(const This_t& x)
  {
    if (this != &x) {
      TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
        apply(*this,x,OpAssign());
    }
    return *this;
  }
  template<class V>
  This_t&
  operator=(const V& x)
  {
    TensorAssign<This_t,V,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
    return *this;
  }
  template<int I, int J>
  CTConstElementRef_t getIJ() const
  {
    PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
    if (I == J) {
      return This_t::Zero;
    } else {
      int lo = I < J ? I : J;
      int hi = I > J ? I : J;
      int symmetrySign = I < J ? -1 : 1;
      return symmetrySign * x_m[((hi - 1)*hi/2) + lo];
    }
  }
  template<int I, int J>
  CTElementRef_t getIJ()
  {
    PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d) && (I > J))>::test();
    return x_m[((I - 1)*I/2) + J];
  }
  ConstElementRef_t operator()(int i,int j) const
  {
    ;
    if (i == j) {
      return This_t::Zero;
    } else if (i < j) {
      return -x_m[((j - 1)*j/2) + i];
    } else {
      return x_m[((i - 1)*i/2) + j];
    }
  }
  ElementRef_t operator()(int i,int j)
  {
    ;
    if (i == j) {
      return AssignProxy(This_t::Zero, 0);
    } else {
      int lo = i < j ? i : j;
      int hi = i > j ? i : j;
      return AssignProxy(x_m[((hi-1)*hi/2) + lo], i - j);
    }
  }
  ConstElementRef_t operator()(int i) const
  {
    ;
    return x_m[i];
  }
  ElementRef_t operator()(int i)
  {
    ;
    return AssignProxy(x_m[i], 1);
  }
  const T* data() const{
    return (const T*) &x_m[0];
  }
  T* data(){
    return (T*) &x_m[0];
  }
  inline void reverseBytes()
  {
    const int sz = TensorStorageSize<d, EngineTag_t>::Size;
    for (int i = 0; i < sz; ++i)
      ::reverseBytes(x_m[i]);
  }
private:
  T x_m[TensorStorageSize<d, EngineTag_t>::Size];
  static T Zero;
};
template<int D, class T>
T TensorEngine<D,T,Antisymmetric>::Zero = 0.0;
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<1,T,Antisymmetric>,T2,Op,0,1,0,1>
{
  static void apply(TensorEngine<1,T,Antisymmetric> &x, const T2 &y,
                    Op op=Op())
  { }
};
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<2,T,Antisymmetric>,T2,Op,0,2,0,2>
{
  static void apply(TensorEngine<2,T,Antisymmetric> &x, const T2 &y,
                    Op op=Op())
  {
    TensorAssign<TensorEngine<2,T,Antisymmetric>,T2,Op,1,1,0,1>::apply(x,y,op);
  }
};
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,0,3,0,3>
{
  static void apply(TensorEngine<3,T,Antisymmetric> &x, const T2 &y,
      Op op=Op())
  {
    TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,1,1,0,1>::apply(x,y,op);
    TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,2,1,0,2>::apply(x,y,op);
  }
};
template<int D, class T>
class TensorEngine<D, T, Symmetric>
{
public:
  enum { dimensions=2 };
  enum { d=D };
  typedef T Element_t;
  typedef Symmetric EngineTag_t;
  typedef T& ElementRef_t;
  typedef const T& ConstElementRef_t;
  typedef T& CTElementRef_t;
  typedef const T& CTConstElementRef_t;
  typedef TensorEngine<D,T,Symmetric> This_t;
  TensorEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
  }
  TensorEngine(const TensorEngine<D,T,Symmetric> &x)
  {
    TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
  }
  template<class X>
  explicit TensorEngine(const X &x)
  {
    *this = x;
  }
  explicit TensorEngine(const T &x) {
    for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
      x_m[i] = x;
    }
  }
  template<class X1, class X2, class X3>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
  {
    PoomaCTAssert<(D == 2)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
               const X5 &x5, const X6 &x6)
  {
    PoomaCTAssert<(D == 3)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
    (*this)(5) = x6;
  }
  ~TensorEngine() {}
  This_t&
  operator=(const This_t &x)
  {
    if (this != &x) {
      TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
        apply(*this,x,OpAssign());
    }
    return *this;
  }
  template<class V>
  This_t&
  operator=(const V &x)
  {
    TensorAssign<This_t,V,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
    return *this;
  }
  template<int I, int J>
  CTConstElementRef_t getIJ() const
  {
    PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
    int lo = I < J ? I : J;
    int hi = I > J ? I : J;
    return x_m[((hi + 1)*hi/2) + lo];
  }
  template<int I, int J>
  CTElementRef_t getIJ()
  {
    PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
    int lo = I < J ? I : J;
    int hi = I > J ? I : J;
    return x_m[((hi + 1)*hi/2) + lo];
  }
  ConstElementRef_t operator()(int i,int j) const
  {
    ;
    int lo = i < j ? i : j;
    int hi = i > j ? i : j;
    return x_m[((hi + 1)*hi/2) + lo];
  }
  ElementRef_t operator()(int i,int j)
  {
    ;
    int lo = i < j ? i : j;
    int hi = i > j ? i : j;
    return x_m[((hi + 1)*hi/2) + lo];
  }
  ConstElementRef_t operator()(int i) const
  {
    ;
    return x_m[i];
  }
  ElementRef_t operator()(int i)
  {
    ;
    return x_m[i];
  }
  const T* data() const{
    return (const T*) &x_m[0];
  }
  T* data(){
    return (T*) &x_m[0];
  }
  inline void reverseBytes()
  {
    const int sz = TensorStorageSize<d, EngineTag_t>::Size;
    for (int i = 0; i < sz; ++i)
      ::reverseBytes(x_m[i]);
  }
private:
  T x_m[TensorStorageSize<d, EngineTag_t>::Size];
};
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,0,2,0,2>
{
  static void apply(TensorEngine<2,T,Symmetric> &x, const T2 &y,
                    Op op=Op())
  {
    TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,0,1,0,1>::apply(x,y,op);
    TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,1,1,0,2>::apply(x,y,op);
  }
};
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,0,3,0,3>
{
  static void apply(TensorEngine<3,T,Symmetric> &x, const T2 &y,
                    Op op=Op())
  {
    TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,0,1,0,1>::apply(x,y,op);
    TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,1,1,0,2>::apply(x,y,op);
    TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,2,1,0,3>::apply(x,y,op);
  }
};
template<int D, class T>
class TensorEngine<D, T, Diagonal>
{
public:
  enum { dimensions=2 };
  enum { d=D };
  typedef T Element_t;
  typedef Diagonal EngineTag_t;
  class AssignProxy {
  public:
    AssignProxy(Element_t &elem, int where)
      : elem_m(elem), where_m(where) { }
    AssignProxy(const AssignProxy &model)
      // LLVM: Initialize where_m with model.where_m
      : elem_m(model.elem_m), where_m(model.where_m) { }
    AssignProxy &operator=(const AssignProxy &a) const
    {
      ;
      elem_m = a.elem_m;
      return const_cast<AssignProxy &>(*this);
    }
    AssignProxy &operator=(const Element_t &e) const
    {
      ;
      elem_m = e;
      return const_cast<AssignProxy &>(*this);
    }
    operator Element_t() const
    {
      return (elem_m);
    }
  private:
    // LLVM: Remove 'mutable' keyword from elem_m.
    Element_t &elem_m;
    mutable int where_m;
  };
  typedef AssignProxy ElementRef_t;
  typedef T ConstElementRef_t;
  typedef T& CTElementRef_t;
  typedef T CTConstElementRef_t;
  typedef TensorEngine<D,T,Diagonal> This_t;
  TensorEngine()
  {
    PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
  }
  TensorEngine(const TensorEngine<D,T,Diagonal> &x)
  {
    TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
  }
  template<class X>
  explicit TensorEngine(const X &x)
  {
    *this = x;
  }
  explicit TensorEngine(const T &x) {
    for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
      x_m[i] = x;
    }
  }
  template<class X1, class X2>
  TensorEngine(const X1 &x1, const X2 &x2)
  {
    PoomaCTAssert<(D == 2)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
  }
  template<class X1, class X2, class X3>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
  {
    PoomaCTAssert<(D == 3)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
  }
  template<class X1, class X2, class X3, class X4>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4)
  {
    PoomaCTAssert<(D == 4)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
  }
  template<class X1, class X2, class X3, class X4, class X5>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
               const X5 &x5)
  {
    PoomaCTAssert<(D == 5)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
               const X5 &x5, const X6 &x6)
  {
    PoomaCTAssert<(D == 6)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
    (*this)(5) = x6;
  }
  template<class X1, class X2, class X3, class X4, class X5, class X6,
    class X7>
  TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
               const X5 &x5, const X6 &x6, const X7 &x7)
  {
    PoomaCTAssert<(D == 7)>::test();
    (*this)(0) = x1;
    (*this)(1) = x2;
    (*this)(2) = x3;
    (*this)(3) = x4;
    (*this)(4) = x5;
    (*this)(5) = x6;
    (*this)(6) = x7;
  }
  ~TensorEngine() {}
  This_t&
  operator=(const This_t &x)
  {
    if (this != &x) {
      TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
        apply(*this,x,OpAssign());
    }
    return *this;
  }
  template<class V>
  This_t&
  operator=(const V &x)
  {
    TensorAssign<This_t,V,OpAssign,0,d,0,d>::
      apply(*this,x,OpAssign());
    return *this;
  }
  template<int I, int J>
  CTConstElementRef_t getIJ() const
  {
    PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
    if (I != J) {
      return This_t::Zero;
    } else {
      return x_m[I];
    }
  }
  template<int I, int J>
  CTElementRef_t getIJ()
  {
    PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
    PoomaCTAssert<(I == J)>::test();
    return x_m[I];
  }
  ConstElementRef_t operator()(int i, int j) const
  {
    ;
    if (i != j) {
      return This_t::Zero;
    } else {
      return x_m[i];
    }
  }
  ElementRef_t operator()(int i, int j)
  {
    ;
    if (i != j) {
      return AssignProxy(This_t::Zero, 0);
    } else {
      return AssignProxy(x_m[i], 1);
    }
  }
  ConstElementRef_t operator()(int i) const
  {
    ;
    return x_m[i];
  }
  ElementRef_t operator()(int i)
  {
    ;
    return AssignProxy(x_m[i], 1);
  }
  const T* data() const{
    return (const T*) &x_m[0];
  }
  T* data(){
    return (T*) &x_m[0];
  }
  inline void reverseBytes()
  {
    const int sz = TensorStorageSize<d, EngineTag_t>::Size;
    for (int i = 0; i < sz; ++i)
      ::reverseBytes(x_m[i]);
  }
private:
  T x_m[TensorStorageSize<d, EngineTag_t>::Size];
  static T Zero;
};
template<int D, class T>
T TensorEngine<D,T,Diagonal>::Zero = 0.0;
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,0,2,0,2>
{
  static void apply(TensorEngine<2,T,Diagonal> &x, const T2 &y, Op op=Op())
  {
    TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,0,1,0,1>::apply(x,y,op);
    TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,1,1,1,1>::apply(x,y,op);
  }
};
template<class T, class T2, class Op>
struct TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,0,3,0,3>
{
  static void apply(TensorEngine<3,T,Diagonal> &x, const T2 &y, Op op=Op())
  {
    TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,0,1,0,1>::apply(x,y,op);
    TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,1,1,1,1>::apply(x,y,op);
    TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,2,1,2,1>::apply(x,y,op);
  }
};
template<class T, class Components> struct ComponentAccess;
template<int D, class T, class E, int N>
struct ComponentAccess< Tensor<D, T, E>, Loc<N> >
{
  typedef Tensor<D, T, E> V;
  typedef typename V::Element_t Element_t;
  typedef typename V::ElementRef_t ElementRef_t;
  static inline ElementRef_t indexRef(V &t, const Loc<N> &l)
  {
    PoomaCTAssert<(N==2)>::test();
    return t(l[0].first(), l[1].first());
  }
  static inline Element_t index(const V &t, const Loc<N> &l)
  {
    PoomaCTAssert<(N==2)>::test();
    return t(l[0].first(), l[1].first());
  }
};
template<int D, class T, int I, int J>
struct TensorElem< TensorEngine<D,T,Full> , I , J>
{
  typedef TensorEngine<D,T,Full> V;
  typedef TensorEngineElem<D,T,Full,I,J,
    Writable<D,Full,I,J>::value> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x); }
  static ElementRef_t get(V& x) { return TE::get(x); }
};
template<int D, class T, int I, int J>
struct TensorElem< TensorEngine<D,T,Antisymmetric> , I , J>
{
  typedef TensorEngine<D,T,Antisymmetric> V;
  typedef TensorEngineElem<D,T,Antisymmetric,I,J,
    Writable<D,Antisymmetric,I,J>::value> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x); }
  static ElementRef_t get(V& x) { return TE::get(x); }
};
template<int D, class T, int I, int J>
struct TensorElem< TensorEngine<D,T,Symmetric> , I , J>
{
  typedef TensorEngine<D,T,Symmetric> V;
  typedef TensorEngineElem<D,T,Symmetric,I,J,
    Writable<D,Symmetric,I,J>::value> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x); }
  static ElementRef_t get(V& x) { return TE::get(x); }
};
template<int D, class T, int I, int J>
struct TensorElem< TensorEngine<D,T,Diagonal> , I , J>
{
  typedef TensorEngine<D,T,Diagonal> V;
  typedef TensorEngineElem<D,T,Diagonal,I,J,
    Writable<D,Diagonal,I,J>::value> TE;
  typedef typename TE::Element_t Element_t;
  typedef typename TE::ConstElementRef_t ConstElementRef_t;
  typedef typename TE::ElementRef_t ElementRef_t;
  static ConstElementRef_t get(const V& x) { return TE::get(x); }
  static ElementRef_t get(V& x) { return TE::get(x); }
};
template<class OutputEngineTag, int D, class T, class EngineTag>
class Symmetrize;
template<class OutputEngineTag, int D, class T, class EngineTag>
Tensor<D, T, OutputEngineTag>
symmetrize(const Tensor<D, T, EngineTag> &x)
{
  Symmetrize<OutputEngineTag, D, T, EngineTag> s;
  return s.apply(x);
}
template<class OutputEngineTag, int D, class T, class E>
struct UnaryReturn< Tensor<D,T,E> , FnSymmetrize<OutputEngineTag> >
{
  typedef Tensor<D,T,OutputEngineTag> Type_t;
};
template<class OutputEngineTag, int D, class T, class EngineTag>
class Symmetrize
{
public:
  Symmetrize() {};
  Tensor<D, T, OutputEngineTag>
  apply(const Tensor<D, T, EngineTag> &x) {
    Tensor<D, T, OutputEngineTag> y(-99.99);
    return y;
  }
};
template<int D, class T, class EngineTag>
class Symmetrize<Symmetric, D, T, EngineTag>
{
public:
  Tensor<D, T, Symmetric>
  apply(const Tensor<D, T, EngineTag> &x)
  {
    Tensor<D, T, Symmetric> y;
    for (int i = 0; i < D; i++) {
      y(i,i) = x(i,i);
      for (int j = i + 1; j < D; j++) {
        y(i,j) = (x(i,j) + x(j,i))*0.5;
      }
    }
    return y;
  }
};
template<int D, class T>
class Symmetrize<Symmetric, D, T, Antisymmetric>
{
public:
  Tensor<D, T, Symmetric>
  apply(const Tensor<D, T, Antisymmetric> &x)
  {
    Tensor<D, T, Symmetric> y(0.0);
    return y;
  }
};
template<int D, class T>
class Symmetrize<Symmetric, D, T, Diagonal>
{
public:
  Tensor<D, T, Symmetric>
  apply(const Tensor<D, T, Diagonal> &x)
  {
    Tensor<D, T, Symmetric> y(0.0);
    for (int i = 0; i < D; i++) {
      y(i,i) = x(i,i);
    }
    return y;
  }
};
template<int D, class T, class EngineTag>
class Symmetrize<Antisymmetric, D, T, EngineTag>
{
public:
  Tensor<D, T, Antisymmetric>
  apply(const Tensor<D, T, EngineTag> &x)
  {
    Tensor<D, T, Antisymmetric> y;
    for (int i = 1; i < D; i++) {
      for (int j = 0; j < i; j++) {
        y(((i - 1)*i/2)+j) = (x(i,j) - x(j,i))*0.5;
      }
    }
    return y;
  }
};
template<int D, class T>
class Symmetrize<Antisymmetric, D, T, Symmetric>
{
public:
  Tensor<D, T, Antisymmetric>
  apply(const Tensor<D, T, Symmetric> &x)
  {
    Tensor<D, T, Antisymmetric> y(0.0);
    return y;
  }
};
template<int D, class T>
class Symmetrize<Antisymmetric, D, T, Diagonal>
{
public:
  Tensor<D, T, Antisymmetric>
  apply(const Tensor<D, T, Diagonal> &x)
  {
    Tensor<D, T, Antisymmetric> y(0.0);
    return y;
  }
};
template<int D, class T, class EngineTag>
class Symmetrize<Diagonal, D, T, EngineTag>
{
public:
  Tensor<D, T, Diagonal>
  apply(const Tensor<D, T, EngineTag> &x)
  {
    Tensor<D, T, Diagonal> y;
    for (int i = 0; i < D; i++) {
      y(i) = x(i,i);
    }
    return y;
  }
};
template<int D, class T>
class Symmetrize<Diagonal, D, T, Antisymmetric>
{
public:
  Tensor<D, T, Diagonal>
  apply(const Tensor<D, T, Antisymmetric> &x)
  {
    Tensor<D, T, Diagonal> y(0.0);
    return y;
  }
};
template<int D, class T>
class Symmetrize<Diagonal, D, T, Symmetric>
{
public:
  Tensor<D, T, Diagonal>
  apply(const Tensor<D, T, Symmetric> &x)
  {
    Tensor<D, T, Diagonal> y(0.0);
    for (int i = 0; i < D; i++) {
      y(i) = x(i,i);
    }
    return y;
  }
};
template<int D, class T, class EngineTag>
class Symmetrize<Full, D, T, EngineTag>
{
public:
  Tensor<D, T, Full>
  apply(const Tensor<D, T, EngineTag> &x)
  {
    Tensor<D, T, Full> y;
    for (int i = 0; i < D; i++) {
      for (int j = 0; j < D; j++) {
        y(i,j) = x(i,j);
      }
    }
    return y;
  }
};
template<int D, class T, class E> class Tensor;
template<int D, class T, class E> class TensorEngine;
template<int D, class T, class E> class Vector;
template<int D, class T, class E> class VectorEngine;
template<class V1, class T2, int I, int B, int L>
struct VectorDotTensor
{
  typedef typename VectorDotTensor<V1,T2,I,B,L/2>::Type_t E1;
  typedef typename VectorDotTensor<V1,T2,I,B+L/2,L-L/2>::Type_t E2;
  typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
  static Type_t get(const V1& v1, const T2& t2)
    {
      return
        VectorDotTensor<V1,T2,I,B,L/2>::get(v1,t2) +
        VectorDotTensor<V1,T2,I,B+L/2,L-L/2>::get(v1,t2);
    }
};
template<class V1, class T2, int I, int B>
struct VectorDotTensor<V1,T2,I,B,1>
{
  typedef typename VectorElem<V1,B>::Element_t E1;
  typedef typename TensorElem<T2,B,I>::Element_t E2;
  typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
  static Type_t get(const V1& v1, const T2& t2)
    {
      return VectorElem<V1,B>::get(v1) * TensorElem<T2,B,I>::get(t2);
    }
};
template<int D, class T1, class T2, class T3, class E1, class E2, int I>
struct VectorEngineElem<D,T3,
  BinaryVectorOp<Vector<D,T1,E1>,Tensor<D,T2,E2>,FnDot>,I>
{
  typedef Vector<D,T1,E1> V1;
  typedef Tensor<D,T2,E2> V2;
  typedef VectorEngine<D,T3,BinaryVectorOp<V1,V2,FnDot> > V;
  typedef typename VectorDotTensor<V1,V2,I,0,D>::Type_t T0;
  typedef T0 Element_t;
  typedef T0 ConstElementRef_t;
  typedef T0 ElementRef_t;
  static T0 get(const V& x)
    {
      return VectorDotTensor<V1,V2,I,0,D>::get(x.v1_m,x.v2_m);
    }
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Tensor<D,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef Vector<D,T0,Full> Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< Vector<D,T1,E1>,Tensor<D,T2,E2> , FnDot >::Type_t
dot( const Vector<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 )
{
  typedef Vector<D,T1,E1> V1;
  typedef Tensor<D,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef Vector<D,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<class T1, class V2, int I, int B, int L>
struct TensorDotVector
{
  typedef typename TensorDotVector<T1,V2,I,B,L/2>::Type_t E1;
  typedef typename TensorDotVector<T1,V2,I,B+L/2,L-L/2>::Type_t E2;
  typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
  static Type_t get(const T1& t1, const V2& v2)
    {
      return
        TensorDotVector<T1,V2,I,B,L/2>::get(t1,v2) +
        TensorDotVector<T1,V2,I,B+L/2,L-L/2>::get(t1,v2);
    }
};
template<class T1, class V2, int I, int B>
struct TensorDotVector<T1,V2,I,B,1>
{
  typedef typename TensorElem<T1,I,B>::Element_t E1;
  typedef typename VectorElem<V2,B>::Element_t E2;
  typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
  static Type_t get(const T1& t1, const V2& v2)
    {
      return TensorElem<T1,I,B>::get(t1) * VectorElem<V2,B>::get(v2);
    }
};
template<int D, class T1, class T2, class T3, class E1, class E2, int I>
struct VectorEngineElem<D,T3,
  BinaryVectorOp<Tensor<D,T1,E1>,Vector<D,T2,E2>,FnDot>,I>
{
  typedef Tensor<D,T1,E1> V1;
  typedef Vector<D,T2,E2> V2;
  typedef VectorEngine<D,T3,BinaryVectorOp<V1,V2,FnDot> > V;
  typedef typename TensorDotVector<V1,V2,I,0,D>::Type_t T0;
  typedef T0 Element_t;
  typedef T0 ConstElementRef_t;
  typedef T0 ElementRef_t;
  static T0 get(const V& x)
    {
      return TensorDotVector<V1,V2,I,0,D>::get(x.v1_m,x.v2_m);
    }
};
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Tensor<D,T1,E1> , Vector<D,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef Vector<D,T0,Full> Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< Tensor<D,T1,E1> , Vector<D,T2,E2>, FnDot >::Type_t
dot( const Tensor<D,T1,E1>& v1 , const Vector<D,T2,E2>& v2 )
{
  typedef Tensor<D,T1,E1> V1;
  typedef Vector<D,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef Vector<D,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2>, FnOuterProduct >
{
  typedef typename BinaryReturn<T1, T2, OpMultiply>::Type_t T0;
  typedef Tensor<D, T0> Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
outerProduct(const Vector<D,T1,E1> &v1, const Vector<D,T2,E2> &v2 )
{
  typedef typename
    BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
    Return_t;
  Return_t ret;
  for (int i = 0; i < D; ++i)
    for (int j = 0; j < D; ++j)
      ret(i, j) = v1(i) * v2(j);
  return ret;
}
template<int D1, int D2, class T, class E> class TinyMatrix;
template<int D1, int D2, class T, class E> class TinyMatrixEngine;
template<int D, class T, class E> class Vector;
template<int D, class T, class E> class VectorEngine;
template<class V1, class T2, int I, int B, int L>
struct VectorDotTinyMatrix
{
  typedef typename VectorDotTinyMatrix<V1,T2,I,B,L/2>::Type_t E1;
  typedef typename VectorDotTinyMatrix<V1,T2,I,B+L/2,L-L/2>::Type_t E2;
  typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
  static Type_t get(const V1& v1, const T2& t2)
    {
      return
        VectorDotTinyMatrix<V1,T2,I,B,L/2>::get(v1,t2) +
        VectorDotTinyMatrix<V1,T2,I,B+L/2,L-L/2>::get(v1,t2);
    }
};
template<class V1, class T2, int I, int B>
struct VectorDotTinyMatrix<V1,T2,I,B,1>
{
  typedef typename VectorElem<V1,B>::Element_t E1;
  typedef typename TinyMatrixElem<T2,B,I>::Element_t E2;
  typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
  static Type_t get(const V1& v1, const T2& t2)
    {
      return VectorElem<V1,B>::get(v1) * TinyMatrixElem<T2,B,I>::get(t2);
    }
};
template<int D1, int D2, class T1, class T2, class T3, class E1, class E2, int I>
struct VectorEngineElem<D2,T3,
  BinaryVectorOp<Vector<D1,T1,E1>,TinyMatrix<D1,D2,T2,E2>,FnDot>,I>
{
  typedef Vector<D1,T1,E1> V1;
  typedef TinyMatrix<D1,D2,T2,E2> V2;
  typedef VectorEngine<D2,T3,BinaryVectorOp<V1,V2,FnDot> > V;
  typedef typename VectorDotTinyMatrix<V1,V2,I,0,D1>::Type_t T0;
  typedef T0 Element_t;
  typedef T0 ConstElementRef_t;
  typedef T0 ElementRef_t;
  static T0 get(const V& x)
    {
      return VectorDotTinyMatrix<V1,V2,I,0,D1>::get(x.v1_m,x.v2_m);
    }
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D1,T1,E1> , TinyMatrix<D1,D2,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef Vector<D2,T0,Full> Type_t;
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< Vector<D1,T1,E1>,TinyMatrix<D1,D2,T2,E2> , FnDot >::Type_t
dot( const Vector<D1,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 )
{
  typedef Vector<D1,T1,E1> V1;
  typedef TinyMatrix<D1,D2,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef Vector<D2,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<class T1, class V2, int I, int B, int L>
struct TinyMatrixDotVector
{
  typedef typename TinyMatrixDotVector<T1,V2,I,B,L/2>::Type_t E1;
  typedef typename TinyMatrixDotVector<T1,V2,I,B+L/2,L-L/2>::Type_t E2;
  typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
  static Type_t get(const T1& t1, const V2& v2)
    {
      return
        TinyMatrixDotVector<T1,V2,I,B,L/2>::get(t1,v2) +
        TinyMatrixDotVector<T1,V2,I,B+L/2,L-L/2>::get(t1,v2);
    }
};
template<class T1, class V2, int I, int B>
struct TinyMatrixDotVector<T1,V2,I,B,1>
{
  typedef typename TinyMatrixElem<T1,I,B>::Element_t E1;
  typedef typename VectorElem<V2,B>::Element_t E2;
  typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
  static Type_t get(const T1& t1, const V2& v2)
    {
      return TinyMatrixElem<T1,I,B>::get(t1) * VectorElem<V2,B>::get(v2);
    }
};
template<int D1, int D2, class T1, class T2, class T3, class E1, class E2, int I>
struct VectorEngineElem<D1,T3,
  BinaryVectorOp<TinyMatrix<D1,D2,T1,E1>,Vector<D2,T2,E2>,FnDot>,I>
{
  typedef TinyMatrix<D1,D2,T1,E1> V1;
  typedef Vector<D2,T2,E2> V2;
  typedef VectorEngine<D1,T3,BinaryVectorOp<V1,V2,FnDot> > V;
  typedef typename TinyMatrixDotVector<V1,V2,I,0,D2>::Type_t T0;
  typedef T0 Element_t;
  typedef T0 ConstElementRef_t;
  typedef T0 ElementRef_t;
  static T0 get(const V& x)
    {
      return TinyMatrixDotVector<V1,V2,I,0,D2>::get(x.v1_m,x.v2_m);
    }
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
struct BinaryReturn< TinyMatrix<D1,D2,T1,E1> , Vector<D2,T2,E2> , FnDot >
{
  typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
  typedef Vector<D1,T0,Full> Type_t;
};
template<int D1, int D2, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn< TinyMatrix<D1,D2,T1,E1> , Vector<D2,T2,E2>, FnDot >::Type_t
dot( const TinyMatrix<D1,D2,T1,E1>& v1 , const Vector<D2,T2,E2>& v2 )
{
  typedef TinyMatrix<D1,D2,T1,E1> V1;
  typedef Vector<D2,T2,E2> V2;
  typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
  typedef typename Return_t::Element_t T3;
  typedef Vector<D1,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
  return Return_t( Expr_t(v1,v2) );
}
template<int D, class T1, class T2, class E1, class E2>
struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2>, FnOuterProductAsTinyMatrix >
{
  typedef typename BinaryReturn<T1, T2, OpMultiply>::Type_t T0;
  typedef TinyMatrix<D, D, T0> Type_t;
};
template<int D, class T1, class T2, class E1, class E2>
inline
typename BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProductAsTinyMatrix>::Type_t
outerProductAsTinyMatrix(const Vector<D,T1,E1> &v1, const Vector<D,T2,E2> &v2 )
{
  typedef typename
    BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
    Return_t;
  Return_t ret;
  for (int i = 0; i < D; ++i)
    for (int j = 0; j < D; ++j)
      ret(i, j) = v1(i) * v2(j);
  return ret;
}
template<int Dim, class T, class EngineTag, class Op>
inline T globalReduction(const Vector<Dim, T, EngineTag> &v,
  const Op &op)
{
  T val = v(0);
  for (int i = 1; i < Dim; i++)
    op(val, v(i));
  return val;
}
template<int Dim, class T, class EngineTag, class Op>
inline T globalReduction(const Tensor<Dim, T, EngineTag> &t,
  const Op &op)
{
  T val = t(0, 0);
  for (int k = 1; k < Dim; k++)
    op(val, t(k, 0));
  for (int j = 1; j < Dim; j++)
    for (int i = 0; i < Dim; i++)
      op(val, t(i, j));
  return val;
}
template<int Dim, class T, class Op>
inline T globalReduction(const Tensor<Dim, T, Full> &t,
  const Op &op)
{
  T val = t(0, 0);
  for (int i = 1; i < TensorStorageSize<Dim, Full>::Size; i++)
    op(val, t(i));
  return val;
}
template<int Dim, class T, class Op>
inline T globalReduction(const Tensor<Dim, T, Antisymmetric> &t,
  const Op &op)
{
  T val = t(0,0);
  for (int i = 0; i < TensorStorageSize<Dim, Antisymmetric>::Size - 1 / Dim; i++)
    {
      op(val, t(i));
      op(val, -t(i));
    }
  return val;
}
template<int Dim, class T, class Op>
inline T globalReduction(const Tensor<Dim, T, Diagonal> &t,
  const Op &op)
{
  T val = t(0);
  for (int i = 1; i < TensorStorageSize<Dim, Diagonal>::Size; i++)
    op(val, t(i));
  if (Dim > 1)
    op(val, T(0));
  return val;
}
template<int Dim1, int Dim2, class T, class EngineTag, class Op>
inline T globalReduction(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m,
  const Op &op)
{
  T val = m(0, 0);
  for (int k = 1; k < Dim1; k++)
    op(val, m(k, 0));
  for (int j = 1; j < Dim2; j++)
    for (int i = 0; i < Dim1; i++)
      op(val, m(i, j));
  return val;
}
template<int Dim1, int Dim2, class T, class Op>
inline T globalReduction(const TinyMatrix<Dim1, Dim2, T, Full> &m,
  const Op &op)
{
  T val = m(0, 0);
  for (int i = 1; i < Dim1 * Dim2; i++)
    op(val, m(i));
  return val;
}
template<int Dim, class T, class EngineTag>
T sum(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, OpAddAssign());
}
template<int Dim, class T, class EngineTag>
T prod(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, OpMultiplyAssign());
}
template<int Dim, class T, class EngineTag>
T min(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, FnMinAssign());
}
template<int Dim, class T, class EngineTag>
T max(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, FnMaxAssign());
}
template<int Dim, class T, class EngineTag>
bool all(const Vector<Dim, T, EngineTag> &v)
{
  for (int i = 0; i < Dim; i++)
    if (!v(i))
      return false;
  return true;
}
template<int Dim, class T, class EngineTag>
bool any(const Vector<Dim, T, EngineTag> &v)
{
  for (int i = 0; i < Dim; i++)
    if (v(i))
      return true;
  return false;
}
template<int Dim, class T, class EngineTag>
T bitOr(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, OpBitwiseOrAssign());
}
template<int Dim, class T, class EngineTag>
T bitAnd(const Vector<Dim, T, EngineTag> &v)
{
  return globalReduction(v, OpBitwiseAndAssign());
}
template<int Dim, class T, class EngineTag>
T sum(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, OpAddAssign());
}
template<int Dim, class T>
T sum(const Tensor<Dim, T, Antisymmetric> &t)
{
  return T(0);
}
template<int Dim, class T, class EngineTag>
T prod(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, OpMultiplyAssign());
}
template<int Dim, class T>
T prod(const Tensor<Dim, T, Antisymmetric> &t)
{
  return T(0);
}
template<int Dim, class T, class EngineTag>
T min(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, FnMinAssign());
}
template<int Dim, class T, class EngineTag>
T max(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, FnMaxAssign());
}
template<int Dim, class T, class EngineTag>
bool all(const Tensor<Dim, T, EngineTag> &t)
{
  for (int j = 0; j < Dim; j++)
    for (int i = 0; i < Dim; i++)
      if (!t(i, j))
        return false;
  return true;
}
template<int Dim, class T>
bool all(const Tensor<Dim, T, Antisymmetric> &t)
{
  return false;
}
template<int Dim, class T, class EngineTag>
bool any(const Tensor<Dim, T, EngineTag> &t)
{
  for (int j = 0; j < Dim; j++)
    for (int i = 0; i < Dim; i++)
      if (t(i, j))
        return true;
  return false;
}
template<int Dim, class T, class EngineTag>
T bitOr(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, OpBitwiseOrAssign());
}
template<int Dim, class T, class EngineTag>
T bitAnd(const Tensor<Dim, T, EngineTag> &t)
{
  return globalReduction(t, OpBitwiseAndAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
T sum(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, OpAddAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
T prod(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, OpMultiplyAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
T min(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, FnMinAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
T max(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, FnMaxAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
bool all(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  for (int j = 0; j < Dim2; j++)
    for (int i = 0; i < Dim1; i++)
      if (!m(i, j))
        return false;
  return true;
}
template<int Dim1, int Dim2, class T, class EngineTag>
bool any(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  for (int j = 0; j < Dim2; j++)
    for (int i = 0; i < Dim1; i++)
      if (m(i, j))
        return true;
  return false;
}
template<int Dim1, int Dim2, class T, class EngineTag>
T bitOr(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, OpBitwiseOrAssign());
}
template<int Dim1, int Dim2, class T, class EngineTag>
T bitAnd(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
{
  return globalReduction(m, OpBitwiseAndAssign());
}
template<class T>
struct Zero
{
  operator T() const { return T(0); }
  bool operator==(const Zero<T>&) const { return true; }
  Zero() {}
  Zero(const Zero<T>&) {}
  Zero<T>& operator=(const Zero<T>&) { return *this; }
};
template<class T, class Op> struct UnaryReturn;
template<class T1, class T2, class Op> struct BinaryReturn;
template<class T>
  inline Zero<T> operator*(Zero<T>, const T&) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator*(const T&, Zero<T>) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator*(Zero<T>, Zero<T>) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator/(Zero<T>, const T&) { return Zero<T>(); }
template<class T>
struct BinaryReturn< Zero<T> , T , OpMultiply >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< T, Zero<T> , OpMultiply >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< Zero<T>, Zero<T> , OpMultiply >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< Zero<T> , T , OpDivide >
{
  typedef Zero<T> Type_t;
};
template<class T>
  inline const T& operator+(Zero<T>, const T& x) { return x; }
template<class T>
  inline const T& operator+(const T& x, Zero<T>) { return x; }
template<class T>
  inline Zero<T> operator+(Zero<T>, Zero<T>) { return Zero<T>(); }
template<class T>
  inline T operator-(Zero<T>, const T& x) { return -x; }
template<class T>
  inline const T& operator-(const T& x, Zero<T>) { return x; }
template<class T>
  inline Zero<T> operator-(Zero<T>, Zero<T>) { return Zero<T>(); }
template<class T>
struct BinaryReturn< Zero<T> , T , OpAdd >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< T, Zero<T> , OpAdd >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< Zero<T>, Zero<T> , OpAdd >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< Zero<T> , T , OpSubtract >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< T, Zero<T> , OpSubtract >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< Zero<T>, Zero<T> , OpSubtract >
{
  typedef Zero<T> Type_t;
};
template<class T>
  inline Zero<T> operator-(Zero<T>) { return Zero<T>(); }
template<class T>
struct UnaryReturn< Zero<T> , OpUnaryMinus >
{
  typedef Zero<T> Type_t;
};
template<class T>
  inline Zero<T> operator+(Zero<T>) { return Zero<T>(); }
template<class T>
struct UnaryReturn< Zero<T> , OpUnaryPlus >
{
  typedef Zero<T> Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< Zero<T1> , Zero<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2>
struct BinaryReturn< Zero<T1> , Zero<T2>, OpEQ >
{
  typedef typename BinaryReturn<T1,T2,OpEQ>::Type_t Type_t;
};
template<class T> struct Zero;
template<class T, class Op> struct UnaryReturn;
template<class T1, class T2, class Op> struct BinaryReturn;
template<class T>
struct One
{
  operator T() const { return T(1); }
  bool operator==(const One<T>&) const { return true; }
  One() {}
  One(const One<T>&) {}
  One<T>& operator=(const One<T>&) { return *this; }
};
template<class T>
struct MinusOne
{
  operator T() const { return T(-1); }
  bool operator==(const MinusOne<T>&) const { return true; }
  MinusOne() {}
  MinusOne(const One<T>&) {}
  MinusOne<T>& operator=(const MinusOne<T>&) { return *this; }
};
template<class T>
  inline MinusOne<T> operator-(One<T>) { return MinusOne<T>(); }
template<class T>
  inline One<T> operator-(MinusOne<T>) { return One<T>(); }
template<class T>
  inline T operator*(One<T>, const T& val) { return val; }
template<class T>
  inline T operator*(const T& val, One<T>) { return val; }
template<class T>
  inline One<T> operator*(One<T>, One<T>) { return One<T>(); }
template<class T>
  inline One<T> operator/(One<T>, One<T>) { return One<T>(); }
template<class T>
  inline T operator/(const T& val, One<T>) { return val; }
template<class T>
  inline T operator*(MinusOne<T>, const T& val) { return -val; }
template<class T>
  inline T operator*(const T& val, MinusOne<T>) { return -val; }
template<class T>
  inline One<T> operator*(MinusOne<T>, MinusOne<T>) { return One<T>(); }
template<class T>
  inline One<T> operator/(MinusOne<T>, MinusOne<T>) { return One<T>(); }
template<class T>
  inline T operator/(const T& val, MinusOne<T>) { return -val; }
template<class T>
  inline MinusOne<T> operator*(MinusOne<T>, One<T>) { return MinusOne<T>(); }
template<class T>
  inline MinusOne<T> operator*(One<T>, MinusOne<T>) { return MinusOne<T>(); }
template<class T>
  inline MinusOne<T> operator/(MinusOne<T>, One<T>) { return MinusOne<T>(); }
template<class T>
  inline MinusOne<T> operator/(One<T>, MinusOne<T>) { return MinusOne<T>(); }
template<class T>
  inline Zero<T> operator-(One<T>, One<T>) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator-(MinusOne<T>, MinusOne<T>) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator+(One<T>, MinusOne<T>) { return Zero<T>(); }
template<class T>
  inline Zero<T> operator+(MinusOne<T>, One<T>) { return Zero<T>(); }
template<class T>
  inline MinusOne<T> operator-(Zero<T>, One<T>) { return MinusOne<T>(); }
template<class T>
  inline One<T> operator-(Zero<T>, MinusOne<T>) { return One<T>(); }
template<class T>
struct UnaryReturn< One<T> , OpUnaryMinus >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct UnaryReturn< MinusOne<T> , OpUnaryMinus >
{
  typedef One<T> Type_t;
};
template<class T>
struct BinaryReturn< One<T> , T , OpMultiply >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< T, One<T> , OpMultiply >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< One<T>, One<T> , OpMultiply >
{
  typedef One<T> Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T> , T , OpMultiply >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< T, MinusOne<T> , OpMultiply >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, MinusOne<T> , OpMultiply >
{
  typedef One<T> Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, One<T> , OpMultiply >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct BinaryReturn< One<T>, MinusOne<T> , OpMultiply >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct BinaryReturn< T, One<T> , OpDivide >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< T, MinusOne<T> , OpDivide >
{
  typedef T Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, One<T> , OpDivide >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct BinaryReturn< One<T>, MinusOne<T> , OpDivide >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct BinaryReturn< One<T>, One<T> , OpSubtract >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, MinusOne<T> , OpSubtract >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< Zero<T>, One<T>, OpSubtract >
{
  typedef MinusOne<T> Type_t;
};
template<class T>
struct BinaryReturn< Zero<T>, MinusOne<T>, OpSubtract >
{
  typedef One<T> Type_t;
};
template<class T>
struct BinaryReturn< One<T>, MinusOne<T> , OpAdd >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, One<T> , OpAdd >
{
  typedef Zero<T> Type_t;
};
template<class T>
struct BinaryReturn< MinusOne<T>, MinusOne<T>, OpEQ>
{
  typedef bool Type_t;
};
template<class T>
struct BinaryReturn< One<T>, One<T>, OpEQ>
{
  typedef bool Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< One<T1> , One<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< MinusOne<T1> , MinusOne<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< One<T1>, Zero<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< Zero<T1>, One<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< MinusOne<T1>, Zero<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< Zero<T1>, MinusOne<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< One<T1>, MinusOne<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class T1, class T2, class Op>
struct BinaryReturn< MinusOne<T1>, One<T2>, Op >
{
  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
};
template<class A1> struct MultiArg1;
template<class A1, class A2> struct MultiArg2;
template<class A1, class A2, class A3> struct MultiArg3;
template<class A1, class A2, class A3, class A4> struct MultiArg4;
template<class A1, class A2, class A3, class A4, class A5> struct MultiArg5;
template<class A1, class A2, class A3, class A4, class A5, class A6> struct MultiArg6;
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct MultiArg7;
template<class A1, class Dom>
struct MultiArgView1
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef MultiArg1<A1_t> Type_t;
};
template<class A1, class A2, class Dom>
struct MultiArgView2
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef MultiArg2<A1_t, A2_t> Type_t;
};
template<class A1, class A2, class A3, class Dom>
struct MultiArgView3
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef typename View1<A3, Dom>::Type_t A3_t;
  typedef MultiArg3<A1_t, A2_t, A3_t> Type_t;
};
template<class A1, class A2, class A3, class A4, class Dom>
struct MultiArgView4
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef typename View1<A3, Dom>::Type_t A3_t;
  typedef typename View1<A4, Dom>::Type_t A4_t;
  typedef MultiArg4<A1_t, A2_t, A3_t, A4_t> Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class Dom>
struct MultiArgView5
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef typename View1<A3, Dom>::Type_t A3_t;
  typedef typename View1<A4, Dom>::Type_t A4_t;
  typedef typename View1<A5, Dom>::Type_t A5_t;
  typedef MultiArg5<A1_t, A2_t, A3_t, A4_t, A5_t> Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class Dom>
struct MultiArgView6
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef typename View1<A3, Dom>::Type_t A3_t;
  typedef typename View1<A4, Dom>::Type_t A4_t;
  typedef typename View1<A5, Dom>::Type_t A5_t;
  typedef typename View1<A6, Dom>::Type_t A6_t;
  typedef MultiArg6<A1_t, A2_t, A3_t, A4_t, A5_t, A6_t> Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Dom>
struct MultiArgView7
{
  typedef typename View1<A1, Dom>::Type_t A1_t;
  typedef typename View1<A2, Dom>::Type_t A2_t;
  typedef typename View1<A3, Dom>::Type_t A3_t;
  typedef typename View1<A4, Dom>::Type_t A4_t;
  typedef typename View1<A5, Dom>::Type_t A5_t;
  typedef typename View1<A6, Dom>::Type_t A6_t;
  typedef typename View1<A7, Dom>::Type_t A7_t;
  typedef MultiArg7<A1_t, A2_t, A3_t, A4_t, A5_t, A6_t, A7_t> Type_t;
};
template<class A1, class Dom>
struct View1<MultiArg1<A1>, Dom>
{
  typedef typename MultiArgView1<A1, Dom>::Type_t Type_t;
};
template<class A1, class A2, class Dom>
struct View1<MultiArg2<A1, A2>, Dom>
{
  typedef typename MultiArgView2<A1, A2, Dom>::Type_t Type_t;
};
template<class A1, class A2, class A3, class Dom>
struct View1<MultiArg3<A1, A2, A3>, Dom>
{
  typedef typename MultiArgView3<A1, A2, A3, Dom>::Type_t Type_t;
};
template<class A1, class A2, class A3, class A4, class Dom>
struct View1<MultiArg4<A1, A2, A3, A4>, Dom>
{
  typedef typename MultiArgView4<A1, A2, A3, A4, Dom>::Type_t Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class Dom>
struct View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>
{
  typedef typename MultiArgView5<A1, A2, A3, A4, A5, Dom>::Type_t Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class Dom>
struct View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>
{
  typedef typename MultiArgView6<A1, A2, A3, A4, A5, A6, Dom>::Type_t Type_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Dom>
struct View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>
{
  typedef typename MultiArgView7<A1, A2, A3, A4, A5, A6, A7, Dom>::Type_t Type_t;
};
template<class A1>
struct MultiArg1
{
  enum { size = 1 };
  MultiArg1(const A1 &a1)
    : a1_m(a1)
  {
  }
  template<class Dom>
  typename View1<MultiArg1<A1>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg1<A1>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom));
  }
  A1 a1_m;
};
template<class A1, class A2>
struct MultiArg2
{
  enum { size = 2 };
  MultiArg2(const A1 &a1, const A2 &a2)
    : a1_m(a1), a2_m(a2)
  {
  }
  template<class Dom>
  typename View1<MultiArg2<A1, A2>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg2<A1, A2>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
};
template<class A1, class A2, class A3>
struct MultiArg3
{
  enum { size = 3 };
  MultiArg3(const A1 &a1, const A2 &a2, const A3 &a3)
    : a1_m(a1), a2_m(a2), a3_m(a3)
  {
  }
  template<class Dom>
  typename View1<MultiArg3<A1, A2, A3>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg3<A1, A2, A3>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
  A3 a3_m;
};
template<class A1, class A2, class A3, class A4>
struct MultiArg4
{
  enum { size = 4 };
  MultiArg4(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
    : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4)
  {
  }
  template<class Dom>
  typename View1<MultiArg4<A1, A2, A3, A4>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg4<A1, A2, A3, A4>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
  A3 a3_m;
  A4 a4_m;
};
template<class A1, class A2, class A3, class A4, class A5>
struct MultiArg5
{
  enum { size = 5 };
  MultiArg5(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
    : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5)
  {
  }
  template<class Dom>
  typename View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
  A3 a3_m;
  A4 a4_m;
  A5 a5_m;
};
template<class A1, class A2, class A3, class A4, class A5, class A6>
struct MultiArg6
{
  enum { size = 6 };
  MultiArg6(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
    : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5), a6_m(a6)
  {
  }
  template<class Dom>
  typename View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom), a6_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
  A3 a3_m;
  A4 a4_m;
  A5 a5_m;
  A6 a6_m;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct MultiArg7
{
  enum { size = 7 };
  MultiArg7(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7)
    : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5), a6_m(a6), a7_m(a7)
  {
  }
  template<class Dom>
  typename View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>::Type_t
  operator()(const Dom &dom) const
  {
    typedef typename View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>::Type_t Ret_t;
    return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom), a6_m(dom), a7_m(dom));
  }
  A1 a1_m;
  A2 a2_m;
  A3 a3_m;
  A4 a4_m;
  A5 a5_m;
  A6 a6_m;
  A7 a7_m;
};
template<class A1, class Function>
void applyMultiArg(const MultiArg1<A1> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
}
template<class A1, class A2, class Function>
void applyMultiArg(const MultiArg2<A1, A2> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
}
template<class A1, class A2, class A3, class Function>
void applyMultiArg(const MultiArg3<A1, A2, A3> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
  f(node.a3_m, condition[2]);
}
template<class A1, class A2, class A3, class A4, class Function>
void applyMultiArg(const MultiArg4<A1, A2, A3, A4> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
  f(node.a3_m, condition[2]);
  f(node.a4_m, condition[3]);
}
template<class A1, class A2, class A3, class A4, class A5, class Function>
void applyMultiArg(const MultiArg5<A1, A2, A3, A4, A5> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
  f(node.a3_m, condition[2]);
  f(node.a4_m, condition[3]);
  f(node.a5_m, condition[4]);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
void applyMultiArg(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
  f(node.a3_m, condition[2]);
  f(node.a4_m, condition[3]);
  f(node.a5_m, condition[4]);
  f(node.a6_m, condition[5]);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
void applyMultiArg(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
     const Function &f,
     const std::vector<bool> &condition)
{
  f(node.a1_m, condition[0]);
  f(node.a2_m, condition[1]);
  f(node.a3_m, condition[2]);
  f(node.a4_m, condition[3]);
  f(node.a5_m, condition[4]);
  f(node.a6_m, condition[5]);
  f(node.a7_m, condition[6]);
}
template<class A1, class Function>
void applyMultiArg(const MultiArg1<A1> &node,
     const Function &f)
{
  f(node.a1_m);
}
template<class A1, class A2, class Function>
void applyMultiArg(const MultiArg2<A1, A2> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
}
template<class A1, class A2, class A3, class Function>
void applyMultiArg(const MultiArg3<A1, A2, A3> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
  f(node.a3_m);
}
template<class A1, class A2, class A3, class A4, class Function>
void applyMultiArg(const MultiArg4<A1, A2, A3, A4> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
  f(node.a3_m);
  f(node.a4_m);
}
template<class A1, class A2, class A3, class A4, class A5, class Function>
void applyMultiArg(const MultiArg5<A1, A2, A3, A4, A5> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
  f(node.a3_m);
  f(node.a4_m);
  f(node.a5_m);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
void applyMultiArg(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
  f(node.a3_m);
  f(node.a4_m);
  f(node.a5_m);
  f(node.a6_m);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
void applyMultiArg(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
     const Function &f)
{
  f(node.a1_m);
  f(node.a2_m);
  f(node.a3_m);
  f(node.a4_m);
  f(node.a5_m);
  f(node.a6_m);
  f(node.a7_m);
}
template<class A1, class Function>
void applyMultiArgIf(const MultiArg1<A1> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
}
template<class A1, class A2, class Function>
void applyMultiArgIf(const MultiArg2<A1, A2> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
}
template<class A1, class A2, class A3, class Function>
void applyMultiArgIf(const MultiArg3<A1, A2, A3> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
  if (condition[2])
    f(node.a3_m);
}
template<class A1, class A2, class A3, class A4, class Function>
void applyMultiArgIf(const MultiArg4<A1, A2, A3, A4> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
  if (condition[2])
    f(node.a3_m);
  if (condition[3])
    f(node.a4_m);
}
template<class A1, class A2, class A3, class A4, class A5, class Function>
void applyMultiArgIf(const MultiArg5<A1, A2, A3, A4, A5> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
  if (condition[2])
    f(node.a3_m);
  if (condition[3])
    f(node.a4_m);
  if (condition[4])
    f(node.a5_m);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
void applyMultiArgIf(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
  if (condition[2])
    f(node.a3_m);
  if (condition[3])
    f(node.a4_m);
  if (condition[4])
    f(node.a5_m);
  if (condition[5])
    f(node.a6_m);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
void applyMultiArgIf(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
   const Function &f,
   const std::vector<bool> &condition)
{
  if (condition[0])
    f(node.a1_m);
  if (condition[1])
    f(node.a2_m);
  if (condition[2])
    f(node.a3_m);
  if (condition[3])
    f(node.a4_m);
  if (condition[4])
    f(node.a5_m);
  if (condition[5])
    f(node.a6_m);
  if (condition[6])
    f(node.a7_m);
}
struct LoopApplyEvaluator
{
  template<class Op, class Dom>
  static /*__attribute__((leafify))*/
  void evaluate(const Op &op, const Dom &domain)
  {
    PoomaCTAssert<(Dom::unitStride)>::test();
    evaluate(op, domain, WrappedInt<Dom::dimensions>());
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<1>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int e0 = domain[0].last();
;
#pragma omp parallel for if (e0-f0 > 512)
    for (int i0 = f0; i0 <= e0; ++i0)
      localOp(i0);
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<2>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
#pragma omp parallel for
    for (int i1 = f1; i1 <= e1; ++i1) {
;
      for (int i0 = f0; i0 <= e0; ++i0)
 localOp(i0, i1);
    }
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<3>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int f2 = domain[2].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
    int e2 = domain[2].last();
#pragma omp parallel for
    for (int i2 = f2; i2 <= e2; ++i2)
      for (int i1 = f1; i1 <= e1; ++i1) {
;
 for (int i0 = f0; i0 <= e0; ++i0)
   localOp(i0,i1,i2);
      }
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<4>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int f2 = domain[2].first();
    int f3 = domain[3].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
    int e2 = domain[2].last();
    int e3 = domain[3].last();
#pragma omp parallel for
    for (int i3 = f3; i3 <= e3; ++i3)
      for (int i2 = f2; i2 <= e2; ++i2)
 for (int i1 = f1; i1 <= e1; ++i1) {
;
   for (int i0 = f0; i0 <= e0; ++i0)
     localOp(i0,i1,i2,i3);
 }
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<5>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int f2 = domain[2].first();
    int f3 = domain[3].first();
    int f4 = domain[4].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
    int e2 = domain[2].last();
    int e3 = domain[3].last();
    int e4 = domain[4].last();
#pragma omp parallel for
    for (int i4 = f4; i4 <= e4; ++i4)
      for (int i3 = f3; i3 <= e3; ++i3)
 for (int i2 = f2; i2 <= e2; ++i2)
   for (int i1 = f1; i1 <= e1; ++i1) {
;
     for (int i0 = f0; i0 <= e0; ++i0)
       localOp(i0,i1,i2,i3,i4);
   }
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<6>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int f2 = domain[2].first();
    int f3 = domain[3].first();
    int f4 = domain[4].first();
    int f5 = domain[5].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
    int e2 = domain[2].last();
    int e3 = domain[3].last();
    int e4 = domain[4].last();
    int e5 = domain[5].last();
#pragma omp parallel for
    for (int i5 = f5; i5 <= e5; ++i5)
      for (int i4 = f4; i4 <= e4; ++i4)
 for (int i3 = f3; i3 <= e3; ++i3)
   for (int i2 = f2; i2 <= e2; ++i2)
     for (int i1 = f1; i1 <= e1; ++i1) {
;
       for (int i0 = f0; i0 <= e0; ++i0)
  localOp(i0,i1,i2,i3,i4,i5);
     }
  }
  template<class Op, class Domain>
  inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<7>)
  {
    Op localOp(op);
    int f0 = domain[0].first();
    int f1 = domain[1].first();
    int f2 = domain[2].first();
    int f3 = domain[3].first();
    int f4 = domain[4].first();
    int f5 = domain[5].first();
    int f6 = domain[6].first();
    int e0 = domain[0].last();
    int e1 = domain[1].last();
    int e2 = domain[2].last();
    int e3 = domain[3].last();
    int e4 = domain[4].last();
    int e5 = domain[5].last();
    int e6 = domain[6].last();
#pragma omp parallel for
    for (int i6 = f6; i6 <= e6; ++i6)
      for (int i5 = f5; i5 <= e5; ++i5)
 for (int i4 = f4; i4 <= e4; ++i4)
   for (int i3 = f3; i3 <= e3; ++i3)
     for (int i2 = f2; i2 <= e2; ++i2)
       for (int i1 = f1; i1 <= e1; ++i1) {
;
  for (int i0 = f0; i0 <= e0; ++i0)
    localOp(i0,i1,i2,i3,i4,i5,i6);
       }
  }
};
template<class MultiArg, class Function>
class MultiArgKernel
  : public Pooma::Iterate_t
{
public:
  MultiArgKernel(const MultiArg &multiArg,
    const Function &function,
    std::vector<bool> &write,
    std::vector<bool> &read)
    : Pooma::Iterate_t(Pooma::scheduler()),
      multiArg_m(multiArg), function_m(function),
      write_m(write), read_m(read)
  {
    DataObjectRequest<BlockAffinity> getAffinity;
    hintAffinity(engineFunctor(multiArg.a1_m.engine(), getAffinity));
    typedef DataObjectRequest<WriteRequest> WriteRequest_t;
    typedef DataObjectRequest<ReadRequest> ReadRequest_t;
    WriteRequest_t writeReq(*this);
    applyMultiArgIf(multiArg, ExpressionApply<WriteRequest_t>(writeReq),
      write_m);
    ReadRequest_t readReq(writeReq);
    applyMultiArgIf(multiArg, ExpressionApply<ReadRequest_t>(readReq),
      read_m);
  }
  virtual ~MultiArgKernel()
  {
    typedef DataObjectRequest<WriteRelease> WriteRequest_t;
    typedef DataObjectRequest<ReadRelease> ReadRequest_t;
    WriteRequest_t writeReq;
    applyMultiArgIf(multiArg_m, ExpressionApply<WriteRequest_t>(writeReq),
      write_m);
    ReadRequest_t readReq(writeReq);
    applyMultiArgIf(multiArg_m, ExpressionApply<ReadRequest_t>(readReq),
      read_m);
  }
  virtual void /*__attribute__((leafify))*/ run()
  {
    function_m(multiArg_m);
  }
private:
  MultiArg multiArg_m;
  Function function_m;
  std::vector<bool> write_m;
  std::vector<bool> read_m;
};
template<int Dim>
class SimpleIntersectorData
  : public RefCounted
{
public:
  typedef SimpleIntersectorData<Dim> This_t;
  typedef INode<Dim> INode_t;
  typedef std::vector<INode_t> INodeContainer_t;
  typedef typename INodeContainer_t::const_iterator const_iterator;
  typedef Unique::Value_t LayoutID_t;
  enum { dimensions = Dim };
  inline SimpleIntersectorData(const Interval<Dim> &domain, const GuardLayers<Dim> &extent)
    : seenFirst_m(false), domain_m(domain), extent_m(extent)
  {
  }
  inline ~SimpleIntersectorData() { }
  template<class Engine>
  void intersect(const Engine &engine, bool useGuards)
  {
    typedef typename Engine::Layout_t Layout_t;
    typedef typename NewEngine<Engine, Interval<Dim> >::Type_t NewEngine_t;
    const Layout_t &layout(engine.layout());
    if (!seenFirst_m)
    {
      firstID_m = layout.ID();
      seenFirst_m = true;
      int key = GlobalIDDataBase::nullNodeKey();
      layout.touches(domain_m, std::back_inserter(inodes_m),
       TouchesConstructINode<Dim>(firstID_m, key, &gidStore_m));
    }
    else
    {
      shared(layout.ID(), firstID_m);
    }
    if (useGuards) {
      expressionApply(NewEngine_t(engine, grow(domain_m, extent_m)),
        IntersectorTag<Intersector<Dim> >(lhsi_m));
    } else {
      expressionApply(NewEngine_t(engine, domain_m),
        IntersectorTag<Intersector<Dim> >(lhsi_m));
    }
  }
  inline
  void shared(LayoutID_t id1, LayoutID_t id2)
  {
    gidStore_m.shared(id1,id2);
  }
  SimpleIntersectorData(const This_t &);
  This_t &operator=(const This_t &);
  LayoutID_t firstID_m;
  bool seenFirst_m;
  INodeContainer_t inodes_m;
  GlobalIDDataBase gidStore_m;
  Interval<Dim> domain_m;
  GuardLayers<Dim> extent_m;
  Intersector<Dim> lhsi_m;
};
template<int Dim>
class SimpleIntersector
{
public:
  typedef SimpleIntersectorData<Dim> SimpleIntersectorData_t;
  typedef SimpleIntersector<Dim> This_t;
  typedef typename SimpleIntersectorData_t::INode_t INode_t;
  typedef typename SimpleIntersectorData_t::INodeContainer_t INodeContainer_t;
  typedef typename SimpleIntersectorData_t::const_iterator const_iterator;
  typedef RefCountedPtr<SimpleIntersectorData_t> DataPtr_t;
  typedef NullCombine Combine_t;
  enum { dimensions = Dim };
  SimpleIntersector(const Interval<Dim> &domain, const GuardLayers<Dim> &extent)
    : pdata_m(new SimpleIntersectorData_t(domain, extent)), useGuards_m(true)
  { }
  SimpleIntersector(const This_t &model)
    : pdata_m(model.pdata_m), useGuards_m(model.useGuards())
  { }
  This_t &operator=(const This_t &model)
  {
    if (this != &model) {
      pdata_m = model.pdata_m;
      useGuards_m = model.useGuards_m;
    }
    return *this;
  }
  ~SimpleIntersector() { }
  inline DataPtr_t &data() { return pdata_m; }
  inline const DataPtr_t &data() const { return pdata_m; }
  inline const_iterator begin() const { return data()->inodes_m.begin(); }
  inline const_iterator end() const { return data()->inodes_m.end(); }
  inline int size() const { return data()->inodes_m.size(); }
  template<class Engine>
  inline
  void intersect(const Engine &l) const
  {
    data()->intersect(l, useGuards());
  }
  inline
  bool useGuards() const
  {
    return useGuards_m;
  }
  inline
  void useGuards(bool f) const
  {
    useGuards_m = f;
  }
  template<class A>
  void operator()(const A &a, bool f) const
  {
    useGuards(f);
    expressionApply(a, *this);
  }
private:
  DataPtr_t pdata_m;
  mutable bool useGuards_m;
};
template<class Eng, int Dim>
struct DefaultExpressionApply<Eng, SimpleIntersector<Dim> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const Eng &,
        const ExpressionApply<SimpleIntersector<Dim> > &)
  {
    PoomaCTAssert<(!(Eng::multiPatch))>::test();
    return true;
  }
};
template<class LT, class PT>
struct MultiPatch;
template <int Dim, class T, class LayoutTag, class PatchTag>
struct LeafFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
  ExpressionApply<SimpleIntersector<Dim> > >
{
  typedef int Type_t;
  static Type_t
  apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
 const ExpressionApply<SimpleIntersector<Dim> > &apply)
  {
    apply.tag().intersect(engine);
    if (apply.tag().useGuards())
      engine.fillGuards(apply.tag().data()->extent_m);
    return 0;
  }
};
template <int Dim, class T, class LT, class PatchTag, int BD>
struct LeafFunctor<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> >,
  ExpressionApply<SimpleIntersector<Dim> > >
{
  typedef int Type_t;
  static Type_t
  apply(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
 const ExpressionApply<SimpleIntersector<Dim> > &apply)
  {
    apply.tag().intersect(engine);
    if (apply.tag().useGuards())
      engine.fillGuards(apply.tag().data()->extent_m);
    return 0;
  }
};
template <int Dim, int size>
class ScalarCodeInfo
{
public:
  enum { dimensions = Dim };
  enum { arguments = size };
  typedef std::vector<bool> BoolVector_t;
  ScalarCodeInfo()
    : extent_m(GuardLayers<Dim>(0)),
      useGuards_m(arguments, true),
      writers_m(arguments, false),
      readers_m(arguments, true)
  {
    useGuards_m[0] = false;
    writers_m[0] = true;
    readers_m[0] = true;
  }
  void extent(const GuardLayers<Dim> &g)
  {
    extent_m = g;
  }
  GuardLayers<Dim>& extent()
  {
    return extent_m;
  }
  const GuardLayers<Dim>& extent() const
  {
    return extent_m;
  }
  void write(int i, bool f, bool r = true)
  {
    writers_m[i] = f;
    readers_m[i] = r;
  }
  BoolVector_t &writers()
  {
    return writers_m;
  }
  BoolVector_t &readers()
  {
    return readers_m;
  }
  void useGuards(int i, bool f)
  {
    useGuards_m[i] = f;
  }
  BoolVector_t &useGuards()
  {
    return useGuards_m;
  }
  inline Interval<Dim> extendDomain(const Interval<Dim> &domain) const
  {
    return grow(domain, extent_m);
  }
  inline Interval<Dim> evaluationDomain(const Interval<Dim> &domain) const
  {
    Interval<Dim> ret;
    for (int d = 0; d < Dim; ++d)
    {
      ret[d] = Interval<1>(extent_m.lower(d),
      domain[d].last() - domain[d].first()
      + extent_m.lower(d));
    }
    return ret;
  }
  inline INode<Dim> extendDomain(const INode<Dim> &inode) const
  {
    return INode<Dim>(inode, extendDomain(inode.domain()));
  }
private:
  GuardLayers<Dim> extent_m;
  BoolVector_t useGuards_m;
  BoolVector_t writers_m;
  BoolVector_t readers_m;
};
template<class MultiArg> struct MultiArgEvaluatorTag;
template<class MeshTag, class T, class EngineTag> class Field;
template<int Dim, class T, class EngineTag> class Array;
template<class EvalTag>
struct MultiArgEvaluator
{
};
struct EngineWriteNotifier
{
  EngineWriteNotifier()
  {
  }
  template<class A>
  inline void dirtyRelations(const A &a, const WrappedInt<true>&) const
  {
    a.notifyPostWrite();
  }
  template<class A>
  inline void dirtyRelations(const A &, const WrappedInt<false>&) const
  {
  }
  template<class A>
  void operator()(const A &a) const
  {
    notifyEngineWrite(a.engine());
    dirtyRelations(a, WrappedInt<A::hasRelations>());
  }
  template<class MeshTag, class T, class Expr>
  void operator()(const Field<MeshTag, T, ExpressionTag<Expr> >&) const
  {
    if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("writing to expression engine?", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Evaluator/MultiArgEvaluator.h", 124);
  }
  template<int Dim, class T, class Expr>
  void operator()(const Array<Dim, T, ExpressionTag<Expr> >&) const
  {
    if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("writing to expression engine?", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Evaluator/MultiArgEvaluator.h", 130);
  }
};
struct UpdateNotifier
{
  UpdateNotifier()
  {
  }
  template<class A>
  void operator()(const A &a) const
  {
    forEach(a, PerformUpdateTag(), NullCombine());
  }
};
template <int Dim>
struct CheckDomain
{
  CheckDomain(const Interval<Dim>&d) : d_m(d) {}
  template <class A>
  void operator()(const A &a) const
  {
    a(d_m);
  }
  Interval<Dim> d_m;
};
template<>
struct MultiArgEvaluator<MainEvaluatorTag>
{
public:
  MultiArgEvaluator() {}
  ~MultiArgEvaluator() {}
  template<class MultiArg, class Function, int Dim, class Kernel>
  static void
  evaluate(const MultiArg &multiArg,
    const Function &function,
    const Interval<Dim> &domain,
    const Kernel &kernel)
  {
    typedef typename MultiArgEvaluatorTag<MultiArg>::Evaluator_t Evaluator_t;
    ScalarCodeInfo<Dim, MultiArg::size> info;
    function.scalarCodeInfo(info);
    Pooma::beginExpression();
    applyMultiArgIf(multiArg, UpdateNotifier(), info.readers());
    MultiArgEvaluator<Evaluator_t>::evaluate(multiArg, function,
          domain, info, kernel);
    applyMultiArgIf(multiArg, EngineWriteNotifier(), info.writers());
    Pooma::endExpression();
  }
  template<class A1, class Function, int Dim, class Kernel>
  static void
  createIterate(const A1& a1,
  const Function& function,
  const Interval<Dim> &domain,
  ScalarCodeInfo<Dim, A1::size> &info,
  const Kernel &)
  {
    Kernel kernelf(function, domain);
    Pooma::Iterate_t *iterate =
      new MultiArgKernel<A1, Kernel>(a1, kernelf,
         info.writers(), info.readers());
    Pooma::scheduler().handOff(iterate);
  }
};
template<>
struct MultiArgEvaluator<SinglePatchEvaluatorTag>
{
public:
  MultiArgEvaluator() {}
  ~MultiArgEvaluator() {}
  template<class MultiArg, class Function, int Dim, class Kernel>
  static void
  evaluate(const MultiArg& multiArg,
    const Function& function,
    Interval<Dim> domain,
    ScalarCodeInfo<Dim, MultiArg::size> &info,
    const Kernel &kernel)
  {
    Interval<Dim> newDom = info.extendDomain(domain);
    Interval<Dim> evalDom = info.evaluationDomain(domain);
    MultiArgEvaluator<MainEvaluatorTag>::createIterate(multiArg(newDom),
             function,
             evalDom, info,
             kernel);
  }
};
template<>
struct MultiArgEvaluator<MultiPatchEvaluatorTag>
{
public:
  MultiArgEvaluator() {}
  ~MultiArgEvaluator() {}
  template<class MultiArg, class Function, int Dim, class Kernel>
  static void
  evaluate(const MultiArg &multiArg,
    const Function &function,
    const Interval<Dim> &domain,
    ScalarCodeInfo<Dim, MultiArg::size> &info,
    const Kernel &kernel)
  {
    typedef SimpleIntersector<Dim> Inter_t;
    Inter_t inter(domain, info.extent());
    applyMultiArg(multiArg, inter, info.useGuards());
    typename Inter_t::const_iterator i = inter.begin();
    while (i != inter.end())
    {
      INode<Dim> inode = info.extendDomain(*i);
      Interval<Dim> evalDom = info.evaluationDomain((*i).domain());
      MultiArgEvaluator<MainEvaluatorTag>::createIterate(multiArg(inode),
        function,
        evalDom, info,
        kernel);
      ++i;
    }
  }
};
template <>
struct MultiArgEvaluator<RemoteSinglePatchEvaluatorTag>
{
  MultiArgEvaluator() { }
  ~MultiArgEvaluator() { }
  template<class MultiArg, class Function, int Dim, class Kernel>
  static void
  evaluate(const MultiArg &multiArg,
    const Function &function,
    const Interval<Dim> &domain,
    ScalarCodeInfo<Dim, MultiArg::size> &info,
    const Kernel &kernel)
  {
    GatherContexts gtag;
    engineFunctor(multiArg.a1_m.engine(), gtag);
    int lhsContext = gtag.mostCommonContext();
    expressionApply(multiArg, RemoteSend(lhsContext));
    EngineView<RemoteView> view;
    if (lhsContext == -1 || Pooma::context() == lhsContext)
    {
      MultiArgEvaluator<SinglePatchEvaluatorTag> speval;
      speval.evaluate(
        forEach(multiArg, view, TreeCombine()),
        function, domain, info, kernel
        );
    }
  }
};
template <>
struct MultiArgEvaluator<RemoteMultiPatchEvaluatorTag>
{
  MultiArgEvaluator() { }
  ~MultiArgEvaluator() { }
  template<class MultiArg, class Function, int Dim, class Kernel>
  static void
  evaluate(const MultiArg &multiArg,
    const Function &function,
    const Interval<Dim> &domain,
    ScalarCodeInfo<Dim, MultiArg::size> &info,
    const Kernel &kernel)
  {
    typedef SimpleIntersector<Dim> Inter_t;
    Inter_t inter(domain, info.extent());
    applyMultiArg(multiArg, inter, info.useGuards());
    typename Inter_t::const_iterator i = inter.begin();
    while (i != inter.end())
    {
      INode<Dim> inode = info.extendDomain(*i);
      Interval<Dim> evalDom = info.evaluationDomain((*i).domain());
      MultiArgEvaluator<RemoteSinglePatchEvaluatorTag>().
 evaluate(multiArg(inode),
   function, evalDom, info, kernel);
      ++i;
    }
  }
};
template<class A1>
struct MultiArgEvaluatorTag<MultiArg1<A1> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Evaluator_t;
};
template<class A1, class A2>
struct MultiArgEvaluatorTag<MultiArg2<A1, A2> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Evaluator_t;
};
template<class A1, class A2, class A3>
struct MultiArgEvaluatorTag<MultiArg3<A1, A2, A3> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
  typedef typename EvaluatorCombine<Eval3_t, Eval12_t>::Evaluator_t
  Evaluator_t;
};
template<class A1, class A2, class A3, class A4>
struct MultiArgEvaluatorTag<MultiArg4<A1, A2, A3, A4> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
  typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
  typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
  typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Evaluator_t;
};
template<class A1, class A2, class A3, class A4, class A5>
struct MultiArgEvaluatorTag<MultiArg5<A1, A2, A3, A4, A5> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
  typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
  typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
  typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
  typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Eval1234_t;
  typedef typename EvaluatorCombine<Eval1234_t, Eval5_t>::Evaluator_t Evaluator_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6>
struct MultiArgEvaluatorTag<MultiArg6<A1, A2, A3, A4, A5, A6> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
  typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
  typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
  typedef typename EvaluatorTag1<A6>::Evaluator_t Eval6_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
  typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
  typedef typename EvaluatorCombine<Eval5_t, Eval6_t>::Evaluator_t Eval56_t;
  typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Eval1234_t;
  typedef typename EvaluatorCombine<Eval1234_t, Eval56_t>::Evaluator_t Evaluator_t;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct MultiArgEvaluatorTag<MultiArg7<A1, A2, A3, A4, A5, A6, A7> >
{
  typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
  typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
  typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
  typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
  typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
  typedef typename EvaluatorTag1<A6>::Evaluator_t Eval6_t;
  typedef typename EvaluatorTag1<A7>::Evaluator_t Eval7_t;
  typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
  typedef typename EvaluatorCombine<Eval3_t, Eval12_t>::Evaluator_t Eval123_t;
  typedef typename EvaluatorCombine<Eval4_t, Eval123_t>::Evaluator_t Eval1234_t;
  typedef typename EvaluatorCombine<Eval5_t, Eval1234_t>::Evaluator_t Eval12345_t;
  typedef typename EvaluatorCombine<Eval6_t, Eval12345_t>::Evaluator_t Eval123456_t;
  typedef typename EvaluatorCombine<Eval7_t, Eval123456_t>::Evaluator_t
  Evaluator_t;
};
template<class A1, class Tag>
struct LeafFunctor<MultiArg1<A1>, ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg1<A1> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    return 0;
  }
};
template<class A1, class Tag>
struct LeafFunctor<MultiArg1<A1>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef MultiArg1<Type1_t> Type_t;
  inline static
  Type_t apply(const MultiArg1<A1> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag)
    );
  }
};
template<class A1, class A2, class Tag>
struct LeafFunctor<MultiArg2<A1, A2>, ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg2<A1, A2> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    return 0;
  }
};
template<class A1, class A2, class Tag>
struct LeafFunctor<MultiArg2<A1, A2>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef MultiArg2<Type1_t, Type2_t> Type_t;
  inline static
  Type_t apply(const MultiArg2<A1, A2> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag)
    );
  }
};
template<class A1, class A2, class A3, class Tag>
struct LeafFunctor<MultiArg3<A1, A2, A3>,
  ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg3<A1, A2, A3> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    leafFunctor(multiarg.a3_m, tag);
    return 0;
  }
};
template<class A1, class A2, class A3, class Tag>
struct LeafFunctor<MultiArg3<A1, A2, A3>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
  typedef MultiArg3<Type1_t, Type2_t, Type3_t> Type_t;
  inline static
  Type_t apply(const MultiArg3<A1, A2, A3> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag),
    leafFunctor(multiarg.a3_m, tag)
    );
  }
};
template<class A1, class A2, class A3, class A4, class Tag>
struct LeafFunctor<MultiArg4<A1, A2, A3, A4>,
  ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg4<A1, A2, A3, A4> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    leafFunctor(multiarg.a3_m, tag);
    leafFunctor(multiarg.a4_m, tag);
    return 0;
  }
};
template<class A1, class A2, class A3, class A4, class Tag>
struct LeafFunctor<MultiArg4<A1, A2, A3, A4>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
  typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
  typedef MultiArg4<Type1_t, Type2_t, Type3_t, Type4_t> Type_t;
  inline static
  Type_t apply(const MultiArg4<A1, A2, A3, A4> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag),
    leafFunctor(multiarg.a3_m, tag),
    leafFunctor(multiarg.a4_m, tag)
    );
  }
};
template<class A1, class A2, class A3, class A4, class A5, class Tag>
struct LeafFunctor<MultiArg5<A1, A2, A3, A4, A5>,
  ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg5<A1, A2, A3, A4, A5> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    leafFunctor(multiarg.a3_m, tag);
    leafFunctor(multiarg.a4_m, tag);
    leafFunctor(multiarg.a5_m, tag);
    return 0;
  }
};
template<class A1, class A2, class A3, class A4, class A5, class Tag>
struct LeafFunctor<MultiArg5<A1, A2, A3, A4, A5>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
  typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
  typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
  typedef MultiArg5<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t> Type_t;
  inline static
  Type_t apply(const MultiArg5<A1, A2, A3, A4, A5> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag),
    leafFunctor(multiarg.a3_m, tag),
    leafFunctor(multiarg.a4_m, tag),
    leafFunctor(multiarg.a5_m, tag)
    );
  }
};
template<class A1, class A2, class A3, class A4, class A5,
  class A6, class Tag>
struct LeafFunctor<MultiArg6<A1, A2, A3, A4, A5, A6>,
  ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    leafFunctor(multiarg.a3_m, tag);
    leafFunctor(multiarg.a4_m, tag);
    leafFunctor(multiarg.a5_m, tag);
    leafFunctor(multiarg.a6_m, tag);
    return 0;
  }
};
template<class A1, class A2, class A3, class A4, class A5,
  class A6, class Tag>
struct LeafFunctor<MultiArg6<A1, A2, A3, A4, A5, A6>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
  typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
  typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
  typedef typename LeafFunctor<A6, EngineView<Tag> >::Type_t Type6_t;
  typedef MultiArg6<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t,
    Type6_t> Type_t;
  inline static
  Type_t apply(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag),
    leafFunctor(multiarg.a3_m, tag),
    leafFunctor(multiarg.a4_m, tag),
    leafFunctor(multiarg.a5_m, tag),
    leafFunctor(multiarg.a6_m, tag)
    );
  }
};
template<class A1, class A2, class A3, class A4, class A5,
  class A6, class A7, class Tag>
struct LeafFunctor<MultiArg7<A1, A2, A3, A4, A5, A6, A7>,
  ExpressionApply<Tag> >
{
  typedef int Type_t;
  inline static
  Type_t apply(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiarg,
        const ExpressionApply<Tag> &tag)
  {
    leafFunctor(multiarg.a1_m, tag);
    leafFunctor(multiarg.a2_m, tag);
    leafFunctor(multiarg.a3_m, tag);
    leafFunctor(multiarg.a4_m, tag);
    leafFunctor(multiarg.a5_m, tag);
    leafFunctor(multiarg.a6_m, tag);
    leafFunctor(multiarg.a7_m, tag);
    return 0;
  }
};
template<class A1, class A2, class A3, class A4, class A5,
  class A6, class A7, class Tag>
struct LeafFunctor<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, EngineView<Tag> >
{
  typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
  typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
  typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
  typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
  typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
  typedef typename LeafFunctor<A6, EngineView<Tag> >::Type_t Type6_t;
  typedef typename LeafFunctor<A7, EngineView<Tag> >::Type_t Type7_t;
  typedef MultiArg7<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t,
    Type6_t, Type7_t> Type_t;
  inline static
  Type_t apply(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiarg,
        const EngineView<Tag> &tag)
  {
    return Type_t(
    leafFunctor(multiarg.a1_m, tag),
    leafFunctor(multiarg.a2_m, tag),
    leafFunctor(multiarg.a3_m, tag),
    leafFunctor(multiarg.a4_m, tag),
    leafFunctor(multiarg.a5_m, tag),
    leafFunctor(multiarg.a6_m, tag),
    leafFunctor(multiarg.a7_m, tag)
    );
  }
};
template<class MA, class Function>
struct ApplyMultiArgLoc;
template<class A1, class Function>
struct ApplyMultiArgLoc<MultiArg1<A1>, Function>
{
  ApplyMultiArgLoc(const MultiArg1<A1> &multiArg, const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg1<A1> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class Function>
struct ApplyMultiArgLoc<MultiArg2<A1, A2>, Function>
{
  ApplyMultiArgLoc(const MultiArg2<A1, A2> &multiArg,const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg2<A1, A2> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class A3, class Function>
struct ApplyMultiArgLoc<MultiArg3<A1, A2, A3>, Function>
{
  ApplyMultiArgLoc(const MultiArg3<A1, A2, A3> &multiArg,
     const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
        Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
        Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
        Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
        Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg3<A1, A2, A3> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
struct ApplyMultiArgLoc<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Function>
{
  ApplyMultiArgLoc(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiArg,
     const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               multiArg_m.a7_m, Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               multiArg_m.a7_m, Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               multiArg_m.a7_m, Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               multiArg_m.a7_m, Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
struct ApplyMultiArgLoc<MultiArg6<A1, A2, A3, A4, A5, A6>, Function>
{
  ApplyMultiArgLoc(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiArg,
     const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
                Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
               Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg6<A1, A2, A3, A4, A5, A6> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class A3, class A4, class Function>
struct ApplyMultiArgLoc<MultiArg4<A1, A2, A3, A4>, Function>
{
  ApplyMultiArgLoc(const MultiArg4<A1, A2, A3, A4> &multiArg,
     const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m,
               Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m,
                Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m,
               Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m,
               Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg4<A1, A2, A3, A4> &multiArg_m;
  const Function &function_m;
};
template<class A1, class A2, class A3, class A4, class A5, class Function>
struct ApplyMultiArgLoc<MultiArg5<A1, A2, A3, A4, A5>, Function>
{
  ApplyMultiArgLoc(const MultiArg5<A1, A2, A3, A4, A5> &multiArg,
     const Function &function)
    : multiArg_m(multiArg), function_m(function)
  {
  }
  void operator()(int i0) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m,
               Loc<1>(i0));
  }
  void operator()(int i0, int i1) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m,
                Loc<2>(i0, i1));
  }
  void operator()(int i0, int i1, int i2) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m,
               Loc<3>(i0, i1, i2));
  }
  void operator()(int i0, int i1, int i2, int i3) const
  {
    function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
               multiArg_m.a4_m, multiArg_m.a5_m,
               Loc<4>(i0, i1, i2, i3));
  }
  const MultiArg5<A1, A2, A3, A4, A5> &multiArg_m;
  const Function &function_m;
};
template<class Function, int Dim>
struct EvaluateLocLoop
{
  EvaluateLocLoop()
  {
  }
  EvaluateLocLoop(const Function &function, const Interval<Dim> &domain)
    : function_m(function), domain_m(domain)
  {
  }
  template<class MultiArg>
  void operator()(MultiArg &multiArg) const
  {
    ApplyMultiArgLoc<MultiArg, Function> op(multiArg, function_m);
    LoopApplyEvaluator::evaluate(op, domain_m);
  }
  Function function_m;
  Interval<Dim> domain_m;
};
template<class Function>
struct ScalarCode
{
  ScalarCode()
  {
  }
  ScalarCode(const Function &function)
    : function_m(function)
  {
  }
  template <class LHS>
  ScalarCode(const ScalarCode<Function>& sc, const LHS&)
    : function_m(sc.function_m)
  {
  }
  template<class F>
  static inline bool checkValidity(const F& f, WrappedInt<false>)
  {
    return true;
  }
  template<class F>
  static inline bool checkValidity(const F& f, WrappedInt<true>)
  {
    return f.centeringSize() == 1 && f.numMaterials() == 1;
  }
  template<class F1>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom) const
  {
    ;
    MultiArg1<F1> multiArg(f1);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1>
  inline void operator()(const F1 &f1) const
  {
    (*this)(f1, f1.physicalDomain());
  }
  template<class F1, class F2>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
                  const F2 &f2) const
  {
    ;
    MultiArg2<F1, F2> multiArg(f1, f2);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2>
  inline void operator()(const F1 &f1, const F2 &f2) const
  {
    (*this)(f1, f1.physicalDomain(), f2);
  }
  template<class F1, class F2, class F3>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
                  const F2 &f2, const F3 &f3) const
  {
    ;
    MultiArg3<F1, F2, F3> multiArg(f1, f2, f3);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2, class F3>
  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3) const
  {
    (*this)(f1, f1.physicalDomain(), f2, f3);
  }
  template<class F1, class F2, class F3, class F4>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
    const F2 &f2, const F3 &f3, const F4 &f4) const
  {
    ;
    MultiArg4<F1, F2, F3, F4> multiArg(f1, f2, f3, f4);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2, class F3, class F4>
  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4) const
  {
    (*this)(f1, f1.physicalDomain(), f2, f3, f4);
  }
  template<class F1, class F2, class F3, class F4, class F5>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
    const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5) const
  {
    ;
    MultiArg5<F1, F2, F3, F4, F5> multiArg(f1, f2, f3, f4, f5);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2, class F3, class F4, class F5>
  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
    const F5 &f5) const
  {
    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5);
  }
  template<class F1, class F2, class F3, class F4, class F5, class F6>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
    const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5,
    const F6 &f6) const
  {
    ;
    MultiArg6<F1, F2, F3, F4, F5, F6> multiArg(f1, f2, f3, f4, f5, f6);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2, class F3, class F4, class F5, class F6>
  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
    const F5 &f5, const F6 &f6) const
  {
    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6);
  }
  template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
    const F2 &f2, const F3 &f3, const F4 &f4,
    const F5 &f5, const F6 &f6, const F7 &f7) const
  {
    ;
    MultiArg7<F1, F2, F3, F4, F5, F6, F7> multiArg(f1, f2, f3, f4, f5, f6, f7);
    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
    MultiArgEvaluator<MainEvaluatorTag>::
      evaluate(multiArg, function_m, evalDom, kernel);
  }
  template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
    const F5 &f5, const F6 &f6, const F7 &f7) const
  {
    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6, f7);
  }
  Function function_m;
};
template<class InputField>
struct PackLocalPatches
{
  typedef typename InputField::Element_t Element_t;
  PackLocalPatches(RefCountedBlockPtr<Element_t> block)
    : block_m(block)
  {
  }
  inline void operator()(const Element_t &t)
  {
    *block_m = t;
    ++block_m;
  }
  RefCountedBlockPtr<Element_t> block_m;
  int total_m;
};
template<class InputField>
RefCountedBlockPtr<typename InputField::Element_t>
pack(const InputField &field)
{
  Pooma::blockAndEvaluate();
  typedef typename InputField::Element_t Element_t;
  int size, i;
  size = 0;
  for (i = 0; i < field.numPatchesLocal(); ++i)
  {
    size += field.patchLocal(i).domain().size();
  }
  RefCountedBlockPtr<Element_t> ret(size);
  RefCountedBlockPtr<Element_t> current = ret;
  for (i = 0; i < field.numPatchesLocal(); ++i)
  {
    typedef typename Patch<InputField>::Type_t PatchField_t;
    PatchField_t patch = field.patchLocal(i);
    PackLocalPatches<PatchField_t> packFunctor(current);
    EngineBlockSerialize::apply(packFunctor, patch, patch.domain());
    current += patch.domain().size();
  }
  return ret;
}
template<class InputField>
struct UnPackLocalPatches
{
  typedef typename InputField::Element_t Element_t;
  UnPackLocalPatches(RefCountedBlockPtr<Element_t> block)
    : block_m(block)
  {
  }
  inline void operator()(Element_t &t)
  {
    t = *block_m;
    ++block_m;
  }
  RefCountedBlockPtr<Element_t> block_m;
  int total_m;
};
template<class InputField, class T>
void
unpack(const InputField &field, RefCountedBlockPtr<T> block)
{
  Pooma::blockAndEvaluate();
  int i;
  RefCountedBlockPtr<T> current = block;
  for (i = 0; i < field.numPatchesLocal(); ++i)
  {
    typedef typename Patch<InputField>::Type_t PatchField_t;
    PatchField_t patch = field.patchLocal(i);
    UnPackLocalPatches<PatchField_t> unpackFunctor(current);
    EngineBlockSerialize::apply(unpackFunctor, patch, patch.physicalDomain());
    current += patch.physicalDomain().size();
  }
}
struct FarLeftTag;
template<class G, class T, class E> class Field;
template<class Expr>
struct MakeFieldReturn;
template<class Op, class Leaf>
struct MakeFieldReturn<UnaryNode<Op, Leaf> >
{
  typedef UnaryNode<Op, Leaf> Tree_t;
  typedef typename
    ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
  typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
  typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
    Type_t::MeshTag_t MeshTag_t;
  typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> > Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class Op, class Left, class Right>
struct MakeFieldReturn<BinaryNode<Op, Left, Right> >
{
  typedef BinaryNode<Op, Left, Right> Tree_t;
  typedef typename
    ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
  typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
  typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
    Type_t::MeshTag_t MeshTag_t;
  typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> >
    Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class Op, class Left, class Middle, class Right>
struct MakeFieldReturn<TrinaryNode<Op, Left, Middle, Right> >
{
  typedef TrinaryNode<Op, Left, Middle, Right> Tree_t;
  typedef typename
    ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
  enum { dim = Domain_t::dimensions };
  typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
  typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
  typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
    Type_t::MeshTag_t MeshTag_t;
  typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> > Expression_t;
  inline static
  Expression_t make(const Tree_t &tree)
    {
      return Expression_t(Engine_t(tree));
    }
};
template<class G, class T, class E> class Field;
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnArcCos,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
acos(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnArcCos,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnArcSin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
asin(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnArcSin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnArcTan,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
atan(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnArcTan,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnCeil,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
ceil(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnCeil,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnCos,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
cos(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnCos,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnHypCos,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
cosh(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnHypCos,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnExp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
exp(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnExp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnFabs,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
fabs(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnFabs,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnFloor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
floor(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnFloor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnLog,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
log(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnLog,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnLog10,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
log10(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnLog10,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnSin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
sin(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnSin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnHypSin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
sinh(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnHypSin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnSqrt,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
sqrt(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnSqrt,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnTan,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
tan(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnTan,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnHypTan,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
tanh(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnHypTan,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<OpUnaryMinus,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<OpUnaryMinus,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<OpUnaryPlus,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<OpUnaryPlus,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<OpBitwiseNot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
operator~(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<OpBitwiseNot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<OpIdentity,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
PETE_identity(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<OpIdentity,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<OpNot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
operator!(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<OpNot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<UnaryNode<OpCast<T1>,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
peteCast(const T1&, const Field<G2,T2,E2> & l)
{
  typedef UnaryNode<OpCast<T1>,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G2,T2,E2> >::make(l)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<<(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLeftShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpRightShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>>(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpRightShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpLT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpLE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<=(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpGT,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpGE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>=(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator&&(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator||(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator<<(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLeftShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator<<(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLeftShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpRightShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
operator>>(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpRightShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpRightShift,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
operator>>(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpRightShift,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator<=(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator>=(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAnd,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAnd,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&&(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAnd,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpOr,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpOr,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator||(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpOr,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2,class T3>
inline typename MakeFieldReturn<TrinaryNode<FnWhere,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t,
  typename CreateLeaf<T3 >::Leaf_t> >::Expression_t
where(const Field<G1,T1,E1> & c,const T2 & t,const T3 & f)
{
  typedef TrinaryNode<FnWhere,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t,
    typename CreateLeaf<T3 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(c),
    CreateLeaf<T2 >::make(t),
    CreateLeaf<T3 >::make(f)));
}
template<int D, class T, class EngineTag> class Tensor;
template<class OutputEngineTag, int D, class T, class EngineTag>
Tensor<D, T, OutputEngineTag>
symmetrize(const Tensor<D, T, EngineTag> &x);
template<class G, class T, class E> class Field;
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnReal,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
real(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnReal,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnImag,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
imag(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnImag,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnAbs,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
abs(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnAbs,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnArg,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
arg(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnArg,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnNorm,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
norm(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnNorm,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnConj,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
conj(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnConj,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnPow2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
pow2(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnPow2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnPow3,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
pow3(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnPow3,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnPow4,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
pow4(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnPow4,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnMagnitude,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
magnitude(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnMagnitude,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnTrace,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
trace(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnTrace,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnDet,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
det(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnDet,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnTranspose,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
transpose(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnTranspose,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class OutputSymmetry,class G1,class T1,class E1>
inline typename MakeFieldReturn<UnaryNode<FnSymmetrize<OutputSymmetry>,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
symmetrize(const Field<G1,T1,E1> & l)
{
  typedef UnaryNode<FnSymmetrize<OutputSymmetry>,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
polar(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
min(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMax,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
max(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LT(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GT(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
NE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
polar(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
polar(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
outerProduct(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
dotdot(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
min(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnMin,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
min(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMax,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
max(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<FnMax,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
max(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LT(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
LT(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
LE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
LE(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GT(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
GT(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
GE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
GE(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
EQ(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
NE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Array<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,class T2>
inline typename MakeFieldReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
NE(const Field<G1,T1,E1> & l,const T2 & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<T2 >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<T2 >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPolar,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
polar(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPolar,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
polar(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPolar,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProduct(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProduct,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
outerProductAsTinyMatrix(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnOuterProductAsTinyMatrix,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDotDot,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dotdot(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDotDot,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMin,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
min(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMin,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
min(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMax,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
max(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnMax,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
max(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LT(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLT2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LT(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLT2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpLE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
LE(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpLE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GT(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGT2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GT(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGT2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpGE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
GE(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpGE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
EQ(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE2,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
NE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class T1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE2,
  typename CreateLeaf<T1 >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
NE(const T1 & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE2,
    typename CreateLeaf<T1 >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<T1 >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<class G, class T, class E> class Field;
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Vector<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int D2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
}
template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
  typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
    typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<G1,T1,E1> >::make(l),
    CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpAdd,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator+(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpAdd,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpSubtract,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator-(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpSubtract,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMultiply,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator*(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMultiply,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpDivide,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator/(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpDivide,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpMod,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator%(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpMod,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator&(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseAnd,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator|(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseOr,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator^(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpBitwiseXor,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnDot,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
dot(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnDot,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnLdexp,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
ldexp(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnLdexp,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnPow,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
pow(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnPow,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnFmod,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
fmod(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnFmod,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
atan2(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<FnArcTan2,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpEQ,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator==(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpEQ,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Vector<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int D1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Tensor<D1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
inline typename MakeFieldReturn<BinaryNode<OpNE,
  typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
operator!=(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
{
  typedef BinaryNode<OpNE,
    typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
  return MakeFieldReturn<Tree_t>::make(Tree_t(
    CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
    CreateLeaf<Field<G2,T2,E2> >::make(r)));
}
struct FarLeftTag;
template<class G, class T, class E> class Field;
template<class GeometryTag, class T, class Expr>
struct CreateLeaf<Field<GeometryTag, T, ExpressionTag<Expr> > >
{
  typedef Field<GeometryTag, T, ExpressionTag<Expr> > Input_t;
  typedef Expr Leaf_t;
  typedef const Leaf_t &Return_t;
  inline static
  Return_t make(const Input_t &f)
    {
      return f.engine().expression();
    }
};
template<class GeometryTag, class T, class EngineTag>
struct CreateLeaf<Field<GeometryTag, T, EngineTag> >
{
  typedef Field<GeometryTag, T, EngineTag> Input_t;
  typedef Reference<Input_t> Leaf_t;
  typedef Leaf_t Return_t;
  inline static
  Return_t make(const Input_t &f)
    {
      return Leaf_t(f);
    }
};
template<class GeometryTag, class T, class EngineTag>
struct CreateLeaf<Scalar<Field<GeometryTag, T, EngineTag> > >
{
  typedef Scalar<Field<GeometryTag, T, EngineTag> > Input_t;
  typedef Scalar<ErrorType> Leaf_t;
  typedef Leaf_t Return_t;
  inline static
  Return_t make(const Input_t &)
    {
      return ErrorType();
    }
};
template <int Dim>
class Centering;
template <int Dim>
class CanonicalCentering;
enum CenteringType {
 VertexType,
 EdgeType,
 FaceType,
 CellType
};
enum ContinuityType {
 Continuous = 0,
 Discontinuous
};
enum {
 XDim = 1,
 YDim = XDim << 1,
 ZDim = YDim << 1,
 AllDim = XDim | YDim | ZDim
};
template <int Dim>
class Centering
{
public:
  typedef Loc<Dim> Orientation;
  typedef Vector<Dim> Position;
  typedef std::vector<Orientation> Orientations;
  typedef std::vector<Position> Positions;
  Centering(CenteringType cent = CellType, ContinuityType cont = Continuous)
    : centering_type_m(cent), discontinuous_m(cont),
      orientations_m(0), positions_m(0)
    { }
  Centering(CenteringType cent, ContinuityType cont,
     const Orientations &orientations, const Positions &positions)
    : centering_type_m(cent), discontinuous_m(cont),
      orientations_m(orientations), positions_m(positions)
  {
      return;
  }
  Centering(const Centering<Dim>& model, int c)
    : centering_type_m(model.centering_type_m),
      discontinuous_m(model.discontinuous_m),
      orientations_m(1, model.orientations_m[c]),
      positions_m(1, model.positions_m[c])
    { }
  Centering<Dim> operator[](int iSubField) const
  {
    return Centering<Dim>(*this, iSubField);
  }
  ~Centering() { }
  inline CenteringType centeringType() const
    {
      return centering_type_m;
    }
  inline ContinuityType continuityType() const
    {
      return discontinuous_m;
    }
  inline bool discontinuous() const
  {
    return discontinuous_m == Discontinuous;
  }
  inline bool continuous() const
  {
    return discontinuous_m == Continuous;
  }
  inline const Orientations &orientations() const
  {
    return orientations_m;
  }
  inline const Positions &positions() const
  {
    return positions_m;
  }
  inline const Orientation &orientation(int i) const
  {
    return orientations_m[i];
  }
  inline const Position &position(int i) const
  {
    return positions_m[i];
  }
  inline int size() const
  {
    return orientations_m.size();
  }
  inline void
  addValue(const Orientation &orientation,
    const Position &position)
    {
      orientations_m.push_back(orientation);
      positions_m.push_back(position);
      return;
    }
private:
  CenteringType centering_type_m;
  ContinuityType discontinuous_m;
  Orientations orientations_m;
  Positions positions_m;
};
template <int Dim>
class CanonicalCentering {
public:
  CanonicalCentering();
  ~CanonicalCentering () {
    if (--class_count_m == 0) {
      for (int i = 0; i <= CellType; ++i) {
 for (int j = 0; j < 2; ++j)
   delete [] centering_table_m[i][j];
 delete [] centering_table_m[i];
      }
      delete [] centering_table_m;
    }
  }
  inline Centering<Dim> operator()
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     int dimension = 0) const
  {
    if (dimension == 0)
      dimension = AllDim;
    dimension %= (1<<Dim);
    return centering_table_m[type][discontinuous][dimension];
  }
private:
  inline static void addValue(typename Centering<Dim>::Orientations &os,
         typename Centering<Dim>::Positions &pos,
         const typename Centering<Dim>::Orientation &o,
         const typename Centering<Dim>::Position &p)
  {
    os.push_back(o);
    pos.push_back(p);
    return;
  }
  template <class T>
  inline static
  T combine(const T &op1, const T &op2)
  {
    T answer(op1);
    answer.insert(answer.end(), op2.begin(), op2.end());
    return answer;
  }
  static int class_count_m;
  static Centering<Dim>*** centering_table_m;
};
template <int Dim>
std::ostream &operator<<(std::ostream &o,
                         const Centering<Dim> &centering)
{
  switch (centering.centeringType())
  {
  case VertexType:
    o << "Vertex";
    break;
  case EdgeType:
    o << "Edge";
    break;
  case FaceType:
    o << "Face";
    break;
  case CellType:
    o << "Cell";
    break;
  }
  o << "," << (centering.continuous() ? "Continuous" : "Discontinuous")
    << ",{";
  for (int i = 0; i < centering.size();)
  {
    o << "[" << centering.orientation(i)
      << "," << centering.position(i) << "]";
    ++i;
    if (i < centering.size())
      o << ",";
  }
  o << "}";
  return o;
}
template <int Dim>
bool operator==(const Centering<Dim> &centering1, const Centering<Dim> &centering2)
{
  return
    centering1.centeringType() == centering2.centeringType() &&
    centering1.discontinuous() == centering2.discontinuous() &&
    centering1.orientations() == centering2.orientations() &&
    centering1.positions() == centering2.positions();
}
template <int Dim>
bool operator!=(const Centering<Dim> &centering1, const Centering<Dim> &centering2)
{
  return !(centering1 == centering2);
}
template <int Dim>
int CanonicalCentering<Dim>::class_count_m = 0;
template <int Dim>
Centering<Dim>*** CanonicalCentering<Dim>::centering_table_m = 0;
extern const CanonicalCentering<1> canonicalCenteringOne_g;
extern const CanonicalCentering<2> canonicalCenteringTwo_g;
extern const CanonicalCentering<3> canonicalCenteringThree_g;
template <int Dim>
const Centering<Dim> canonicalCentering
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension = 0);
template <>
const Centering<1> canonicalCentering<1>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension);
template <>
const Centering<2> canonicalCentering<2>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension);
template <>
const Centering<3> canonicalCentering<3>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension);
template<int Dim>
inline Interval<Dim>
cellDomainToCenteringDomain(const Interval<Dim> &cellDom,
                            const Centering<Dim> &centering, int i)
{
  if (centering.discontinuous())
  {
    return cellDom;
  }
  else
  {
    return shrinkRight(growRight(cellDom, 1), centering.orientation(i));
  }
}
template<int Dim>
inline Interval<Dim>
centeringDomainToCellDomain(const Interval<Dim> &cDom,
                            const Centering<Dim> &centering, int i)
{
  if (centering.discontinuous())
  {
    return cDom;
  }
  else
  {
    return shrinkRight(growRight(cDom, centering.orientation(i)), 1);
  }
}
template <int Dim>
class FieldOffset;
template <int Dim>
class FieldOffsetList;
template <int Dim>
class FieldOffset {
public:
  FieldOffset(const Loc<Dim> &loc, const int subFieldNumber = 0)
    : cell_offset_m(loc), subfield_number_m(subFieldNumber)
  {
    return;
  }
  FieldOffset()
    : cell_offset_m(Loc<Dim>()), subfield_number_m(0)
  {}
  inline void setSubFieldNumber(int subFieldNumber)
    {
      subfield_number_m = subFieldNumber;
      return;
    }
  inline Loc<Dim> &modifyCellOffset()
    {
      return cell_offset_m;
    }
  inline const Loc<Dim> &cellOffset() const
    {
      return cell_offset_m;
    }
  inline int subFieldNumber() const
    {
      return subfield_number_m;
    }
private:
  Loc<Dim> cell_offset_m;
  int subfield_number_m;
};
template <int Dim>
std::ostream &operator<<(std::ostream &o,
    const FieldOffset<Dim> &fieldOffset)
{
  return o << "FieldOffset: (" << fieldOffset.cellOffset()
    << ", " << fieldOffset.subFieldNumber() << ")";
}
template <int Dim>
inline bool
operator==(const FieldOffset<Dim> &fieldOffset1,
    const FieldOffset<Dim> &fieldOffset2)
{
  return
    fieldOffset1.cellOffset() == fieldOffset2.cellOffset() &&
    fieldOffset1.subFieldNumber() == fieldOffset2.subFieldNumber();
}
template <int Dim>
inline bool
operator!=(const FieldOffset<Dim> &fieldOffset1,
    const FieldOffset<Dim> &fieldOffset2)
{
  return !(fieldOffset1 == fieldOffset2);
}
template <int Dim>
class FieldOffsetList
{
public:
  typedef size_t size_type;
  typedef FieldOffset<Dim>& reference;
  typedef const FieldOffset<Dim>& const_reference;
  size_type size() const
  {
    return v_m.size();
  }
  const_reference operator[](const size_type n) const
  {
    return v_m[n];
  }
  FieldOffsetList() {}
  FieldOffsetList(const size_type sz)
  {
    v_m.reserve(sz);
  }
  FieldOffsetList(const std::vector<FieldOffset<Dim> > &v) {
    v_m.resize(v.size());
    std::copy(v.begin(), v.end(), v_m.begin());
  }
  FieldOffsetList &operator=(const std::vector<FieldOffset<Dim> > &v)
  {
    v_m.resize(v.size());
    std::copy(v.begin(), v.end(), v_m.begin());
    return *this;
  }
  reference operator[](const size_type n)
  {
    return v_m[n];
  }
private:
  std::vector<FieldOffset<Dim> > v_m;
};
template <int Dim>
std::ostream &operator<<(std::ostream &o,
    const FieldOffsetList<Dim> &fieldOffsetList)
{
  o << "FieldOffsetList:\n";
  for (int index = 0; index < fieldOffsetList.size(); ++index)
    o << fieldOffsetList[index] << std::endl;
  return o;
}
template<class GeometryTag, class T, class Expr, int Dim,
         class BinaryFunction>
inline
T
accumulate(BinaryFunction binary_op,
    const Field<GeometryTag, T, Expr>& field,
    const FieldOffsetList<Dim> &lst,
    const Loc<Dim> &loc)
{
  typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
  typedef typename FieldOffsetList<Dim>::size_type size_type;
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  const size_type lstLength = lst.size();
  if (__builtin_expect(!!(lstLength > 0), true)) {} else Pooma::toss_cookies("accumulate must be given a nonempty list.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 334);
  T_t init = field(lst[0], loc);
  for (size_type i = 1; i < lstLength ; ++i)
    init = binary_op(init, field(lst[i], loc));
  return init;
}
template<class GeometryTag, class T, class Expr, int Dim>
inline
T
sum(const Field<GeometryTag, T, Expr>& field,
    const FieldOffsetList<Dim> &lst,
    const Loc<Dim> &loc)
{
  typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  return accumulate(std::plus<T_t>(), field, lst, loc);
}
template<class GeometryTag, class T, class Expr, int Dim>
inline
T
av(const Field<GeometryTag, T, Expr>& field,
   const FieldOffsetList<Dim> &lst,
   const Loc<Dim> &loc)
{
  typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  return sum(field, lst, loc) / lst.size();
}
template <class T>
struct fomin : public std::binary_function<T, T, T>
{
  T operator()(const T &op1, const T &op2) const {
    return std::min(op1, op2);
  }
};
template<class GeometryTag, class T, class Expr, int Dim>
inline
T
min(const Field<GeometryTag, T, Expr>& field,
    const FieldOffsetList<Dim> &lst,
    const Loc<Dim> &loc)
{
  typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  return accumulate(fomin<T_t>(), field, lst, loc);
}
template <class T>
struct fomax : public std::binary_function<T, T, T>
{
  T operator()(const T &op1, const T &op2) const {
    return std::max(op1, op2);
  }
};
template<class GeometryTag, class T, class Expr, int Dim>
inline
T
max(const Field<GeometryTag, T, Expr>& field,
    const FieldOffsetList<Dim> &lst,
    const Loc<Dim> &loc)
{
  typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  return accumulate(fomax<T_t>(), field, lst, loc);
}
template <class GeometryTag, class T, class Expr, int Dim>
inline
typename
View2<Field<GeometryTag, T, Expr>, std::vector<FieldOffset<Dim> >,
      Centering<Dim> >::Type_t
replicate(const Field<GeometryTag, T, Expr>& field,
          const std::vector<FieldOffsetList<Dim> > &vec,
          const Centering<Dim> &centering)
{
  PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
  typedef typename std::vector<FieldOffsetList<Dim> >::size_type vsize_type;
  if (__builtin_expect(!!(vec.size() > 0), true)) {} else Pooma::toss_cookies("Cannot replicate no values.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 445);
  if (__builtin_expect(!!(vec.size() == centering.size()), true)) {} else Pooma::toss_cookies("Vector and output centering sizes must match.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 447);
  std::vector<FieldOffset<Dim> > vecFO(vec.size());
  for (vsize_type i = 0; i < vec.size(); ++i) {
    if (__builtin_expect(!!(vec[i].size() == 1), true)) {} else Pooma::toss_cookies("Can replicate only one value.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 451);
    vecFO[i] = vec[i][0];
  }
  return field(vecFO, centering);
}
#include <numeric>
template <int Dim, bool IntraCellOnly = false>
class NearestNeighborClass {
public:
  typedef FieldOffset<Dim> FieldOffset_t;
  typedef FieldOffsetList<Dim> FieldOffsetList_t;
  typedef std::vector<FieldOffset_t> FieldOffset_vt;
  typedef std::vector<FieldOffsetList_t> Answer_t;
  typedef Centering<Dim> Center;
  typedef typename Center::Positions Positions;
  typedef typename Center::Position Position;
  typedef std::pair<int, Position> MinimumPair;
  typedef std::vector<MinimumPair> MinimumSet;
  NearestNeighborClass() {}
  inline Answer_t
  operator()(const Center &inputCentering, const Center &outputCentering)
  {
    if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 95);
    Answer_t answer;
    answer.resize(outputCentering.size());
    const Positions inputPositions = inputCentering.positions();
    const Positions outputPositions = outputCentering.positions();
    for (typename Answer_t::size_type outputIndex = 0;
  outputIndex < outputCentering.size();
  ++outputIndex)
      answer[outputIndex] = nearestNeighbors(inputPositions,
          outputPositions[outputIndex]);
    return answer;
  }
  inline FieldOffsetList_t
  operator()(const Center &inputCentering,
      const FieldOffset_t &fieldOffset,
      const Center &outputCentering)
  {
    if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 122);
    if (__builtin_expect(!!(fieldOffset.subFieldNumber() < outputCentering.size()), true)) {} else Pooma::toss_cookies("The field offset must correspond to the output centering.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 124);
    return nearestNeighbors(inputCentering.positions(),
       outputCentering.position(fieldOffset.subFieldNumber()));
  }
  inline std::vector<FieldOffsetList_t>
  operator()(const Center &inputCentering,
      const FieldOffsetList_t &fieldOffsetList,
      const Center &outputCentering)
  {
    if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 140);
    Answer_t answer;
    answer.resize(fieldOffsetList.size());
    const Positions inputPositions = inputCentering.positions();
    for (typename FieldOffsetList_t::size_type folIndex = 0;
  folIndex < outputCentering.size();
  ++folIndex) {
      if (__builtin_expect(!!(fieldOffsetList[folIndex].subFieldNumber() < outputCentering.size()), true)) {} else Pooma::toss_cookies("The field offset must correspond to the output centering.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 152);
      answer[folIndex] =
 nearestNeighbors(inputPositions,
    outputCentering.position(fieldOffsetList[folIndex].subFieldNumber()));
    }
    return answer;
  }
private:
  inline FieldOffsetList_t
  nearestNeighbors(const Positions &inputPositions,
     const Position outputValue)
  {
    MinimumSet minimumSet;
    typename Positions::size_type inputIndex = 0;
    Position positionDifference = inputPositions[inputIndex] - outputValue;
    double minimumDistance =
      (IntraCellOnly ?
       manhattanDistance<Manhattan>(positionDifference) :
       manhattanDistance<ManhattanGrid>(positionDifference));
    minimumSet.push_back(std::make_pair(inputIndex, positionDifference));
    for (++inputIndex;
  inputIndex < inputPositions.size();
  ++inputIndex) {
      positionDifference = inputPositions[inputIndex] - outputValue;
      const double distance =
 (IntraCellOnly ?
  manhattanDistance<Manhattan>(positionDifference) :
  manhattanDistance<ManhattanGrid>(positionDifference));
      if (distance < minimumDistance + epsilon) {
 if (distance < minimumDistance) {
   minimumSet.clear();
   minimumDistance = distance;
 }
 minimumSet.push_back(std::make_pair(inputIndex,
         positionDifference));
      }
    }
    FieldOffset_vt answerHolder;
    if (IntraCellOnly) {
      for (typename MinimumSet::size_type minIndex = 0;
    minIndex < minimumSet.size();
    ++minIndex)
 answerHolder.push_back(FieldOffset_t(Loc<Dim>(0),
          minimumSet[minIndex].first));
    }
    else {
      FieldOffset_vt partialAnswer;
      for (typename MinimumSet::size_type minIndex = 0;
    minIndex < minimumSet.size();
    ++minIndex)
 {
   partialAnswer = computeCellOffsets(minimumSet[minIndex].first,
          minimumSet[minIndex].second);
   answerHolder.insert(answerHolder.end(),
         partialAnswer.begin(), partialAnswer.end());
 }
      std::sort(answerHolder.begin(), answerHolder.end(),
  CompareFieldOffset());
      answerHolder.erase(std::unique(answerHolder.begin(),
         answerHolder.end(),
         EqualFieldOffset()),
    answerHolder.end());
    }
    return answerHolder;
  }
  struct ManhattanGrid : public std::binary_function<double, double, double>
  {
    double operator()(const double totalSoFar, double coordinate) const {
      const double absCoordinate = std::abs(coordinate);
      return totalSoFar + std::min(absCoordinate, 1-absCoordinate);
    }
  };
  struct Manhattan : public std::binary_function<double, double, double>
  {
    double operator()(const double totalSoFar, double coordinate) const {
      return totalSoFar + std::abs(coordinate);
    }
  };
  template <class Distance>
  inline static
  double manhattanDistance(const Position &difference)
  {
    double answer = 0.0;;
    for (int coordinate = Dim-1; coordinate >= 0; --coordinate)
      answer = Distance()(answer, difference(coordinate));
    return answer;
  }
  inline static const FieldOffset_vt
  computeCellOffsets(const int inputValueIndex, const Position &difference)
  {
    FieldOffset_vt answer(1);
    int numTuples = 1;
    int cellOffsetCoordinates[2];
    int numOffsets;
    for (int dimension = 0; dimension < Dim; ++dimension) {
      numOffsets =
 convertDifferenceToCellOffsets(difference(dimension),
           cellOffsetCoordinates);
      if (__builtin_expect(!!(numOffsets >= 1 && numOffsets <= 2), true)) {} else Pooma::toss_cookies("Incorrect number of cell offsets", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 309);
      if (numOffsets == 2)
 answer.insert(answer.end(), answer.begin(), answer.end());
      for (int coc = 0; coc < numOffsets; ++coc)
 for (int tuple = 0; tuple < numTuples; ++tuple)
   answer[numTuples * coc + tuple].modifyCellOffset()[dimension] =
     cellOffsetCoordinates[coc];
      numTuples *= numOffsets;
    }
    for (int i = numTuples-1; i >= 0; --i)
      answer[i].setSubFieldNumber(inputValueIndex);
    return answer;
  }
  inline static
  int convertDifferenceToCellOffsets(const double difference,
         int cellOffsetCoordinate[])
  {
    if (difference < -0.5 - epsilon) {
      cellOffsetCoordinate[0] = +1;
      return 1;
    }
    else if (std::abs(difference + 0.5) < epsilon) {
      cellOffsetCoordinate[0] = +1;
      cellOffsetCoordinate[1] = 0;
      return 2;
    }
    else if (difference <= 0.5 - epsilon) {
      cellOffsetCoordinate[0] = 0;
      return 1;
    }
    else if (std::abs(difference - 0.5) < epsilon) {
      cellOffsetCoordinate[0] = 0;
      cellOffsetCoordinate[1] = -1;
      return 2;
    }
    else if (difference < 1.0 + epsilon) {
      cellOffsetCoordinate[0] = -1;
      return 1;
    }
    else {
      if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Out of range difference", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 361);
      return 0;
    }
  }
  struct CompareFieldOffset :
    public std::binary_function<FieldOffset_t, FieldOffset_t, bool> {
    bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) {
      return (op1.cellOffset() < op2.cellOffset()) ||
 (op1.cellOffset() == op2.cellOffset() &&
  op1.subFieldNumber() < op2.subFieldNumber());
    }
  };
  struct EqualFieldOffset :
    public std::binary_function<FieldOffset_t, FieldOffset_t, bool> {
    bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) {
      return op1.cellOffset() == op2.cellOffset() &&
 op1.subFieldNumber() == op2.subFieldNumber();
    }
  };
  static const double epsilon;
};
template <int Dim, bool IntraCellOnly>
const double
NearestNeighborClass<Dim, IntraCellOnly>::epsilon = 1.0e-08;
template <int Dim>
inline
std::vector<FieldOffsetList<Dim> >
nearestNeighbors(const Centering<Dim> &inputCentering,
   const Centering<Dim> &outputCentering)
{
  return NearestNeighborClass<Dim>()(inputCentering, outputCentering);
}
template <int Dim>
inline
std::vector<FieldOffsetList<Dim> >
nearestNeighbors(const Centering<Dim> &inputCentering,
   const Centering<Dim> &outputCentering,
   const bool)
{
  return NearestNeighborClass<Dim, true>()(inputCentering, outputCentering);
}
template <int Dim>
inline
std::vector<FieldOffsetList<Dim> >
nearestNeighbors(const Centering<Dim> &inputCentering,
   const FieldOffsetList<Dim> &fOL,
   const Centering<Dim> &outputCentering)
{
  return NearestNeighborClass<Dim>()(inputCentering, fOL, outputCentering);
}
template <int Dim>
inline
std::vector<FieldOffsetList<Dim> >
nearestNeighbors(const Centering<Dim> &inputCentering,
   const FieldOffsetList<Dim> &fOL,
   const Centering<Dim> &outputCentering,
   const bool)
{
  return NearestNeighborClass<Dim, true>()
    (inputCentering, fOL, outputCentering);
}
template <int Dim>
inline
FieldOffsetList<Dim>
nearestNeighbors(const Centering<Dim> &inputCentering,
   const FieldOffset<Dim> &fieldOffset,
   const Centering<Dim> &outputCentering)
{
  return NearestNeighborClass<Dim>()
    (inputCentering, fieldOffset, outputCentering);
}
template <int Dim>
inline
FieldOffsetList<Dim>
nearestNeighbors(const Centering<Dim> &inputCentering,
   const FieldOffset<Dim> &fieldOffset,
   const Centering<Dim> &outputCentering,
   const bool)
{
  return NearestNeighborClass<Dim, true>()
    (inputCentering, fieldOffset, outputCentering);
}
template<int Dim>
inline Vector<Dim, double>
inputPosition(const Centering<Dim> &inputCentering,
              const FieldOffset<Dim> &fieldOffset)
{
  Vector<Dim, double> ret =
    inputCentering.position(fieldOffset.subFieldNumber());
  for (int i = 0; i < Dim; ++i)
    ret(i) += fieldOffset.cellOffset()[i].first();
  return ret;
}
class PrintField;
template<int Dim>
struct PerformPrintField
{
  template <class S, class A>
  static void print(const PrintField &, S &, const A &);
};
template<>
struct PerformPrintField<1>
{
  template<class S, class A>
  static void print(const PrintField &, S &, const A &);
};
class PrintField
{
public:
  PrintField(int domainWidth = 3, int dataWidth = 10,
      int dataPrecision = 4, int carReturn = -1,
      bool scientific = false, int spacing = 1)
    : domainwidth_m(domainWidth), datawidth_m(dataWidth),
      dataprecision_m(dataPrecision), carreturn_m(carReturn),
      spacing_m(spacing), scientific_m(scientific)
    {
      ;
      ;
      ;
      ;
    }
  PrintField(const PrintField &a)
    : domainwidth_m(a.domainwidth_m), datawidth_m(a.datawidth_m),
      dataprecision_m(a.dataprecision_m), carreturn_m(a.carreturn_m),
      scientific_m(a.scientific_m)
    {
    }
  ~PrintField()
    {
    }
  template<class S, class A>
  void print(S &s, const A &a) const
    {
      forEach(a, PerformUpdateTag(), NullCombine());
      Pooma::blockAndEvaluate();
      for (int m = 0; m < a.numMaterials(); m++)
        for (int c = 0; c < a.centeringSize(); c++)
          {
            s << "Material #" << m << ", Centering #" << c << " " << a.centering(c)
              << "\n"<< "-------------\n";
            PerformPrintField<A::dimensions>::print(*this, s, a.subField(m, c));
          }
    }
  int domainWidth() const
    {
      return domainwidth_m;
    }
  void setDomainWidth(int val)
    {
      domainwidth_m = val;
      ;
    }
  int dataWidth() const
    {
      return datawidth_m;
    }
  void setDataWidth(int val)
    {
      datawidth_m = val;
      ;
    }
  int dataPrecision() const
    {
      return dataprecision_m;
    }
  void setDataPrecision(int val)
    {
      dataprecision_m = val;
      ;
    }
  int carReturn() const
    {
      return carreturn_m;
    }
  void setCarReturn(int val)
    {
      carreturn_m = val;
    }
  bool scientific() const
    {
      return scientific_m;
    }
  void setScientific(bool val)
    {
      scientific_m = val;
    }
  int spacing() const
    {
      return spacing_m;
    }
  void setSpacing(int val)
    {
      spacing_m = val;
      ;
    }
private:
  int domainwidth_m;
  int datawidth_m;
  int dataprecision_m;
  int carreturn_m;
  int spacing_m;
  bool scientific_m;
};
template<class S, class A>
void
PerformPrintField<1>::print(const PrintField &p, S &s, const A &a)
{
  PoomaCTAssert<(A::dimensions == 1)>::test();
  typedef typename A::Domain_t Domain_t;
  typedef typename Domain_t::const_iterator Iterator_t;
  Iterator_t griditer = a.domain().begin();
  Iterator_t enditer = a.domain().end();
  s << "[";
  if (a.domain()[0].first() < 0)
    s.fill(' ');
  else
    s.fill('0');
  s.width(p.domainWidth());
  s << a.domain()[0].first() << ":";
  if (a.domain()[0].last() < 0)
    s.fill(' ');
  else
    s.fill('0');
  s.width(p.domainWidth());
  s << a.domain()[0].last() << "] = ";
  s.fill(' ');
  int i, printed = 0;
  while (griditer != enditer)
    {
      int spacing = 0;
      if (printed > 0)
     {
       spacing = p.spacing();
       if (p.carReturn() >= 0 && printed >= p.carReturn())
            {
              s << "\n";
           spacing = 2*p.domainWidth() + 6;
           printed = 0;
         }
     }
      for (i=0; i < spacing; ++i)
        s << " ";
      if (p.scientific())
        s.setf(std::ios::scientific);
      s.precision(p.dataPrecision());
      s.width(p.dataWidth());
      s << a.read(*griditer);
      ++griditer;
      ++printed;
    }
  s << "\n";
}
template<int Dim>
template<class S, class A>
void
PerformPrintField<Dim>::print(const PrintField &p, S &s, const A &a)
{
  int i, j, k;
  PoomaCTAssert<(A::dimensions == Dim && Dim > 1)>::test();
  typedef typename A::Domain_t Domain_t;
  typedef typename Domain_t::Element_t Element_t;
  typedef typename Domain_t::const_iterator Iterator_t;
  Iterator_t griditer = a.domain().begin();
  Iterator_t enditer = a.domain().end();
  Element_t x0 = a.domain()[0].first();
  Element_t x1 = a.domain()[0].last();
  Element_t xs = a.domain()[0].stride();
  Element_t y0 = a.domain()[1].first();
  Element_t y1 = a.domain()[1].last();
  Element_t ys = a.domain()[1].stride();
  while (griditer != enditer)
    {
      if (Dim > 2)
     {
       s << '\n' << a.domain()[0] << a.domain()[1];
       for (i=2; i < Dim; ++i)
         s << "[" << (*griditer)[i].first() << "]";
       s << ":" << '\n';
       s << "----------------------------------------------------\n";
        }
      for (j=y0; j <= y1; j += ys)
     {
       s << "[";
          if (x0 < 0)
            s.fill(' ');
          else
            s.fill('0');
          s.width(p.domainWidth());
          s << x0 << ":";
          if (x1 < 0)
            s.fill(' ');
          else
            s.fill('0');
          s.width(p.domainWidth());
       s << x1 << "]";
       for (i=1; i < Dim; ++i)
         {
           s << "[";
              if ((*griditer)[i].first() < 0)
                s.fill(' ');
              else
                s.fill('0');
              s.width(p.domainWidth());
           s << (*griditer)[i].first() << "]";
         }
       s.fill(' ');
          s << " = ";
       int printed = 0;
       for (i=x0; i <= x1; i += xs)
         {
           int spacing = 0;
           if (printed > 0)
          {
            spacing = p.spacing();
            if (p.carReturn() >= 0 && printed >= p.carReturn())
              {
                s << '\n';
                spacing = (Dim + 1)*(p.domainWidth() + 2) + 4;
                printed = 0;
              }
          }
           for (k=0; k < spacing; ++k)
          s << ' ';
           if (p.scientific())
          s.setf(std::ios::scientific);
           s.precision(p.dataPrecision());
           s.width(p.dataWidth());
           s << a.read(*griditer);
           ++griditer;
           ++printed;
         }
       s << '\n';
        }
    }
}
template<int Dim>
struct FieldEnginePatch
{
  FieldEnginePatch(int patch, Interval<Dim> domain)
    : patch_m(patch), domain_m(domain)
  { }
  int patch_m;
  Interval<Dim> domain_m;
};
namespace Pooma {
  unsigned int activeRelationGroups();
  bool isRelationGroupActive(unsigned int groups);
  void activateRelationGroup(unsigned int group);
  void deactivateRelationGroup(unsigned int group);
  unsigned int newRelationGroup();
}
class RelationListItem {
public:
  RelationListItem()
  : priority_m(0),
    groups_m(Pooma::activeRelationGroups()),
    dirty_m(true)
    { }
  RelationListItem(const RelationListItem &model)
  : priority_m(model.priority_m),
    groups_m(model.groups_m),
    dirty_m(model.dirty_m)
    { }
  virtual ~RelationListItem() { }
  virtual void apply() = 0;
  virtual void notifyPreRead()
    {
      if (Pooma::isRelationGroupActive(groups_m) && dirty_m)
        {
          apply();
          clearDirty();
        }
    }
  virtual void notifyPostWrite()
    {
      setDirty();
    }
  inline bool dirty() const { return dirty_m; }
  inline unsigned int priority() const { return priority_m; }
  virtual void setDirty()
    {
      dirty_m = true;
    }
  virtual void clearDirty()
    {
      dirty_m = false;
    }
  inline void setPriority(unsigned int p)
    {
      priority_m = p;
    }
private:
  unsigned int priority_m;
  unsigned int groups_m;
  bool dirty_m;
};
namespace Pooma {
  struct DontCopyRelations { };
}
template<class Target>
class RelationRetargetBase : public RelationListItem {
public:
  RelationRetargetBase(const Target &target)
  : target_m(target, Pooma::DontCopyRelations())
    { }
  RelationRetargetBase(const RelationRetargetBase<Target> &model)
  : RelationListItem(model),
    target_m(model.target_m)
    { }
  virtual ~RelationRetargetBase() { }
  Target &target() { return target_m; }
  const Target &target() const { return target_m; }
  virtual RelationListItem *retarget(const Target &target) const = 0;
protected:
  Target target_m;
};
template<class Target, class Functor>
class RelationBase : public RelationRetargetBase<Target> {
public:
  RelationBase(const Target &t, const Functor &f)
  : RelationRetargetBase<Target>(t),
    functor_m(f, t)
    { }
  RelationBase(const RelationBase<Target, Functor> &model)
  : RelationRetargetBase<Target>(model),
    functor_m(model.functor_m)
    { }
  virtual ~RelationBase() { }
  Functor &functor() { return functor_m; }
  const Functor &functor() const { return functor_m; }
protected:
  Functor functor_m;
};
class RelationListData : public RefCounted
{
public:
  RelationListData()
    { }
  RelationListData(const RelationListData &model)
  : data_m(model.data_m)
    { }
  RelationListData &operator=(const RelationListData &rhs)
    {
      data_m = rhs.data_m;
      return *this;
    }
  ~RelationListData()
    {
      typedef List_t::size_type size_type;
      for (size_type i = 0; i < data_m.size(); i++)
        delete data_m[i];
    }
  inline int size() const
    {
      return data_m.size();
    }
  inline RelationListItem *elem(int i) const
    {
      return data_m[i];
    }
  inline RelationListItem* &elem(int i)
    {
      return data_m[i];
    }
  void add(RelationListItem *item)
    {
      data_m.push_back(item);
      int i = size() - 1;
      while (i > 0)
        {
          if (data_m[i]->priority() <= data_m[i]->priority())
            break;
          data_m[i] = data_m[i - 1];
          data_m[i - 1] = item;
          --i;
        }
    }
private:
  typedef std::vector<RelationListItem *> List_t;
  List_t data_m;
};
class RelationList {
public:
  RelationList()
  : list_m(new RelationListData)
    { }
  RelationList(const RelationList &model)
  : list_m(model.list_m)
    { }
  ~RelationList() { }
  template<class Target>
  void makeOwnCopy(const Target &t)
    {
      list_m = new RelationListData(*list_m);
      for (int i = 0; i < list_m->size(); i++)
        {
          RelationRetargetBase<Target> *u =
            dynamic_cast<RelationRetargetBase<Target> *>(list_m->elem(i));
          if (u != NULL)
            list_m->elem(i) = u->retarget(t);
        }
    }
  inline void erase()
    {
     list_m = new RelationListData;
    }
  void addRelation(RelationListItem *item)
    {
      list_m->add(item);
    }
  void notifyPreRead() const
    {
      for (int i = 0; i < list_m->size(); ++i)
        list_m->elem(i)->notifyPreRead();
    }
  void notifyPostWrite() const
    {
      for (int i = 0; i < list_m->size(); ++i)
        list_m->elem(i)->notifyPostWrite();
    }
  void setDirty() const
    {
      for (int i = 0; i < list_m->size(); ++i)
        list_m->elem(i)->setDirty();
    }
  void clearDirty() const
    {
      for (int i = 0; i < list_m->size(); ++i)
        list_m->elem(i)->clearDirty();
    }
  bool dirty() const
    {
      for (int i = 0; i < list_m->size(); ++i)
        if (list_m->elem(i)->dirty())
   return true;
      return false;
    }
  inline RelationListItem *operator()(int i) const
    {
      return list_m->elem(i);
    }
  inline RelationListItem *operator()(int i)
    {
      return list_m->elem(i);
    }
  inline int size() const { return list_m->size(); }
private:
  RefCountedPtr<RelationListData> list_m;
};
template<int Dim, class T, class EngineTag> class Engine;
template<class Components> class ComponentWrapper;
namespace Pooma {
  struct MaterialViewTag {};
  struct CenteringViewTag {};
}
template <int Dim, class T, class EngineTag>
class FieldEngineBaseData
{
public:
  FieldEngineBaseData()
    : engine_m()
  { }
  template<class Initializer>
  FieldEngineBaseData(const Initializer &init)
    : engine_m(init)
  { }
  FieldEngineBaseData(const Pooma::NoInit &)
    : engine_m()
  { }
  template<class Initializer>
  FieldEngineBaseData(const Initializer &init, const RelationList &l)
    : engine_m(init),
      relations_m(l)
  { }
  template<class Engine, class Domain>
  FieldEngineBaseData(const Engine &e,
                      const Domain &d, const RelationList &l)
    : engine_m(NewEngineEngine<Engine, Domain>::apply(e, d),
               NewEngineDomain<Engine, Domain>::apply(e, d)),
      relations_m(l)
  {
  }
  const Engine<Dim, T, EngineTag> &engine() const { return engine_m; }
  Engine<Dim, T, EngineTag> &engine() { return engine_m; }
  RelationList &relations() const { return relations_m; }
private:
  Engine<Dim, T, EngineTag> engine_m;
  mutable RelationList relations_m;
};
template<class Mesh, class T, class EngineTag>
class FieldEngine
{
public:
  enum { dimensions = Mesh::dimensions };
  enum { Dim = dimensions };
  typedef FieldEngine<Mesh, T, EngineTag> This_t;
  typedef FieldEngineBaseData<Dim, T, EngineTag> Data_t;
  typedef Engine<Dim, T, EngineTag> Engine_t;
  typedef typename Engine_t::Domain_t Domain_t;
  typedef typename Engine_t::Layout_t Layout_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  FieldEngine()
    : num_materials_m(0),
      physicalCellDomain_m(Pooma::NoInit()),
      guards_m(0)
  { }
  template<class Layout2>
  FieldEngine(const Centering<Dim> &centering, const Layout2 &layout,
              const Mesh &mesh, int materials = 1)
    : num_materials_m(materials),
      centering_m(centering),
      stride_m(centering.size()),
      physicalCellDomain_m(layout.domain()),
      guards_m(layout.externalGuards()),
      mesh_m(mesh)
  {
    physicalCellDomain_m = shrinkRight(shrink(physicalCellDomain_m, guards_m), 1);
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering.size(); ++ c)
      {
        data(m, c) = Data_t(layout);
      }
    }
  }
  FieldEngine(const This_t &model)
    : num_materials_m(model.num_materials_m),
      centering_m(model.centering_m),
      stride_m(model.stride_m),
      data_m(model.data_m),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guards_m),
      mesh_m(model.mesh_m)
  {
  }
  FieldEngine(const This_t &model, int subField)
    : num_materials_m(1),
      centering_m(model.centering_m, subField % model.centeringSize()),
      stride_m(model.stride_m),
      data_m(model.data_m + subField),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guards_m),
      mesh_m(model.mesh_m)
  {
  }
  FieldEngine(const This_t &model, int m, int c)
    : num_materials_m(1),
      centering_m(model.centering_m, c),
      stride_m(model.stride_m),
      data_m(model.data_m + model.stride_m * m + c),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guards_m),
      mesh_m(model.mesh_m)
  {
  }
  FieldEngine(const This_t &model, int c, const Pooma::CenteringViewTag&)
    : num_materials_m(model.num_materials_m),
      centering_m(model.centering_m, c),
      stride_m(model.stride_m),
      data_m(model.data_m + c),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guards_m),
      mesh_m(model.mesh_m)
  {
  }
  FieldEngine(const This_t &model, int m, const Pooma::MaterialViewTag&)
    : num_materials_m(1),
      centering_m(model.centering_m),
      stride_m(model.stride_m),
      data_m(model.data_m + m * model.stride_m),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guards_m),
      mesh_m(model.mesh_m)
  {
  }
  template<class T2, class EngineTag2>
  FieldEngine(const FieldEngine<Mesh, T2, EngineTag2> &model,
              const Domain_t &d)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      guards_m(0),
      mesh_m(model.mesh(), inputDomainToVertexDomain(d))
  {
    addSubFields();
    physicalCellDomain_m = d;
    if (centeringSize() == 1)
    {
      physicalCellDomain_m =
        centeringDomainToCellDomain(physicalCellDomain_m, centering_m, 0);
    }
    for (int c = 0; c < centeringSize(); ++c)
    {
      Domain_t dc(cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, c));
      for (int m = 0; m < numMaterials(); ++m)
      {
        data(m, c) = Data_t(model.data(m, c).engine(), dc, model.data(m, c).relations());
      }
    }
    physicalCellDomain_m -= d.firsts();
  }
  template<class Mesh2, class T2, class EngineTag2, class Domain>
  FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
              const Domain &d)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      guards_m(0)
  {
    addSubFields();
    ;
    for (int m = 0; m < numMaterials(); ++m)
    {
      data(m, 0) = Data_t(model.data(m, 0).engine(), d,
                          model.data(m, 0).relations());
    }
    mesh_m = Mesh(DomainLayout<Dim>(inputDomainToVertexDomain(data(0,0).engine().domain())));
    physicalCellDomain_m = mesh_m.physicalCellDomain();
  }
  template<class Mesh2, class EngineTag2>
  FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
              const SliceInterval<Mesh2::dimensions, Dim> &d)
  {
    initSlice(model, d);
  }
  template<class Mesh2, class EngineTag2>
  FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
              const SliceRange<Mesh2::dimensions, Dim> &d)
  {
    initSlice(model, d);
  }
  template<class Mesh2, class EngineTag2>
  FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
       const SliceInterval<Dim, Mesh2::dimensions> &d,
       const Interval<Dim>& totalDomain)
  {
    initSlice(model, d, totalDomain);
  }
  template<class T2, class EngineTag2>
  FieldEngine(const FieldEngine<Mesh, T2, EngineTag2> &model,
              const INode<Dim> &i)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      guards_m(0),
      mesh_m(model.mesh(),
             inputDomainToVertexDomain(i.domain()))
  {
    addSubFields();
    physicalCellDomain_m = i.domain();
    if (centeringSize() == 1)
    {
      physicalCellDomain_m =
        centeringDomainToCellDomain(physicalCellDomain_m, centering_m, 0);
    }
    for (int c = 0; c < centeringSize(); ++ c)
    {
      INode<Dim> ic(i, cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, c));
      for (int m = 0; m < numMaterials(); ++m)
      {
        data(m, c) = Data_t(model.data(m, c).engine(), ic, model.data(m, c).relations());
      }
    }
    physicalCellDomain_m -= i.domain().firsts();
  }
  template<class Mesh2, class T2, class EngineTag2, class Tag>
  FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
              const EngineView<Tag> &ev)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      physicalCellDomain_m(model.physicalCellDomain()),
      guards_m(model.guardLayers()),
      mesh_m(model.mesh())
  {
    typedef typename FieldEngine<Mesh2, T2, EngineTag2>::Engine_t EngIn_t;
    typedef LeafFunctor<EngIn_t, EngineView<Tag> > Functor_t;
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centeringSize(); ++c)
      {
        data(m, c)
          = Data_t(Functor_t::apply(model.data(m, c).engine(), ev),
                   model.data(m, c).relations());
      }
    }
  }
  template<class EngineTag2>
  FieldEngine(const FieldEngine<Mesh, T, EngineTag2> &model,
              const FieldEnginePatch<Dim> &p)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      guards_m(model.guardLayers()),
      mesh_m(model.mesh())
  {
    ;
    addSubFields();
    data(0, 0) = Data_t(engineFunctor(model.engine(), EnginePatch(p.patch_m)));
    physicalCellDomain_m =
      centeringDomainToCellDomain(p.domain_m, centering_m, 0);
  }
  template<class Mesh2, class T2, class EngineTag2, class Components>
  FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
              const ComponentWrapper<Components> &cw)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      physicalCellDomain_m(model.physicalCellDomain()),
      guards_m(model.guardLayers()),
      mesh_m(model.mesh())
  {
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centeringSize(); ++ c)
      {
        data(m, c) =
          Data_t(Engine_t(model.data(m, c).engine(), cw.components()),
                 model.data(m, c).relations());
      }
    }
  }
  FieldEngine(const This_t &model,
              const Pooma::DontCopyRelations &d)
    : num_materials_m(model.numMaterials()),
      centering_m(model.centering()),
      stride_m(model.centeringSize()),
      physicalCellDomain_m(model.physicalCellDomain_m),
      guards_m(model.guardLayers()),
      mesh_m(model.mesh())
  {
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centeringSize(); ++ c)
      {
        data(m, c) = Data_t(model.data(m, c).engine());
      }
    }
  }
  void initialize(const This_t &model)
  {
    num_materials_m = model.num_materials_m;
    stride_m = model.stride_m;
    centering_m = model.centering_m;
    data_m = model.data_m;
    physicalCellDomain_m = model.physicalCellDomain_m;
    guards_m = model.guards_m;
    mesh_m = model.mesh_m;
  }
  void addSubFields()
  {
    ;
    int size = numMaterials() * centeringSize();
    data_m.reserve(size);
    data_m.resize(size);
  }
  int numSubFields() const
  {
    return numMaterials() * centeringSize();
  }
  Engine_t &engine()
  {
    ;
    return data_m->engine();
  }
  const Engine_t &engine() const
  {
    ;
    return data_m->engine();
  }
  Engine_t &engine(int m, int c)
  {
    ;
    return data(m,c).engine();
  }
  const Engine_t &engine(int m, int c) const
  {
    ;
    return data(m,c).engine();
  }
  RelationList &relations() const
  {
    ;
    return data_m->relations();
  }
  RelationList &relations(int m, int c) const
  {
    ;
    return data(m, c).relations();
  }
  const GuardLayers_t &guardLayers() const
  {
    return guards_m;
  }
  GuardLayers_t &guardLayers()
  {
    return guards_m;
  }
  int numMaterials() const
  {
    return num_materials_m;
  }
  Domain_t &physicalCellDomain()
  {
    return physicalCellDomain_m;
  }
  const Domain_t &physicalCellDomain() const
  {
    return physicalCellDomain_m;
  }
  Domain_t totalCellDomain() const
  {
    return grow(physicalCellDomain_m, guards_m);
  }
  Domain_t physicalDomain() const
  {
    if (centeringSize() == 1)
      return cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, 0);
    else
      return physicalCellDomain_m;
  }
  Domain_t physicalDomain(int i) const
  {
    return cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, i);
  }
  Domain_t totalDomain() const
  {
    if (centeringSize() == 1)
      return cellDomainToCenteringDomain(totalCellDomain(), centering_m, 0);
    else
      return totalCellDomain();
  }
  Domain_t totalDomain(int i) const
  {
    return cellDomainToCenteringDomain(totalCellDomain(), centering_m, i);
  }
  const Centering<Dim> &centering() const
  {
    return centering_m;
  }
  int centeringSize() const
  {
    return centering_m.size();
  }
  Mesh &mesh()
  {
    return mesh_m;
  }
  const Mesh &mesh() const
  {
    return mesh_m;
  }
  template<class Subject>
  void makeOwnCopy(const Subject &s)
  {
    ;
    RefCountedBlockPtr<Data_t> model = data_m;
    data_m = RefCountedBlockPtr<Data_t>();
    stride_m = centeringSize();
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centeringSize(); ++ c)
      {
        data(m, c) = model[m*stride_m + c];
        data(m, c).engine().makeOwnCopy();
        data(m, c).relations().makeOwnCopy(s.subField(m, c));
      }
    }
  }
  Domain_t
  inputDomainToVertexDomain(const Domain_t &d) const
  {
    if (centeringSize() == 1)
      return growRight(centeringDomainToCellDomain(d, centering(), 0), 1);
    else
      return growRight(d, 1);
  }
  inline Data_t &
  data(int material, int centering)
  {
    ;
    return data_m[material * stride_m + centering];
  }
  inline const Data_t &
  data(int material, int centering) const
  {
    ;
    return data_m[material * stride_m + centering];
  }
private:
  template <class FE, class Domain>
  void initSlice(const FE& model, const Domain& d)
  {
    ;
    num_materials_m = model.numMaterials();
    stride_m = 1;
    typename Centering<Dim>::Orientation orientation;
    typename Centering<Dim>::Position position;
    int j=0;
    for (int i=0; i<FE::dimensions; ++i)
      {
 if (d.ignorable(i))
   continue;
 orientation[j] = model.centering().orientation(0)[i];
 position(j) = model.centering().position(0)(i);
 guards_m.lower(j) = model.guardLayers().lower(i);
 guards_m.upper(j) = model.guardLayers().upper(i);
 physicalCellDomain_m[j] = model.physicalCellDomain()[i];
 ++j;
      }
    centering_m.addValue(orientation, position);
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      data(m, 0) = Data_t(model.data(m, 0).engine(), d,
                          model.data(m, 0).relations());
    }
    mesh_m = Mesh(DomainLayout<Dim>(growRight(physicalCellDomain(), 1),
        guardLayers()));
  }
  template <class FE>
  void initSlice(const FE& model,
   const SliceInterval<Dim, FE::dimensions>& d,
   const Interval<Dim>& totalDomain)
  {
    ;
    num_materials_m = model.numMaterials();
    stride_m = 1;
    typename Centering<Dim>::Orientation orientation;
    typename Centering<Dim>::Position position;
    int j=0;
    for (int i=0; i<Dim; ++i)
      {
 if (d.ignorable(i)) {
   if (model.centering().centeringType() == CellType) {
     orientation[i] = 1;
     position(i) = 0.5;
   } else {
     orientation[i] = 0;
     position(i) = 0.0;
   }
   guards_m.lower(i) = 0;
   guards_m.upper(i) = 0;
   physicalCellDomain_m[i] = totalDomain[i];
 } else {
   orientation[i] = model.centering().orientation(0)[j];
   position(i) = model.centering().position(0)(j);
   guards_m.lower(i) = model.guardLayers().lower(j);
   guards_m.upper(i) = model.guardLayers().upper(j);
   physicalCellDomain_m[i] = model.physicalCellDomain()[j];
   ++j;
 }
      }
    centering_m.addValue(orientation, position);
    addSubFields();
    for (int m = 0; m < numMaterials(); ++m)
    {
      typedef typename NewEngine<typename FE::Engine_t, SliceInterval<Dim, FE::dimensions> >::Type_t NewEngine_t;
      data(m, 0) = Data_t(NewEngine_t(model.data(m, 0).engine(), d, totalDomain),
                          model.data(m, 0).relations());
    }
    mesh_m = Mesh(DomainLayout<Dim>(growRight(physicalCellDomain(), 1),
        guardLayers()));
  }
  unsigned int num_materials_m;
  Centering<Dim> centering_m;
  int stride_m;
  RefCountedBlockPtr<Data_t> data_m;
  Domain_t physicalCellDomain_m;
  GuardLayers_t guards_m;
  Mesh mesh_m;
};
template<class Mesh, class T, class EngineTag, class Tag>
struct LeafFunctor<FieldEngine<Mesh, T, EngineTag>,
                   ExpressionApply<Tag> >
{
  typedef FieldEngine<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Subject_t &fieldEngineBase,
        const ExpressionApply<Tag> &tag)
  {
    for (int m = 0; m < fieldEngineBase.numMaterials(); ++m)
    {
      for (int c = 0; c < fieldEngineBase.centeringSize(); ++ c)
      {
        LeafFunctor_t::apply(fieldEngineBase.data(m, c).engine(), tag);
      }
    }
    return 0;
  }
};
struct CompressibleBrick;
template<class Mesh, class T, class EngineTag>
class Field;
template<class LTag, class EngineTag>
struct MultiPatch;
template<int Dim> struct NoMesh;
struct Brick;
template<class Subject> class SubFieldView;
template<class Subject, class Domain, bool SV>
struct View1Implementation;
template <class Subject, class Domain>
struct ReverseSliceView;
class RelationListItem;
template <int Dim>
class FieldOffset;
template <int Dim>
class FieldOffsetList;
template<class Mesh, class T, class EngineTag,
  class MeshTag2, class T2, class EngineTag2, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const Field<MeshTag2, T2, EngineTag2> &rhs,
       const Op &op);
template<class Mesh, class T, class EngineTag,
 int Dim2, class T2, class EngineTag2, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const Array<Dim2, T2, EngineTag2> &rhs, const Op &op);
template<class Mesh, class T, class EngineTag, class T1, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const T1 &rhs, const Op &op);
template<class Mesh, class T, class EngineTag,
 int Dim2, class T2, class EngineTag2, class Op>
const Array<Dim2, T2, EngineTag2> &
assign(const Array<Dim2, T2, EngineTag2> &lhs,
       const Field<Mesh, T, EngineTag> &rhs, const Op &op);
template<class Mesh, class T, class EngineTag,
 class F, class B, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const WhereProxy<F, B> &rhs,
       const Op &op);
struct SubFieldViewFunctorTag;
template<class Mesh, class T, class EngineTag>
class SubFieldView<Field<Mesh, T, EngineTag> > {
public:
  typedef Field<Mesh, T, EngineTag> Type_t;
  inline static Type_t make(const Type_t &s, int iSubField)
    {
      ;
      return Type_t(s, iSubField);
    }
  inline static Type_t make(const Type_t &s, int m, int c)
  {
    ;
    return Type_t(s, m, c);
  }
  inline static Type_t make(const Type_t &s, int c, const Pooma::CenteringViewTag &tag)
  {
    ;
    return Type_t(s, c, tag);
  }
  inline static Type_t make(const Type_t &s, int m, const Pooma::MaterialViewTag &tag)
  {
    ;
    return Type_t(s, m, tag);
  }
};
template<class Mesh, class T, class Expr>
class SubFieldView<Field<Mesh, T, ExpressionTag<Expr> > > {
public:
  typedef Field<Mesh, T, ExpressionTag<Expr> > Subject_t;
  typedef
    typename ForEach<Expr, SubFieldViewFunctorTag, TreeCombine>::Type_t
      Expr_t;
  typedef Field<Mesh, T, ExpressionTag<Expr_t> > Type_t;
  inline static Type_t make(const Subject_t &s, int iSubField)
    {
      ;
      return Type_t(s, iSubField);
    }
  inline static Type_t make(const Subject_t &s, int m, int c)
  {
    ;
    return Type_t(s, m, c);
  }
  inline static Type_t make(const Subject_t &s, int c, const Pooma::CenteringViewTag &tag)
  {
    ;
    return Type_t(s, c, tag);
  }
  inline static Type_t make(const Subject_t &s, int m, const Pooma::MaterialViewTag &tag)
  {
    ;
    return Type_t(s, m, tag);
  }
};
template<class Mesh, class T, class EngineTag, class Domain>
struct View1Implementation<Field<Mesh, T, EngineTag>, Domain, true>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  template<class S1, class Combine>
  inline static
  Type_t make(const Subject_t &f, const S1 &s1,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1));
      ;
      return f.engine()(s);
    }
  template<class S1, class S2, class Combine>
  inline static
  Type_t make(const Subject_t &f,
       const S1 &s1, const S2 &s2,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1, s2));
      ;
      return f.engine()(s);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  Type_t make(const Subject_t &f,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1, s2, s3));
      ;
      return f.engine()(s);
    }
  template<class S1, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &f, const S1 &s1,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1));
      ;
      return f.engine().read(s);
    }
  template<class S1, class S2, class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &f,
       const S1 &s1, const S2 &s2,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1, s2));
      ;
      return f.engine().read(s);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  ReadType_t makeRead(const Subject_t &f,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const Combine &)
    {
      ;
      Domain s(Combine::make(f, s1, s2, s3));
      ;
      return f.engine().read(s);
    }
};
template<int Dim, class Mesh, class Domain>
struct NewMeshTag
{
  typedef NoMesh<Dim> Type_t;
};
template<int Dim, class Mesh>
struct NewMeshTag<Dim, Mesh, Interval<Dim> >
{
  typedef Mesh Type_t;
};
template<int Dim, class Mesh>
struct NewMeshTag<Dim, Mesh, INode<Dim> >
{
  typedef Mesh Type_t;
};
template<class Mesh, class T, class EngineTag, class Domain>
struct View1Implementation<Field<Mesh, T, EngineTag>, Domain, false>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef typename NewEngine<Engine_t, Domain>::Type_t NewEngine_t;
  typedef typename NewEngine_t::Element_t NewT_t;
  typedef typename NewEngine_t::Tag_t NewEngineTag_t;
  typedef typename
    NewMeshTag<NewEngine_t::dimensions, Mesh, Domain>::Type_t
      NewMeshTag_t;
  typedef Field<NewMeshTag_t, NewT_t, NewEngineTag_t> ReadType_t;
  typedef Field<NewMeshTag_t, NewT_t, NewEngineTag_t> Type_t;
  template<class S1, class Combine>
  static
  Type_t make(const Subject_t &f, const S1 &s1,
       const Combine &)
    {
      Domain s(Combine::make(f, s1));
      ;
      return Type_t(f, s);
    }
  template<class S1, class S2, class Combine>
  static
  Type_t make(const Subject_t &f, const S1 &s1,
       const S2 &s2, const Combine &)
    {
      Domain s(Combine::make(f, s1, s2));
      ;
      return Type_t(f, s);
    }
  template<class S1, class S2, class S3,
    class Combine>
  static
  Type_t make(const Subject_t &f,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const Combine &)
    {
      Domain s(Combine::make(f, s1, s2, s3));
      ;
      return Type_t(f, s);
    }
  template<class S1, class Combine>
  inline static
  Type_t makeRead(const Subject_t &f, const S1 &s1,
       const Combine &c)
    {
      return make(f, s1, c);
    }
  template<class S1, class S2, class Combine>
  inline static
  Type_t makeRead(const Subject_t &f, const S1 &s1,
       const S2 &s2, const Combine &c)
    {
      return make(f, s1, s2, c);
    }
  template<class S1, class S2, class S3,
    class Combine>
  inline static
  Type_t makeRead(const Subject_t &f,
       const S1 &s1, const S2 &s2, const S3 &s3,
       const Combine &c)
    {
      return make(f, s1, s2, s3, c);
    }
};
template<class Mesh, class T, class EngineTag, class Sub1>
struct View1<Field<Mesh, T, EngineTag>, Sub1>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef TemporaryNewDomain1<Domain_t, Sub1> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  typedef typename Dispatch_t::Type_t Type_t;
  inline static
  Type_t make(const Subject_t &f, const Sub1 &s1)
    {
      return Dispatch_t::make(f, s1, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, const Sub1 &s1)
    {
      return Dispatch_t::makeRead(f, s1, Combine_t());
    }
};
template<class Mesh, class T, class EngineTag>
struct View1<Field<Mesh, T, EngineTag>, int>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &f, int s1)
    {
      ;
      ;
      return f.engine()(s1);
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, int s1)
    {
      ;
      ;
      return f.engine().read(s1);
    }
};
template<class Mesh, class T, class EngineTag>
struct View1<Field<Mesh, T, EngineTag>, Loc<Mesh::dimensions> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &f, const Loc<Mesh::dimensions>& s1)
    {
      ;
      return f.engine()(s1);
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, const Loc<Mesh::dimensions>& s1)
    {
      ;
      return f.engine().read(s1);
    }
};
template<class Mesh, class T, class EngineTag,
  class Sub1, class Sub2>
struct View2<Field<Mesh, T, EngineTag>, Sub1, Sub2>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain2<Sub1, Sub2> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  typedef typename Dispatch_t::Type_t Type_t;
  inline static
  Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
    {
      return Dispatch_t::make(f, s1, s2, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
    {
      return Dispatch_t::makeRead(f, s1, s2, Combine_t());
    }
};
template<class Mesh, class T, class EngineTag>
struct View2<Field<Mesh, T, EngineTag>, int, int>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &f, int s1, int s2)
    {
      ;
      ;
      return f.engine()(s1, s2);
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, int s1, int s2)
    {
      ;
      ;
      return f.engine().read(s1, s2);
    }
};
template<class Mesh, class T, class EngineTag, int Dim>
struct View2<Field<Mesh, T, EngineTag>,
             FieldOffset<Dim>,
             Loc<Dim> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  enum { dimensions = Subject_t::dimensions };
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &f,
       const FieldOffset<dimensions> &fo,
       const Loc<dimensions> &loc)
    {
      PoomaCTAssert<(dimensions == Dim)>::test();
      if (f.numSubFields() > 1) {
 ;
 return f[fo.subFieldNumber()].engine()(loc + fo.cellOffset());
      }
      else {
 ;
 return f.engine()(loc + fo.cellOffset());
      }
    }
  inline static
  ReadType_t makeRead(const Subject_t &f,
        const FieldOffset<dimensions> &fo,
        const Loc<dimensions> &loc)
    {
      if (f.numSubFields() > 1) {
 ;
 return f[fo.subFieldNumber()].engine().read(loc + fo.cellOffset());
      }
      else {
 ;
 return f.engine().read(loc + fo.cellOffset());
      }
    }
};
template<class Mesh, class T, class EngineTag,
  class Sub1, class Sub2, class Sub3>
struct View3<Field<Mesh, T, EngineTag>, Sub1, Sub2, Sub3>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Domain_t Domain_t;
  typedef NewDomain3<Sub1, Sub2, Sub3> NewDomain_t;
  typedef typename NewDomain_t::SliceType_t SDomain_t;
  enum { sv = DomainTraits<SDomain_t>::singleValued };
  typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
  typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
  typedef typename Dispatch_t::ReadType_t ReadType_t;
  typedef typename Dispatch_t::Type_t Type_t;
  inline static
  Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3)
    {
      return Dispatch_t::make(f, s1, s2, s3, Combine_t());
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
    const Sub3 &s3)
    {
      return Dispatch_t::makeRead(f, s1, s2, s3, Combine_t());
    }
};
template<class Mesh, class T, class EngineTag>
struct View3<Field<Mesh, T, EngineTag>, int, int, int>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Element_t ReadType_t;
  typedef typename Subject_t::ElementRef_t Type_t;
  inline static
  Type_t make(const Subject_t &f, int s1, int s2, int s3)
    {
      ;
      ;
      return f.engine()(s1, s2, s3);
    }
  inline static
  ReadType_t makeRead(const Subject_t &f, int s1, int s2, int s3)
    {
      ;
      ;
      return f.engine().read(s1, s2, s3);
    }
};
template <int SliceDim, class Mesh, class T, class EngineTag, int Dim>
struct ReverseSliceView<Field<Mesh, T, EngineTag>, SliceInterval<Dim, SliceDim> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef SliceInterval<Dim, SliceDim> Domain_t;
  typedef typename NewEngine<typename Subject_t::Engine_t, Domain_t>::Type_t NewEngine_t;
  typedef Field<NoMesh<Dim>, T, typename NewEngine_t::Tag_t> Type_t;
  inline static
  Type_t make(const Subject_t &a, const SliceInterval<Dim, SliceDim>& dom,
       const Interval<Dim>& totalDom)
  {
    PoomaCTAssert<(Mesh::dimensions == SliceDim)>::test();
    ;
    return Type_t(typename Type_t::FieldEngine_t(a.fieldEngine(), dom, totalDom));
  }
};
template<class Subject> struct Patch;
template<class Mesh, class T, class EngineTag>
struct Patch<Field<Mesh, T, EngineTag> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t OldEngine_t;
  typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
  typedef Field<Mesh, T, typename Engine_t::Tag_t> Type_t;
  enum { dim = OldEngine_t::dimensions };
  inline static
  Type_t make(const Subject_t &f, int i)
  {
    ;
    return Type_t(f, FieldEnginePatch<dim>(i, f.physicalDomain()));
  }
};
template<class Mesh, class T, class LTag, class EngineTag>
struct Patch<Field<Mesh, T, MultiPatch<LTag, EngineTag> > >
{
  typedef Field<Mesh, T, MultiPatch<LTag, EngineTag> > Subject_t;
  typedef typename Subject_t::Engine_t OldEngine_t;
  typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
  typedef Field<Mesh, T, typename Engine_t::Tag_t> Type_t;
  enum { dim = OldEngine_t::dimensions };
  typedef typename OldEngine_t::Layout_t Layout_t;
  typedef typename Layout_t::Value_t Node_t;
  inline static
  Type_t make(const Subject_t &f, int i)
  {
    ;
    Node_t *node = f.engine().layout().nodeListLocal()[i];
    return Type_t(f, FieldEnginePatch<dim>(i, intersect(f.physicalDomain(),
                                                        node->domain())));
  }
};
template<class Components, class Subject> struct ComponentView;
template<class Components, class Mesh, class T, class EngineTag>
struct ComponentView<Components, Field<Mesh, T, EngineTag> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef Engine<Mesh::dimensions, T, EngineTag> Engine_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename ComponentAccess<Element_t, Components>::Element_t NewT_t;
  typedef CompFwd<Engine_t, Components> NewEngineTag_t;
  typedef Field<Mesh, NewT_t, NewEngineTag_t> Type_t;
  inline static
  Type_t make(const Subject_t &f, const Components &c)
    {
      return Type_t(f, ComponentWrapper<Components>(c));
    }
};
template<class Mesh,
         class T = double,
         class EngineTag = Brick>
class Field {
public:
  typedef Mesh MeshTag_t;
  typedef Mesh Mesh_t;
  typedef T T_t;
  typedef EngineTag EngineTag_t;
  typedef Field<Mesh, T, EngineTag> This_t;
  typedef FieldEngine<Mesh, T, EngineTag> FieldEngine_t;
  enum { dimensions = FieldEngine_t::dimensions };
  enum { coordinateDimensions = MeshTag_t::coordinateDimensions };
  typedef Engine<dimensions, T, EngineTag> Engine_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef typename Engine_t::Layout_t Layout_t;
  typedef typename Engine_t::Domain_t Domain_t;
  typedef Centering<dimensions> Centering_t;
  enum { hasRelations = true };
  Field()
  : fieldEngine_m()
    { }
  template<class I1>
  explicit Field(const I1 &i1)
    : fieldEngine_m(i1)
  { }
  template<class Layout2>
  Field(const Centering_t &centering, const Layout2 &layout, const Mesh_t &mesh)
    : fieldEngine_m(centering, layout, mesh)
  { }
  template<class Layout2>
  Field(int materials, const Centering_t &centering, const Layout2 &layout, const Mesh_t &mesh)
    : fieldEngine_m(centering, layout, mesh, materials)
  { }
  template<class I1, class I2>
  Field(const Centering_t &centering, const Layout_t &layout, const I1 &i1, const I2 &i2)
    : fieldEngine_m(centering, layout, Mesh_t(layout, i1, i2))
  { }
  Field(const Centering_t &centering, const Layout_t &layout)
    : fieldEngine_m(centering, layout, Mesh_t(layout))
  { }
  template<class I1, class I2>
  Field(int materials, const Centering_t &centering, const Layout_t &layout,
        const I1 &i1, const I2 &i2)
    : fieldEngine_m(centering, layout, Mesh_t(layout, i1, i2), materials)
  { }
  Field(const This_t &model)
  : fieldEngine_m(model.fieldEngine())
  { }
  void initialize(const This_t &model)
  {
    fieldEngine_m = model.fieldEngine();
  }
  template<class Layout2>
  void
  initialize(const Centering_t &centering, const Layout2 &layout,
             const Mesh_t &mesh)
  {
    fieldEngine_m = FieldEngine_t(centering, layout, mesh);
  }
  template<class Layout2>
  void
  initialize(int materials, const Centering_t &centering,
             const Layout2 &layout, const Mesh_t &mesh)
  {
    fieldEngine_m = FieldEngine_t(centering, layout, mesh, materials);
  }
  void
  initialize(const Centering_t &centering, const Layout_t &layout)
  {
    fieldEngine_m = FieldEngine_t(centering, layout, Mesh_t(layout));
  }
  template<class GT2, class T2, class ET2, class Initializer>
  Field(const Field<GT2, T2, ET2> &model, const Initializer &i)
  : fieldEngine_m(model.fieldEngine(), i)
  { }
  template<class ET2>
  Field(const Field<Mesh, T, ET2> &model, int m, int c)
    : fieldEngine_m(model.fieldEngine(), m, c)
  { }
  template<class ET2>
  Field(const Field<Mesh, T, ET2> &model, int c, const Pooma::CenteringViewTag &tag)
    : fieldEngine_m(model.fieldEngine(), c, tag)
  { }
  template<class ET2>
  Field(const Field<Mesh, T, ET2> &model, int m, const Pooma::MaterialViewTag &tag)
    : fieldEngine_m(model.fieldEngine(), m, tag)
  { }
  ~Field() { }
  inline const Engine_t &engine() const
    {
      return fieldEngine_m.engine();
    }
  inline Engine_t &engine()
    {
      return fieldEngine_m.engine();
    }
  inline const FieldEngine_t &fieldEngine() const
    {
      return fieldEngine_m;
    }
  inline FieldEngine_t &fieldEngine()
    {
      return fieldEngine_m;
    }
  inline int numSubFields() const
    {
      return fieldEngine_m.numSubFields();
    }
  const Centering<dimensions> &centering() const
  {
    return fieldEngine().centering();
  }
  const Centering<dimensions> centering(int c) const
  {
    return fieldEngine().centering()[c];
  }
  inline int centeringSize() const
  {
    return fieldEngine().centeringSize();
  }
  inline int numMaterials() const
    {
      return fieldEngine().numMaterials();
    }
  inline const Domain_t& physicalCellDomain() const
    {
      return fieldEngine_m.physicalCellDomain();
    }
  inline Domain_t totalCellDomain() const
    {
      return fieldEngine_m.totalCellDomain();
    }
  Domain_t physicalDomain(int iSubfield) const
    {
      return fieldEngine_m.physicalDomain(iSubfield);
    }
  Domain_t totalDomain(int iSubfield) const
    {
      return fieldEngine_m.totalDomain(iSubfield);
    }
  Domain_t physicalDomain() const
    {
      return fieldEngine_m.physicalDomain();
    }
  Domain_t totalDomain() const
    {
      return fieldEngine_m.totalDomain();
    }
  Domain_t domain() const
    {
      return fieldEngine_m.physicalDomain();
    }
  inline
  const Mesh_t &mesh() const
  {
    return fieldEngine_m.mesh();
  }
  inline Layout_t layout() const
  {
    return fieldEngine_m.engine(0, 0).layout();
  }
  void makeOwnCopy()
  {
    fieldEngine_m.makeOwnCopy(*this);
  }
  inline typename SubFieldView<This_t>::Type_t
  operator[](int iSubfield) const
    {
      typedef SubFieldView<This_t> Ret_t;
      return Ret_t::make(*this, iSubfield);
    }
  inline typename SubFieldView<This_t>::Type_t
  subField(int m, int c) const
  {
    typedef SubFieldView<This_t> Ret_t;
    return Ret_t::make(*this, m, c);
  }
  inline typename SubFieldView<This_t>::Type_t
  center(int c) const
  {
    typedef SubFieldView<This_t> Ret_t;
    return Ret_t::make(*this, c, Pooma::CenteringViewTag());
  }
  inline typename SubFieldView<This_t>::Type_t
  material(int m) const
  {
    ;
    typedef SubFieldView<This_t> Ret_t;
    return Ret_t::make(*this, m, Pooma::MaterialViewTag());
  }
  inline typename View1<This_t, Domain_t>::ReadType_t
  read() const
    {
      typedef View1<This_t, Domain_t> Ret_t;
      return Ret_t::makeRead(*this, physicalDomain());
    }
  inline typename View1<This_t, Domain_t>::ReadType_t
  readAll() const
    {
      typedef View1<This_t, Domain_t> Ret_t;
      return Ret_t::makeRead(*this, totalDomain());
    }
  template<class Sub1>
  inline typename View1<This_t, Sub1>::ReadType_t
  read(const Sub1 &s1) const
    {
      typedef View1<This_t, Sub1> Ret_t;
      return Ret_t::makeRead(*this, s1);
    }
  template<class Sub1, class Sub2>
  inline typename View2<This_t, Sub1, Sub2>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2) const
    {
      typedef View2<This_t, Sub1, Sub2> Ret_t;
      return Ret_t::makeRead(*this, s1, s2);
    }
  template<class Sub1, class Sub2, class Sub3>
  inline typename View3<This_t, Sub1, Sub2, Sub3>::ReadType_t
  read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
    {
      typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
      return Ret_t::makeRead(*this, s1, s2, s3);
    }
  inline typename View1<This_t, Domain_t>::Type_t
  operator()() const
    {
      typedef View1<This_t, Domain_t> Ret_t;
      return Ret_t::make(*this, physicalDomain());
    }
  inline typename View1<This_t, Domain_t>::Type_t
  all() const
    {
      typedef View1<This_t, Domain_t> Ret_t;
      return Ret_t::make(*this, totalDomain());
    }
  template<class Sub1>
  inline typename View1<This_t, Sub1>::Type_t
  operator()(const Sub1 &s1) const
    {
      typedef View1<This_t, Sub1> Ret_t;
      return Ret_t::make(*this, s1);
    }
  template<class Sub1, class Sub2>
  inline typename View2<This_t, Sub1, Sub2>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2) const
    {
      typedef View2<This_t, Sub1, Sub2> Ret_t;
      return Ret_t::make(*this, s1, s2);
    }
  template<class Sub1, class Sub2, class Sub3>
  inline typename View3<This_t, Sub1, Sub2, Sub3>::Type_t
  operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
    {
      typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
      return Ret_t::make(*this, s1, s2, s3);
    }
  inline typename ComponentView<Loc<1>, This_t>::Type_t
  comp(int i1) const
  {
    return ComponentView<Loc<1>, This_t>::make(*this, Loc<1>(i1));
  }
  inline typename ComponentView<Loc<2>, This_t>::Type_t
  comp(int i1, int i2) const
  {
    return ComponentView<Loc<2>, This_t>::make(*this, Loc<2>(i1, i2));
  }
  template<class Components>
  inline typename ComponentView<Components, This_t>::Type_t
  comp(const Components &loc) const
  {
    return ComponentView<Components, This_t>::make(*this, loc);
  }
  inline typename Patch<This_t>::Type_t
  patchLocal(EnginePatch::PatchID_t i) const
    {
      return Patch<This_t>::make(*this, i);
    }
  inline int
  numPatchesLocal() const
  {
    return engineFunctor(engine(), EngineNumPatches());
  }
  This_t &operator=(const This_t &rhs)
    {
      assign(*this, rhs, OpAssign());
      return *this;
    }
  const This_t &operator=(const This_t &rhs) const
    {
      return assign(*this, rhs, OpAssign());
    }
  template<class T1>
  const This_t &operator=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpAssign());
    }
  template<class T1>
  const This_t &operator+=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpAddAssign());
    }
  template<class T1>
  const This_t &operator-=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpSubtractAssign());
    }
  template<class T1>
  const This_t &operator*=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpMultiplyAssign());
    }
  template<class T1>
  const This_t &operator/=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpDivideAssign());
    }
  template<class T1>
  const This_t &operator%=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpModAssign());
    }
  template<class T1>
  const This_t &operator|=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseOrAssign());
    }
  template<class T1>
  const This_t &operator&=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseAndAssign());
    }
  template<class T1>
  const This_t &operator^=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpBitwiseXorAssign());
    }
  template<class T1>
  const This_t &operator<<=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpLeftShiftAssign());
    }
  template<class T1>
  const This_t &operator>>=(const T1 &rhs) const
    {
      return assign(*this, rhs, OpRightShiftAssign());
    }
  void addRelation(RelationListItem *item) const
  {
    ;
    fieldEngine_m.relations().addRelation(item);
  }
  void removeRelations()
  {
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering().size(); ++ c)
      {
        fieldEngine_m.data(m, c).relations().erase();
      }
    }
  }
  void applyRelations(bool makeDirty = false) const
  {
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering().size(); ++ c)
      {
        if (makeDirty)
          fieldEngine_m.data(m, c).relations().setDirty();
        fieldEngine_m.data(m, c).relations().notifyPreRead();
      }
    }
  }
  void notifyPreRead() const
  {
    for (int m = 0; m < numMaterials(); ++m)
      for (int c = 0; c < centering().size(); ++c)
        fieldEngine_m.data(m, c).relations().notifyPreRead();
  }
  void notifyPostWrite() const
  {
    for (int m = 0; m < numMaterials(); ++m)
      for (int c = 0; c < centering().size(); ++c)
        fieldEngine_m.data(m, c).relations().notifyPostWrite();
  }
  void setDirty() const
  {
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering().size(); ++ c)
      {
        fieldEngine_m.data(m, c).relations().setDirty();
      }
    }
  }
  void clearDirty() const
  {
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering().size(); ++ c)
      {
        fieldEngine_m.data(m, c).relations().clearDirty();
      }
    }
  }
  bool isDirty() const
  {
    for (int m = 0; m < numMaterials(); ++m)
    {
      for (int c = 0; c < centering().size(); ++ c)
      {
        if (fieldEngine_m.data(m, c).relations().dirty())
   return true;
      }
    }
    return false;
  }
private:
  FieldEngine_t fieldEngine_m;
};
template<class Op>
struct AssignOpReadWriteTraits
{
  enum { readLHS = true };
};
template<>
struct AssignOpReadWriteTraits<OpAssign>
{
  enum { readLHS = false };
};
template<class Mesh, class T, class EngineTag, int Dim>
struct LeafFunctor<Field<Mesh, T, EngineTag>, ConformTag<Dim> >
{
  typedef bool Type_t;
  static Type_t apply1(const Interval<Dim> &d,
    const ConformTag<Dim> &ct)
    {
      return conforms(d, ct);
    }
  template<int Dim2>
  static Type_t apply1(const Interval<Dim2> &d,
    const ConformTag<Dim> &ct)
    {
      return false;
    }
  static Type_t apply(const Field<Mesh, T, EngineTag> &f,
    const ConformTag<Dim> &ct)
    {
      return apply1(f.physicalDomain(), ct);
    }
};
template<class Mesh, class T, class EngineTag, class RequestType>
struct LeafFunctor<Field<Mesh, T, EngineTag>,
  DataObjectRequest<RequestType> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::FieldEngine_t FieldEngine_t;
  typedef LeafFunctor<FieldEngine_t, DataObjectRequest<RequestType> >
    LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t Type_t;
  enum { dataObject = LeafFunctor_t::dataObject };
  inline static
  Type_t apply(const Subject_t &f,
            const DataObjectRequest<RequestType> &functor)
    {
      return LeafFunctor_t::apply(f.fieldEngine(), functor);
    }
};
template<class Mesh, class T, class EngineTag, class RequestType>
struct LeafFunctor<FieldEngine<Mesh, T, EngineTag>,
  DataObjectRequest<RequestType> >
{
  typedef typename FieldEngine<Mesh, T, EngineTag>::Engine_t
    Engine_t;
  enum { dataObject = Engine_t::dataObject };
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  inline static
  Type_t apply(const FieldEngine<Mesh, T, EngineTag> &f,
            const DataObjectRequest<RequestType> &functor)
    {
      return DataObjectApply<dataObject>::apply(f.engine(), functor);
    }
};
template<class Mesh, class T, class EngineTag>
struct LeafFunctor<Field<Mesh, T, EngineTag>, DomainFunctorTag>
{
  typedef typename Field<Mesh, T, EngineTag>::Domain_t Type_t;
  inline static Type_t apply(const Field<Mesh, T, EngineTag> &f,
    const DomainFunctorTag &)
    {
      return f.physicalDomain() - f.physicalDomain().firsts();
    }
};
template<class Mesh, class T, class EngineTag, class Tag>
struct LeafFunctor<Field<Mesh, T, EngineTag>, ExpressionApply<Tag> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::FieldEngine_t FieldEngine_t;
  typedef LeafFunctor<FieldEngine_t, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Subject_t &field,
        const ExpressionApply<Tag> &tag)
    {
      return LeafFunctor_t::apply(field.fieldEngine(), tag);
    }
};
template<class Mesh, class T, class EngineTag, class Tag>
struct LeafFunctor<Field<Mesh, T, EngineTag>, EngineView<Tag> >
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef typename LeafFunctor<Engine_t, EngineView<Tag> >::Type_t NewEngine_t;
  typedef typename NewEngine_t::Tag_t NewEngineTag_t;
  typedef Field<Mesh, T, NewEngineTag_t> Type_t;
  inline static
  Type_t apply(const Subject_t &field,
        const EngineView<Tag> &tag)
  {
    return Type_t(field, tag);
  }
};
template<class Mesh, class T, class EngineTag, class Tag>
struct LeafFunctor<Field<Mesh, T, EngineTag>, EngineFunctorTag<Tag> >
{
  typedef typename Field<Mesh,T,EngineTag>::Engine_t Engine_t;
  typedef typename EngineFunctor<Engine_t,Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Field<Mesh, T, EngineTag> &field,
        const EngineFunctorTag<Tag> &tag)
  {
    return EngineFunctor<Engine_t,Tag>::apply(field.engine(), tag.tag());
  }
};
template<class Mesh, class T, class EngineTag, class Tag>
struct EngineFunctor<Field<Mesh, T, EngineTag>, Tag>
{
  typedef typename Field<Mesh, T, EngineTag>::Engine_t Engine_t;
  typedef typename EngineFunctor<Engine_t, Tag>::Type_t Type_t;
  inline static
  Type_t apply(const Field<Mesh, T, EngineTag> &field,
            const Tag &tag)
    {
      return engineFunctor(field.engine(), tag);
    }
};
template<class Mesh, class T, class EngineTag, int Dim>
struct LeafFunctor<Field<Mesh, T, EngineTag>, EvalLeaf<Dim> >
{
  typedef typename Field<Mesh, T, EngineTag>::Element_t Type_t;
  inline static
  Type_t apply(const Field<Mesh, T, EngineTag> &f,
    const EvalLeaf<Dim> &t)
    {
      return t.eval(f.engine());
    }
};
template<class Mesh, class T, class EngineTag>
struct LeafFunctor<Field<Mesh, T, EngineTag>,
  PerformUpdateTag>
{
  typedef Field<Mesh, T, EngineTag> Subject_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Subject_t &f, const PerformUpdateTag &)
    {
      f.notifyPreRead();
      return 0;
    }
};
template<class Mesh, class T, class Expr>
struct LeafFunctor<Field<Mesh, T, ExpressionTag<Expr> >,
  PerformUpdateTag>
{
  typedef Field<Mesh, T, ExpressionTag<Expr> > Subject_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Subject_t &f, const PerformUpdateTag &tag)
    {
      forEach(f.engine().expression(), tag, NullCombine());
      return 0;
    }
};
template<class Mesh, class T, class EngineTag>
struct LeafFunctor<Field<Mesh, T, EngineTag>, SubFieldViewFunctorTag>
{
  typedef Field<Mesh, T, EngineTag> Type_t;
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, SubFieldViewFunctorTag>
{
  typedef Array<Dim, T, EngineTag> Type_t;
};
template<class T>
struct LeafFunctor<Scalar<T>, SubFieldViewFunctorTag>
{
  typedef Scalar<T> Type_t;
};
template<class Mesh, class T, class EngineTag, class Domain>
struct LeafFunctor<Field<Mesh, T, EngineTag>, ViewFunctorTag<Domain> >
{
  typedef typename View1<Field<Mesh, T, EngineTag>, Domain>::Type_t
    Type_t;
};
template <class Mesh, class T, class EngineTag>
std::ostream &operator<<(std::ostream &o,
  const Field<Mesh, T, EngineTag> &cf)
{
  Pooma::blockAndEvaluate();
  PrintField().print(o, cf);
  return o;
}
template <class Mesh, class T, class EngineTag>
std::fstream &operator<<(std::fstream &f,
  const Field<Mesh, T, EngineTag> &cf)
{
  Pooma::blockAndEvaluate();
  PrintField().print(f, cf);
  return f;
}
struct ExpressionIsField { };
template<class Mesh, class T, class EngineTag>
struct ExpressionTraits<Field<Mesh, T, EngineTag> >
{
  typedef ExpressionIsField Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsField, ExpressionIsField>
{
  typedef ExpressionIsField Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsField, ExpressionIsScalar>
{
  typedef ExpressionIsField Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsField>
{
  typedef ExpressionIsField Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsField, ExpressionIsArray>
{
  typedef ExpressionIsField Type_t;
};
template<>
struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsField>
{
  typedef ExpressionIsField Type_t;
};
template<class Mesh, class T, class EngineTag,
 int Dim2, class T2, class EngineTag2, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const Array<Dim2, T2, EngineTag2> &rhs, const Op &op)
{
  for (int m = 0; m < lhs.numMaterials(); ++m)
    {
      for (int c = 0; c < lhs.centeringSize(); ++c)
        {
          const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
          if (AssignOpReadWriteTraits<Op>::readLHS)
            l.notifyPreRead();
          Evaluator<MainEvaluatorTag>().evaluate(l, op, rhs);
          l.notifyPostWrite();
        }
    }
  return lhs;
}
template<class Mesh, class T, class EngineTag,
  class Mesh2, class T2, class EngineTag2, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const Field<Mesh2, T2, EngineTag2> &rhs,
       const Op &op)
{
  ;
  for (int m = 0; m < lhs.numMaterials(); ++m)
    {
      for (int c = 0; c < lhs.centeringSize(); ++c)
        {
          const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
          const typename SubFieldView<Field<Mesh2, T2, EngineTag2> >::Type_t &r =
            rhs.subField(m, c);
          forEach(r, PerformUpdateTag(), NullCombine());
          if (AssignOpReadWriteTraits<Op>::readLHS)
            l.notifyPreRead();
          Evaluator<MainEvaluatorTag>().evaluate(l, op, r);
          l.notifyPostWrite();
        }
    }
  return lhs;
}
template<class Mesh, class T, class EngineTag, class T1, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs, const T1 &rhs,
       const Op &op)
{
  for (int m = 0; m < lhs.numMaterials(); ++m)
    {
      for (int c = 0; c < lhs.centeringSize(); ++c)
        {
          const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
          if (AssignOpReadWriteTraits<Op>::readLHS)
            l.notifyPreRead();
          typedef Field<Mesh, T, EngineTag> LHS_t;
          Array<LHS_t::dimensions, T1, ConstantFunction> rhsExpr(l.physicalDomain());
          rhsExpr.engine().setConstant(rhs);
          Evaluator<MainEvaluatorTag>().evaluate(l, op, rhsExpr);
          l.notifyPostWrite();
        }
    }
  return lhs;
}
template<class Mesh, class T, class EngineTag,
 int Dim2, class T2, class EngineTag2, class Op>
const Array<Dim2, T2, EngineTag2> &
assign(const Array<Dim2, T2, EngineTag2> &lhs,
       const Field<Mesh, T, EngineTag> &rhs, const Op &op)
{
  ;
  forEach(rhs, PerformUpdateTag(), NullCombine());
  Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhs);
  return lhs;
}
template<class Tree>
struct ConvertWhereProxy<ExpressionIsField, Tree>
{
  typedef MakeFieldReturn<Tree> Make_t;
};
template<class Mesh, class T, class EngineTag,
 class F, class B, class Op>
const Field<Mesh, T, EngineTag> &
assign(const Field<Mesh, T, EngineTag> &lhs,
       const WhereProxy<F, B> &rhs, const Op &op)
{
  assign(lhs, rhs.whereMask(), rhs.opMask(op));
  return lhs;
}
template<class Mesh, class T, class EngineTag>
inline bool compressed(const Field<Mesh, T, EngineTag> &f)
{
  ;
  return compressed(f.engine());
}
template<class Mesh, class T, class EngineTag>
inline long elementsCompressed(const Field<Mesh, T, EngineTag> &f)
{
  ;
  return elementsCompressed(f.engine());
}
template<class Mesh, class T, class LTag>
void
compress(Field<Mesh, T, MultiPatch<LTag,CompressibleBrick> > &f)
{
  for (int m = 0; m < f.numMaterials(); ++m)
  {
    for (int c = 0; c < f.centeringSize(); ++c)
    {
      compress(f.fieldEngine().data(m, c).engine());
    }
  }
}
template<class Mesh, class T, class LTag>
void
uncompress(Field<Mesh, T, MultiPatch<LTag,CompressibleBrick> > &f)
{
  for (int m = 0; m < f.numMaterials(); ++m)
  {
    for (int c = 0; c < f.centeringSize(); ++c)
    {
      uncompress(f.fieldEngine().data(m, c).engine());
    }
  }
}
template<int Dim, class T, class EngineTag>
inline int numMaterials(const Array<Dim, T, EngineTag> &a)
{
  return 1;
}
template<class Mesh, class T, class EngineTag>
inline int numMaterials(const Field<Mesh, T, EngineTag> &f)
{
  return f.numMaterials();
}
template<int Dim, class T, class EngineTag>
inline int centeringSize(const Array<Dim, T, EngineTag> &a)
{
  return 1;
}
template<class Mesh, class T, class EngineTag>
inline int centeringSize(const Field<Mesh, T, EngineTag> &f)
{
  return f.centeringSize();
}
template<int Dim, class T, class EngineTag>
inline Array<Dim, T, EngineTag> &subField(Array<Dim, T, EngineTag> &a, int, int)
{
  return a;
}
template<class Mesh, class T, class EngineTag>
inline typename SubFieldView<Field<Mesh, T, EngineTag> >::Type_t
subField(Field<Mesh, T, EngineTag> &f, int m, int c)
{
  return f.subField(m, c);
}
template<class Mesh, class T, class EngineTag> class Field;
struct FarLeftTag
{
 
};
template<class G1, class T1, class E1, class Op>
struct Combine1<Field<G1, T1, E1>, Op, FarLeftTag>
{
  typedef Field<G1, T1, E1> Type_t;
  inline static
  const Type_t &combine(const Field<G1, T1, E1> &a,
   const FarLeftTag &)
    {
      return a;
    }
};
template<class G1, class T1, class E1, class G2, class T2, class E2,
  class Op>
struct Combine2<Field<G1, T1, E1>, Field<G2, T2, E2>, Op, FarLeftTag>
{
  typedef Field<G1, T1, E1> Type_t;
  inline static
  const Type_t &combine(const Field<G1, T1, E1> &a,
                        const Field<G2, T2, E2> &, FarLeftTag)
    {
      return a;
    }
};
template<class T, class G2, class T2, class E2, class Op>
struct Combine2<T, Field<G2, T2, E2>, Op, FarLeftTag>
{
  typedef Field<G2, T2, E2> Type_t;
  inline static
  const Type_t &combine(const T &,
                        const Field<G2, T2, E2> &b, FarLeftTag)
    {
      return b;
    }
};
template<class G1, class T1, class E1, class T, class Op>
struct Combine2<Field<G1, T1, E1>, T, Op, FarLeftTag>
{
  typedef Field<G1, T1, E1> Type_t;
  inline static
  const Type_t &combine(const Field<G1, T1, E1> &a,
                        const T &, FarLeftTag)
    {
      return a;
    }
};
template<class T, class Op>
struct Combine2<ErrorType, T, Op, FarLeftTag>
{
  typedef T Type_t;
  inline static
  const Type_t &combine(const ErrorType& e, const T& t,
          FarLeftTag)
  {
    return t;
  }
};
template<class T, class Op>
struct Combine2<T, ErrorType, Op, FarLeftTag>
{
  typedef T Type_t;
  inline static
  const Type_t &combine(const T& t, const ErrorType& e,
          FarLeftTag)
  {
    return t;
  }
};
template<class A,class B,class C,class Op>
struct Combine3<A, B, C, Op, FarLeftTag>
{
  typedef typename Combine2<A, B, Op, FarLeftTag>::Type_t Type1_t;
  typedef typename Combine2<Type1_t, C, Op, FarLeftTag>::Type_t Type_t;
  inline static
  const Type_t &combine(const A& a, const B& b, const C& c,
   const FarLeftTag& t)
  {
    return
      Combine2<Type1_t, C,
      Op, FarLeftTag>::combine(Combine2<A, B, Op,
          FarLeftTag>::combine(a, b, t), c, t);
  }
};
template<class GeometryTag, class T, class EngineTag>
struct LeafFunctor<Field<GeometryTag, T, EngineTag>, FarLeftTag>
{
  typedef Field<GeometryTag, T, EngineTag> Type_t;
  inline static
  const Type_t &apply(const Field<GeometryTag, T, EngineTag> &f,
    const FarLeftTag &)
    {
      return f;
    }
};
template<int Dim, class T, class EngineTag>
struct LeafFunctor<Array<Dim, T, EngineTag>, FarLeftTag>
{
  typedef ErrorType Type_t;
  inline static
  const Type_t &apply(const Array<Dim, T, EngineTag> &a,
    const FarLeftTag &)
    {
      return Type_t();
    }
};
template<class T>
struct LeafFunctor<Scalar<T>, FarLeftTag>
{
  typedef Scalar<T> Type_t;
  inline static
  const Type_t &apply(const Scalar<T> &s, const FarLeftTag &)
    {
      return s;
    }
};
template<class Mesh, class T, class Expr>
class FieldEngine<Mesh, T, ExpressionTag<Expr> >
{
public:
  enum { dimensions = Mesh::dimensions };
  enum { Dim = dimensions };
  typedef ExpressionTag<Expr> EngineTag_t;
  typedef FieldEngine<Mesh, T, EngineTag_t> This_t;
  typedef Engine<Dim, T, EngineTag_t> Engine_t;
  typedef typename Engine_t::Domain_t Domain_t;
  typedef typename Engine_t::Layout_t Layout_t;
  typedef typename Engine_t::Element_t Element_t;
  typedef typename Engine_t::ElementRef_t ElementRef_t;
  typedef GuardLayers<Dim> GuardLayers_t;
  typedef typename ForEach<Expr, FarLeftTag, FarLeftTag>::Type_t
    ReferenceField_t;
  FieldEngine(const Engine_t &e)
  : engine_m(e),
    referenceField_m(
      forEachRef(engine_m.expression(), FarLeftTag(), FarLeftTag()))
    { }
  template<class Expr2, class Domain>
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model,
    const Domain &d)
  : engine_m(NewEngineEngine<Engine<Dim, T, ExpressionTag<Expr2> >, Domain>::apply(model.engine(), d),
      NewEngineDomain<Engine<Dim, T, ExpressionTag<Expr2> >, Domain>::apply(model.engine(), d)
      ),
    referenceField_m(
      forEachRef(engine_m.expression(), FarLeftTag(), FarLeftTag()))
    { }
  template<class Expr2>
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int m, int c)
    : engine_m(Expr(model.engine().expression(), m, c)),
      referenceField_m(forEachRef(engine_m.expression(),
                                  FarLeftTag(), FarLeftTag()))
  { }
  template<class Expr2>
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int m,
       const Pooma::MaterialViewTag& tag)
    : engine_m(Expr(model.engine().expression(), m, tag)),
      referenceField_m(forEachRef(engine_m.expression(),
                                  FarLeftTag(), FarLeftTag()))
  { }
  template<class Expr2>
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int c,
       const Pooma::CenteringViewTag& tag)
    : engine_m(Expr(model.engine().expression(), c, tag)),
      referenceField_m(forEachRef(engine_m.expression(),
                                  FarLeftTag(), FarLeftTag()))
  { }
  template<class Expr2>
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int iSubField)
    : engine_m(Expr(model.engine().expression, iSubField)),
      referenceField_m(forEachRef(engine_m.expression(),
                                  FarLeftTag(), FarLeftTag()))
  { }
  FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr> > &other)
  : engine_m(other.engine()),
    referenceField_m(forEachRef(engine_m.expression(),
    FarLeftTag(), FarLeftTag()))
  { }
  int numSubFields() const
    {
      return referenceField().numSubFields();
    }
  const Engine_t &engine() const
    {
      return engine_m;
    }
  Engine_t &engine()
    {
      return engine_m;
    }
  const ReferenceField_t &referenceField() const
  {
    return referenceField_m;
  }
  const Domain_t &physicalCellDomain() const
    {
      return referenceField().physicalCellDomain();
    }
  Domain_t totalCellDomain() const
    {
      return referenceField().totalCellDomain();
    }
  Domain_t physicalDomain() const
    {
      return referenceField().physicalDomain();
    }
  Domain_t totalDomain() const
    {
      return referenceField().totalDomain();
    }
  Domain_t physicalDomain(int iSubField) const
    {
      return referenceField().physicalDomain(iSubField);
    }
  Domain_t totalDomain(int iSubField) const
    {
      return referenceField().totalDomain(iSubField);
    }
  const Centering<Dim> &centering() const
  {
    return referenceField().centering();
  }
  int centeringSize() const
    {
      return referenceField().centeringSize();
    }
  int numMaterials() const
    {
      return referenceField().numMaterials();
    }
  Mesh &mesh()
  {
    return referenceField().mesh();
  }
  const Mesh &mesh() const
  {
    return referenceField().mesh();
  }
private:
  This_t &operator=(const This_t &other);
  Engine_t engine_m;
  const ReferenceField_t &referenceField_m;
};
template<class Mesh, class T, class Expr, class Tag>
struct LeafFunctor<FieldEngine<Mesh, T, ExpressionTag<Expr> >,
  ExpressionApply<Tag> >
{
  typedef FieldEngine<Mesh, T, ExpressionTag<Expr> > Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  inline static
  Type_t apply(const Subject_t &fieldEngineBase,
        const ExpressionApply<Tag> &tag)
  {
    LeafFunctor_t::apply(fieldEngineBase.engine(), tag);
    return 0;
  }
};
struct RectilinearTag {};
struct UniformRectilinearTag {};
struct CartesianTag {
  enum { x = 0, y = 1, z = 2 };
};
struct CylindricalTag {
  enum { r = 0, z = 1, phi = 2 };
};
struct SphericalTag {
  enum { r = 0, theta = 1, phi = 2};
};
template<class MeshTraits> struct CartesianRM;
template<class MeshTraits> struct CartesianURM;
template<class MeshTraits> struct CylindricalRM;
template<class MeshTraits> struct CylindricalURM;
template<class MeshTraits> struct SphericalRM;
template<class MeshTraits> struct SphericalURM;
template<class MeshTraits> class RectilinearMeshData;
template<class MeshTraits> class RectilinearMesh;
template<class MeshTraits> class UniformRectilinearMeshData;
template<class MeshTraits> class UniformRectilinearMesh;
template <int Dim, typename T = double, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag, int CDim = Dim>
struct MeshTraits;
template <int Dim, typename T, class MeshTag, class CoordinateSystemTag, int CDim>
struct MeshTraitsBase
{
  typedef MeshTraits<Dim, T, MeshTag, CoordinateSystemTag, CDim> MeshTraits_t;
  typedef MeshTag MeshTag_t;
  typedef CoordinateSystemTag CoordinateSystemTag_t;
  typedef T T_t;
  enum { dimensions = Dim };
  enum { coordinateDimensions = CDim };
  typedef T Scalar_t;
  typedef Loc<Dim> Loc_t;
  typedef Interval<Dim> Domain_t;
  typedef Vector<CDim, T> PointType_t;
  typedef Vector<CDim, T> VectorType_t;
  typedef Vector<CDim, int> CIndexType_t;
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, RectilinearTag, CartesianTag, CDim>
  : MeshTraitsBase<Dim, T, RectilinearTag, CartesianTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, RectilinearTag, CartesianTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef CartesianRM<MeshTraits_t> CoordinateSystem_t;
  typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef RectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Array<1, T, Brick> SpacingsType_t[CDim];
  typedef Array<1, T, Brick> PositionsType_t[CDim];
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, UniformRectilinearTag, CartesianTag, CDim>
  : public MeshTraitsBase<Dim, T, UniformRectilinearTag, CartesianTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, CartesianTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef CartesianURM<MeshTraits_t> CoordinateSystem_t;
  typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Vector<CDim, T> SpacingsType_t;
  typedef Vector<CDim, T> PositionsType_t;
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, RectilinearTag, CylindricalTag, CDim>
  : public MeshTraitsBase<Dim, T, RectilinearTag, CylindricalTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, RectilinearTag, CylindricalTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef CylindricalRM<MeshTraits_t> CoordinateSystem_t;
  typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef RectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Array<1, T, Brick> SpacingsType_t[CDim];
  typedef Array<1, T, Brick> PositionsType_t[CDim];
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>
  : public MeshTraitsBase<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef CylindricalURM<MeshTraits_t> CoordinateSystem_t;
  typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Vector<CDim, T> SpacingsType_t;
  typedef Vector<CDim, T> PositionsType_t;
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, RectilinearTag, SphericalTag, CDim>
  : MeshTraitsBase<Dim, T, RectilinearTag, SphericalTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, RectilinearTag, SphericalTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef SphericalRM<MeshTraits_t> CoordinateSystem_t;
  typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef RectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Array<1, T, Brick> SpacingsType_t[CDim];
  typedef Array<1, T, Brick> PositionsType_t[CDim];
};
template <int Dim, typename T, int CDim>
struct MeshTraits<Dim, T, UniformRectilinearTag, SphericalTag, CDim>
  : MeshTraitsBase<Dim, T, UniformRectilinearTag, SphericalTag, CDim>
{
  typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, SphericalTag, CDim>::MeshTraits_t MeshTraits_t;
  typedef SphericalURM<MeshTraits_t> CoordinateSystem_t;
  typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
  typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
  typedef Vector<CDim, T> SpacingsType_t;
  typedef Vector<CDim, T> PositionsType_t;
};
template <int Dim>
class NoMeshData : public RefCounted
{
public:
  NoMeshData()
    {
    }
  template<class Layout>
  explicit NoMeshData(const Layout &layout)
  : physicalVertexDomain_m(layout.innerDomain()),
    physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
    totalVertexDomain_m(layout.domain()),
    totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
    {
    }
  NoMeshData(const NoMeshData<Dim> &model)
  : physicalVertexDomain_m(model.physicalVertexDomain_m),
    physicalCellDomain_m(model.physicalCellDomain_m),
    totalVertexDomain_m(model.totalVertexDomain_m),
    totalCellDomain_m(model.totalCellDomain_m)
    {
    }
  NoMeshData(const Interval<Dim> &d)
  : physicalVertexDomain_m(d - d.firsts()),
    physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
    totalVertexDomain_m(d - d.firsts()),
    totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
    {
    }
  NoMeshData(const NoMeshData<Dim> &model, const FieldEnginePatch<Dim> &p)
  : physicalVertexDomain_m(p.domain_m),
    physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
    totalVertexDomain_m(p.domain_m),
    totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
    {
    }
  NoMeshData<Dim> &operator=(const NoMeshData<Dim> &rhs)
    {
      if (this != &rhs)
        {
          physicalVertexDomain_m = rhs.physicalVertexDomain_m;
          physicalCellDomain_m = rhs.physicalCellDomain_m;
          totalVertexDomain_m = rhs.totalVertexDomain_m;
          totalCellDomain_m = rhs.totalCellDomain_m;
        }
      return *this;
    }
  ~NoMeshData()
    {
    }
  inline const Interval<Dim> &physicalVertexDomain() const
    {
      return physicalVertexDomain_m;
    }
  inline const Interval<Dim> &physicalCellDomain() const
    {
      return physicalCellDomain_m;
    }
  inline const Interval<Dim> &totalVertexDomain() const
    {
      return totalVertexDomain_m;
    }
  inline const Interval<Dim> &totalCellDomain() const
    {
      return totalCellDomain_m;
    }
private:
  Interval<Dim> physicalVertexDomain_m, physicalCellDomain_m;
  Interval<Dim> totalVertexDomain_m, totalCellDomain_m;
};
template<int Dim>
class NoMesh
{
public:
  enum { dimensions = Dim };
  enum { coordinateDimensions = Dim };
  inline NoMesh()
  : data_m(new NoMeshData<Dim>)
    {
    }
  template<class Layout>
  inline explicit NoMesh(const Layout &layout)
  : data_m(new NoMeshData<Dim>(layout))
    {
    }
  inline explicit NoMesh(const NoMeshData<Dim> &data)
  : data_m(new NoMeshData<Dim>(data))
    {
    }
  inline NoMesh(const NoMesh<Dim> &model)
  : data_m(model.data_m)
    {
    }
  inline NoMesh(const NoMesh<Dim> &model, const Interval<Dim> &d)
  : data_m(new NoMeshData<Dim>(d))
    {
    }
  NoMesh(const NoMesh<Dim> &model, const INode<Dim> &i)
  : data_m(new NoMeshData<Dim>(i.domain()))
    {
    }
  inline NoMesh(const NoMesh<Dim> &model, const FieldEnginePatch<Dim> &p)
  : data_m(new NoMeshData<Dim>(*model.data_m, p))
    {
    }
  template<class Mesh, class Domain>
  inline NoMesh(const Mesh &, const Domain &d)
    {
      Interval<Dim> dom;
      for (int i = 0; i < Dim; i++)
        dom[i] = d[i].size();
      data_m = new NoMeshData<Dim>(dom);
    }
  ~NoMesh() { }
  const NoMeshData<Dim>& data() const
    {
      return *data_m;
    }
  NoMesh<Dim> &
  operator=(const NoMesh<Dim> &rhs)
    {
      if (&rhs != this)
        {
          data_m = rhs.data_m;
        }
      return *this;
    }
  inline const Interval<Dim> &physicalVertexDomain() const
    {
      return data_m->physicalVertexDomain();
    }
  inline const Interval<Dim> &physicalCellDomain() const
    {
      return data_m->physicalCellDomain();
    }
  inline const Interval<Dim> &totalVertexDomain() const
    {
      return data_m->totalVertexDomain();
    }
  inline const Interval<Dim> &totalCellDomain() const
    {
      return data_m->totalCellDomain();
    }
private:
  RefCountedPtr<NoMeshData<Dim> > data_m;
};
template <class MeshTraits>
class UniformRectilinearMeshData : public NoMeshData<MeshTraits::dimensions>
{
public:
  typedef typename MeshTraits::MeshData_t MeshData_t;
  typedef typename MeshTraits::Domain_t Domain_t;
  typedef typename MeshTraits::Scalar_t Scalar_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  UniformRectilinearMeshData()
    {
    }
  template<class Layout>
  UniformRectilinearMeshData(
    const Layout &layout,
    const PointType_t &origin,
    const SpacingsType_t &spacings)
  : NoMeshData<dimensions>(layout),
    origin_m(origin),
    spacings_m(spacings)
    {
    }
  UniformRectilinearMeshData(const MeshData_t &model)
  : NoMeshData<dimensions>(model),
    origin_m(model.origin_m),
    spacings_m(model.spacings_m)
    {
    }
  UniformRectilinearMeshData(const MeshData_t &model,
                             const Domain_t &d)
  : NoMeshData<dimensions>(d),
    origin_m(model.origin_m),
    spacings_m(model.spacings_m)
    {
      for (int i = 0; i < dimensions; i++)
        origin_m(i) +=
          spacings_m(i) *
            (d[i].first() - model.physicalCellDomain()[i].first());
    }
  MeshData_t &
  operator=(const MeshData_t &rhs)
    {
      if (this != &rhs)
        {
          NoMeshData<dimensions>::operator=(rhs);
          origin_m = rhs.origin_m;
          spacings_m = rhs.spacings_m;
        }
      return *this;
    }
  ~UniformRectilinearMeshData() { }
  inline const SpacingsType_t &spacings() const
    {
      return spacings_m;
    }
  inline const PointType_t &origin() const
    {
      return origin_m;
    }
private:
  PointType_t origin_m;
  SpacingsType_t spacings_m;
};
template<class MeshTraits>
class UniformRectilinearMesh : public MeshTraits::CoordinateSystem_t
{
public:
  typedef MeshTraits MeshTraits_t;
  typedef typename MeshTraits::CoordinateSystem_t CoordinateSystem_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::MeshData_t MeshData_t;
  typedef typename MeshTraits::Loc_t Loc_t;
  typedef typename MeshTraits::Domain_t Domain_t;
  typedef typename MeshTraits::Scalar_t Scalar_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::T_t T_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  UniformRectilinearMesh()
  : data_m(new MeshData_t())
    {
    }
  template<class Layout>
  inline UniformRectilinearMesh(const Layout &layout,
                                const PointType_t &origin,
                                const SpacingsType_t &spacings)
  : data_m(new MeshData_t(layout, origin, spacings))
    {
    }
  template<class Layout>
  inline explicit UniformRectilinearMesh(const Layout &layout)
  : data_m(new MeshData_t(layout,
                                                  PointType_t(0),
                                                  SpacingsType_t(1)))
    {
    }
  inline UniformRectilinearMesh(const Mesh_t &model)
  : data_m(model.data_m)
    {
    }
  inline UniformRectilinearMesh(const Mesh_t &model,
                                const Domain_t &d)
  : data_m(new MeshData_t(*model.data_m, d))
    {
    }
  inline UniformRectilinearMesh(const Mesh_t &model,
                                const INode<dimensions> &i)
  : data_m(new MeshData_t(*model.data_m, i.domain()))
    {
    }
  inline Mesh_t &
  operator=(const Mesh_t &rhs)
    {
      if (&rhs != this)
        {
          data_m = rhs.data_m;
        }
      return *this;
    }
  ~UniformRectilinearMesh()
    {
    }
  const MeshData_t& data() const
    {
      return *data_m;
    }
  inline const Domain_t &physicalVertexDomain() const
    {
      return data_m->physicalVertexDomain();
    }
  inline const Domain_t &physicalCellDomain() const
    {
      return data_m->physicalCellDomain();
    }
  inline const Domain_t &totalVertexDomain() const
    {
      return data_m->totalVertexDomain();
    }
  inline const Domain_t &totalCellDomain() const
    {
      return data_m->totalCellDomain();
    }
  inline const PointType_t &origin() const
    {
      return data_m->origin();
    }
  inline const SpacingsType_t &spacings() const
    {
      return data_m->spacings();
    }
  inline Loc_t cellContaining(const PointType_t &point) const
    {
      Loc_t loc((Pooma::NoInit()));
      for (int i = 0; i < dimensions; i++)
        loc[i] =
          Loc<1>(static_cast<int>((point(i) - origin()(i)) / spacings()(i)));
      return loc;
    }
  inline PointType_t vertexPosition(const Loc_t &loc) const
    {
      PointType_t point;
      for (int i = 0; i < dimensions; i++)
        point(i) = origin()(i) + spacings()(i) *
          (loc[i].first() - physicalCellDomain()[i].first());
      return point;
    }
  inline Scalar_t vertexPosition(int dim, int i) const
    {
      return origin()(dim) + spacings()(dim)
              * (i - physicalCellDomain()[dim].first());
    }
  inline PointType_t cellPosition(const Loc_t &loc) const
    {
      PointType_t point;
      for (int i=0; i<dimensions; i++)
 point(i) = origin()(i) + spacings()(i)
   * (loc[i].first() - physicalCellDomain()[i].first() + 0.5);
      return point;
    }
  inline Scalar_t cellPosition(int dim, int i) const
    {
      return origin()(dim) + spacings()(dim)
               * (i - physicalCellDomain()[dim].first() + 0.5);
    }
  inline VectorType_t vertexSpacing(const Loc_t &loc) const
    {
      return spacings();
    }
  inline Scalar_t vertexSpacing(int dim, int = 0) const
    {
      return spacings()(dim);
    }
  inline VectorType_t cellSpacing(const Loc_t &loc) const
    {
      return spacings();
    }
  inline Scalar_t cellSpacing(int dim, int = 0) const
    {
      return spacings()(dim);
    }
private:
  RefCountedPtr<MeshData_t > data_m;
};
template <class MeshTraits>
struct GenericURM {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::Loc_t Loc_t;
  typedef typename MeshTraits::CIndexType_t CIndexType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  class PositionsFunctor {
  public:
    PositionsFunctor() { }
    PositionsFunctor(const Mesh_t &m,
                     const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
      {
        for (int i = 0; i < dimensions; i++)
          origin_m(i) += spacings_m(i) *
            (c.position(0)(i) - m.physicalCellDomain()[i].first());
      }
    inline PointType_t operator()(int i0) const
      {
 CIndexType_t i(0);
 i(0) = i0;
        return origin_m + i * spacings_m;
      }
    inline PointType_t operator()(int i0, int i1) const
      {
 CIndexType_t i(0);
 i(0) = i0;
 i(1) = i1;
        return origin_m + i * spacings_m;
      }
    inline PointType_t operator()(int i0, int i1, int i2) const
      {
 CIndexType_t i(0);
 i(0) = i0;
 i(1) = i1;
 i(2) = i2;
        return origin_m + i * spacings_m;
      }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  typedef IndexFunction<PositionsFunctor> PositionsEngineTag_t;
  template <class PositionsEngineTag>
  void initializePositions(
    Engine<dimensions, PointType_t, PositionsEngineTag> &e,
    const Centering<dimensions> &c) const
    {
      e.setFunctor(typename PositionsEngineTag::Functor_t(static_cast<const Mesh_t&>(*this), c));
    }
  typedef ConstantFunction SpacingsEngineTag_t;
  void initializeSpacings(
    Engine<dimensions, VectorType_t, SpacingsEngineTag_t> &e,
    const Centering<dimensions> &) const
    {
      e.setConstant(static_cast<const Mesh_t&>(*this).spacings());
    }
  typedef ConstantFunction NormalsEngineTag_t;
  void initializeNormals(
    Engine<dimensions, VectorType_t, NormalsEngineTag_t> &e,
    const Centering<dimensions> &c,
    bool outward = true) const
    {
      ;
      ;
      VectorType_t normal;
      for (int i = 0; i < dimensions; i++)
        {
          normal(i) = static_cast<T_t>(1 - c.orientation(0)[i].first());
          if (outward && c.position(0)(i) == 0.0)
            normal(i) *= static_cast<T_t>(-1);
        }
      e.setConstant(normal);
    }
  inline T_t DDX0(int) const { return 0.5; }
  inline T_t DDX0(const Loc_t&) const { return 0.5; }
  inline T_t DDX1(int) const { return 0.5; }
  inline T_t DDX1(const Loc_t&) const { return 0.5; }
  inline T_t DDY0(int) const { return 0.5; }
  inline T_t DDY0(const Loc_t&) const { return 0.5; }
  inline T_t DDY1(int) const { return 0.5; }
  inline T_t DDY1(const Loc_t&) const { return 0.5; }
  inline T_t DDZ0(int) const { return 0.5; }
  inline T_t DDZ0(const Loc_t&) const { return 0.5; }
  inline T_t DDZ1(int) const { return 0.5; }
  inline T_t DDZ1(const Loc_t&) const { return 0.5; }
};
template <class MeshTraits>
class RectilinearMeshData : public NoMeshData<MeshTraits::dimensions>
{
public:
  typedef typename MeshTraits::Domain_t Domain_t;
  typedef typename MeshTraits::MeshData_t MeshData_t;
  typedef typename MeshTraits::Scalar_t Scalar_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  RectilinearMeshData()
    {
    }
  template<class Layout>
  RectilinearMeshData(
    const Layout &layout,
    const PointType_t &origin,
    const SpacingsType_t &spacings)
  : NoMeshData<dimensions>(layout),
    origin_m(origin)
    {
      typedef Engine<1, Scalar_t, Brick> Engine_t;
      for (int i=0; i<dimensions; i++) {
 Interval<1> dom(layout.domain()[i]), idom(layout.innerDomain()[i]);
 spacings_m[i].engine() = Engine_t(dom);
 spacings_m[i] = spacings[i];
 Pooma::blockAndEvaluate();
 positions_m[i].engine() = Engine_t(dom);
 positions_m[i](idom.min()) = origin_m(i);
 for (int j=idom.min()-1; j>=dom.min(); j--)
   positions_m[i](j) = positions_m[i].read(j+1) - spacings_m[i].read(j);
 for (int j=idom.min()+1; j<=dom.max(); j++)
   positions_m[i](j) = positions_m[i].read(j-1) + spacings_m[i].read(j-1);
      }
    }
  template<class Layout>
  RectilinearMeshData(
    const Layout &layout,
    const PointType_t &origin,
    const VectorType_t &spacings)
  : NoMeshData<dimensions>(layout),
    origin_m(origin)
    {
      for (int i=0; i<dimensions; i++) {
 Interval<1> dom(layout.domain()[i]), idom(layout.innerDomain()[i]);
 spacings_m[i].engine() = Engine<1, Scalar_t, Brick>(dom, spacings(i));
 positions_m[i].engine() = Engine<1, Scalar_t, Brick>(dom);
 positions_m[i](idom.min()) = origin_m(i);
 for (int j=idom.min()-1; j>=dom.min(); j--)
   positions_m[i](j) = positions_m[i].read(j+1) - spacings_m[i].read(j);
 for (int j=idom.min()+1; j<=dom.max(); j++)
   positions_m[i](j) = positions_m[i].read(j-1) + spacings_m[i].read(j-1);
      }
    }
  RectilinearMeshData(const MeshData_t &model)
  : NoMeshData<dimensions>(model),
    origin_m(model.origin_m)
    {
      for (int i=0; i<dimensions; i++) {
 spacings_m[i].engine() = model.spacings_m[i].engine();
 positions_m[i].engine() = model.positions_m[i].engine();
      }
    }
  RectilinearMeshData(const MeshData_t &model,
        const Interval<dimensions> &d)
  : NoMeshData<dimensions>(d)
    {
      typedef Engine<1, Scalar_t, Brick> Engine_t;
      for (int i = 0; i < dimensions; i++) {
 Interval<1> dom(d[i]);
 Interval<1> viewdom(dom.size());
 spacings_m[i].engine() = Engine_t(&model.spacings_m[i](dom)(0),
       viewdom);
 positions_m[i].engine() = Engine_t(&model.positions_m[i](dom)(0),
        viewdom);
 origin_m(i) = model.positions_m[i].read(dom.min());
      }
    }
  MeshData_t &
  operator=(const MeshData_t &rhs)
    {
      if (this != &rhs)
        {
          NoMeshData<dimensions>::operator=(rhs);
          origin_m = rhs.origin_m;
   for (int i=0; i<dimensions; i++) {
     spacings_m[i].engine() = rhs.spacings_m[i].engine();
     positions_m[i].engine() = rhs.positions_m[i].engine();
   }
        }
      return *this;
    }
  ~RectilinearMeshData() { }
  inline const SpacingsType_t &spacings() const
    {
      return spacings_m;
    }
  inline const PositionsType_t &positions() const
    {
      return positions_m;
    }
  inline const PointType_t &origin() const
    {
      return origin_m;
    }
private:
  PointType_t origin_m;
  SpacingsType_t spacings_m;
  PositionsType_t positions_m;
};
template<class MeshTraits>
class RectilinearMesh : public MeshTraits::CoordinateSystem_t
{
public:
  typedef MeshTraits MeshTraits_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::MeshData_t MeshData_t;
  typedef typename MeshTraits::CoordinateSystem_t CoordinateSystem_t;
  typedef typename MeshTraits::Domain_t Domain_t;
  typedef typename MeshTraits::Loc_t Loc_t;
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Scalar_t Scalar_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  RectilinearMesh()
  : data_m(new MeshData_t)
    {
    }
  template<class Layout>
  inline RectilinearMesh(const Layout &layout,
    const PointType_t &origin,
    const SpacingsType_t &spacings)
  : data_m(new MeshData_t(layout, origin, spacings))
    {
    }
  template<class Layout>
  inline RectilinearMesh(const Layout &layout,
    const PointType_t &origin,
    const PointType_t &spacings)
  : data_m(new MeshData_t(layout, origin, spacings))
    {
    }
  template<class Layout>
  inline explicit RectilinearMesh(const Layout &layout)
  : data_m(new MeshData_t(layout,
        PointType_t(0),
        PointType_t(1)))
    {
    }
  inline RectilinearMesh(const Mesh_t &model)
  : data_m(model.data_m)
    {
    }
  inline RectilinearMesh(const Mesh_t &model,
    const Domain_t &d)
  : data_m(new MeshData_t(*model.data_m, d))
    {
    }
  inline RectilinearMesh(const Mesh_t &model,
    const INode<dimensions> &i)
  : data_m(new MeshData_t(*model.data_m, i.domain()))
    {
    }
  inline Mesh_t &
  operator=(const Mesh_t &rhs)
    {
      if (&rhs != this)
        {
          data_m = rhs.data_m;
        }
      return *this;
    }
  ~RectilinearMesh()
    {
    }
  const MeshData_t& data() const
    {
      return *data_m;
    }
  inline const Domain_t &physicalVertexDomain() const
    {
      return data_m->physicalVertexDomain();
    }
  inline const Domain_t &physicalCellDomain() const
    {
      return data_m->physicalCellDomain();
    }
  inline const Domain_t &totalVertexDomain() const
    {
      return data_m->totalVertexDomain();
    }
  inline const Domain_t &totalCellDomain() const
    {
      return data_m->totalCellDomain();
    }
  inline const PointType_t &origin() const
    {
      return data_m->origin();
    }
  inline const SpacingsType_t &spacings() const
    {
      return data_m->spacings();
    }
  inline const PositionsType_t &positions() const
    {
      return data_m->positions();
    }
  inline Loc_t cellContaining(const PointType_t &point) const
    {
      Loc_t loc((Pooma::NoInit()));
      for (int i = 0; i < dimensions; i++)
 {
   const T_t *start = &positions()[i](0);
   const T_t *finish = start + positions()[i].physicalDomain()[i].length();
   const T_t *p = std::lower_bound(start, finish, point(i));
   int j = static_cast<int>(std::distance(start, p));
   if (*p == point(i))
     loc[i] = j;
   else
     loc[i] = j-1;
 }
      return loc;
    }
  inline PointType_t vertexPosition(const Loc_t &loc) const
    {
      PointType_t point;
      for (int i = 0; i < dimensions; i++)
        point(i) = positions()[i](loc[i]);
      return point;
    }
  inline Scalar_t vertexPosition(int dim, int i) const
    {
      return positions()[dim](i);
    }
  inline PointType_t cellPosition(const Loc_t &loc) const
    {
      PointType_t point;
      for (int i=0; i<dimensions; i++)
 point(i) = positions()[i](loc[i]) + 0.5*spacings()[i](loc[i]);
      return point;
    }
  inline Scalar_t cellPosition(int dim, int i) const
    {
      return positions()[dim](i) + 0.5*spacings()[dim](i);
    }
  inline VectorType_t vertexSpacing(const Loc_t &loc) const
    {
      VectorType_t delta;
      for (int i=0; i<dimensions; i++)
 delta(i) = spacings()[i](loc[i]);
      return delta;
    }
  inline Scalar_t vertexSpacing(int dim, int i) const
    {
      return spacings()[dim](i);
    }
  inline VectorType_t cellSpacing(const Loc_t &loc) const
    {
      VectorType_t delta;
      for (int i=0; i<dimensions; i++)
 delta(i) = 0.5 * (spacings()[i](loc[i]) + spacings()[i](loc[i]+1));
      return delta;
    }
  inline Scalar_t cellSpacing(int dim, int i) const
    {
      return 0.5*(spacings()[dim](i) + spacings()[dim](i+1));
    }
private:
  RefCountedPtr<MeshData_t> data_m;
};
template <class MeshTraits>
struct GenericRM {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  typedef typename MeshTraits::Loc_t Loc_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  class PositionsFunctor {
  public:
    PositionsFunctor() { }
    PositionsFunctor(const Mesh_t &m,
                     const Centering<dimensions> &c)
      : centering_m(c.position(0))
      {
 for (int i=0; i<dimensions; i++) {
   positions_m[i].engine() = m.positions()[i].engine();
   spacings_m[i].engine() = m.spacings()[i].engine();
 }
      }
    PositionsFunctor(const PositionsFunctor &m)
      : centering_m(m.centering_m)
    {
      for (int i=0; i<dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
    }
    PositionsFunctor& operator=(const PositionsFunctor &m)
    {
      centering_m = m.centering_m;
      for (int i=0; i<dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
      {
        return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
      }
    inline PointType_t operator()(int i0, int i1) const
      {
        return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
      }
    inline PointType_t operator()(int i0, int i1, int i2) const
      {
        return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  typedef IndexFunction<PositionsFunctor> PositionsEngineTag_t;
  template <class PositionsEngineTag>
  void initializePositions(
    Engine<dimensions, PointType_t, PositionsEngineTag> &e,
    const Centering<dimensions> &c) const
    {
      e.setFunctor(typename PositionsEngineTag::Functor_t(static_cast<const Mesh_t&>(*this), c));
    }
  class SpacingsFunctor {
  public:
    SpacingsFunctor() { }
    SpacingsFunctor(const Mesh_t &m,
      const Centering<dimensions> &c)
      : centering_m(c.position(0))
      {
 for (int i=0; i<dimensions; i++)
   spacings_m[i].engine() = m.spacings()[i].engine();
      }
    SpacingsFunctor(const SpacingsFunctor &m)
      : centering_m(m.centering_m)
    {
      for (int i=0; i<dimensions; i++)
 spacings_m[i].engine() = m.spacings_m[i].engine();
    }
    SpacingsFunctor& operator=(const SpacingsFunctor &m)
    {
      centering_m = m.centering_m;
      for (int i=0; i<dimensions; i++)
 spacings_m[i].engine() = m.spacings_m[i].engine();
      return *this;
    }
    inline VectorType_t operator()(int i0) const
      {
        return VectorType_t(spacings_m[0].read(i0)
      + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0));
      }
    inline VectorType_t operator()(int i0, int i1) const
      {
        return VectorType_t(spacings_m[0].read(i0)
      + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0),
      spacings_m[1].read(i1)
      + (spacings_m[1].read(i1+1)-spacings_m[1].read(i1))*centering_m(1));
      }
    inline VectorType_t operator()(int i0, int i1, int i2) const
      {
        return VectorType_t(spacings_m[0].read(i0)
      + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0),
      spacings_m[1].read(i1)
      + (spacings_m[1].read(i1+1)-spacings_m[1].read(i1))*centering_m(1),
      spacings_m[2].read(i2)
      + (spacings_m[2].read(i2+1)-spacings_m[2].read(i2))*centering_m(2));
      }
  private:
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  typedef IndexFunction<SpacingsFunctor> SpacingsEngineTag_t;
  void initializeSpacings(
    Engine<dimensions, PointType_t, SpacingsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      e.setFunctor(SpacingsFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef ConstantFunction NormalsEngineTag_t;
  void initializeNormals(
    Engine<dimensions, VectorType_t, NormalsEngineTag_t> &e,
    const Centering<dimensions> &c,
    bool outward = true) const
    {
      ;
      ;
      VectorType_t normal;
      for (int i = 0; i < dimensions; i++)
        {
          normal(i) = static_cast<T_t>(1 - c.orientation(0)[i].first());
          if (outward && c.position(0)(i) == 0.0)
            normal(i) *= static_cast<T_t>(-1);
        }
      e.setConstant(normal);
    }
  inline T_t DDX0(int i) const
  {
    return (static_cast<const Mesh_t&>(*this).cellPosition( 0, i)
     - static_cast<const Mesh_t&>(*this).vertexPosition( 0, i))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 0, i-1);
  }
  inline T_t DDX0(const Loc_t& l) const { return DDX0(l[0].first()); }
  inline T_t DDX1(int i) const
  {
    return (static_cast<const Mesh_t&>(*this).vertexPosition( 0, i)
     - static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 0, i-1);
  }
  inline T_t DDX1(const Loc_t& l) const { return DDX0(l[0].first()); }
  inline T_t DDY0(int j) const
  {
    return (static_cast<const Mesh_t&>(*this).cellPosition( 1, j)
     - static_cast<const Mesh_t&>(*this).vertexPosition( 1, j))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 1, j-1);
  }
  inline T_t DDY0(const Loc_t& l) const { return DDX0(l[0].first()); }
  inline T_t DDY1(int j) const
  {
    return (static_cast<const Mesh_t&>(*this).vertexPosition( 1, j)
     - static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 1, j-1);
  }
  inline T_t DDY1(const Loc_t& l) const { return DDX0(l[0].first()); }
  inline T_t DDZ0(int k) const
  {
    return (static_cast<const Mesh_t&>(*this).cellPosition( 2, k)
     - static_cast<const Mesh_t&>(*this).vertexPosition( 2, k))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 2, k-1);
  }
  inline T_t DDZ0(const Loc_t& l) const { return DDX0(l[0].first()); }
  inline T_t DDZ1(int k) const
  {
    return (static_cast<const Mesh_t&>(*this).vertexPosition( 1, k)
     - static_cast<const Mesh_t&>(*this).cellPosition( 1, k-1))
      / static_cast<const Mesh_t&>(*this).cellSpacing( 1, k-1);
  }
  inline T_t DDZ1(const Loc_t& l) const { return DDX0(l[0].first()); }
};
template <class MeshTraits>
struct CartesianRM : public GenericRM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  class GeneralVolumesFunctor {
  public:
    GeneralVolumesFunctor() { }
    GeneralVolumesFunctor(const Mesh_t &m,
     const Centering<dimensions> &c)
      : orientation_m(c.orientation(0))
      {
 for (int i=0; i<dimensions; i++)
   spacings_m[i].engine() = m.spacings()[i].engine();
      }
    GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
      : orientation_m(m.orientation_m)
      {
 for (int i=0; i<dimensions; i++)
   spacings_m[i].engine() = m.spacings_m[i].engine();
      }
    GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
    {
      orientation_m = m.orientation_m;
      for (int i=0; i<dimensions; i++)
 spacings_m[i].engine() = m.spacings_m[i].engine();
      return *this;
    }
    inline T_t operator()(int i0) const
      {
 return spacings_m[0].read(i0);
      }
    inline T_t operator()(int i0, int i1) const
      {
 if (orientation_m[0].first() == 0)
   return spacings_m[1].read(i1);
 else if (orientation_m[1].first() == 0)
   return spacings_m[0].read(i0);
 else
   return spacings_m[0].read(i0) * spacings_m[1].read(i1);
      }
    inline T_t operator()(int i0, int i1, int i2) const
      {
 T_t volume = static_cast<T_t>(1);
 if (orientation_m[0].first() != 0)
   volume *= spacings_m[0].read(i0);
 if (orientation_m[1].first() != 0)
   volume *= spacings_m[1].read(i1);
 if (orientation_m[2].first() != 0)
   volume *= spacings_m[2].read(i2);
 return volume;
      }
  private:
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Orientation orientation_m;
  };
  typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  class SphericalPositionsFunctor {
  public:
    SphericalPositionsFunctor() {}
    SphericalPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    SphericalPositionsFunctor& operator=(const SphericalPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
      return PointType_t(norm(x),
    atan2(x(0), x(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      T_t r = norm(x);
      return PointType_t(r,
    acos(x(2)/r),
    atan2(x(1), x(0)));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  class CylindricalPositionsFunctor {
  public:
    CylindricalPositionsFunctor() {}
    CylindricalPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    CylindricalPositionsFunctor& operator=(const CylindricalPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
    positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      return PointType_t(norm(Vector<2, T_t>(x(0), x(1))),
    x(2),
    atan2(x(1), x(0)));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 0, i);
  }
  inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
  inline T_t VOLYA(int j) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 1, j);
  }
  inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
  inline T_t VOLZA(int k) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k);
  }
  inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
  inline T_t VOLXB(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 0, i);
  }
  inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
  inline T_t VOLYB(int j) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 1, j);
  }
  inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
  inline T_t VOLZB(int k) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
  }
  inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
  inline One<T_t> SURXA(int) const { return One<T_t>(); }
  inline One<T_t> SURXA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURYA(int) const { return One<T_t>(); }
  inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURXB(int) const { return One<T_t>(); }
  inline One<T_t> SURXB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURYB(int) const { return One<T_t>(); }
  inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCXA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> GEOXG(int) const { return One<T_t>(); }
  inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXH(int) const { return One<T_t>(); }
  inline One<T_t> GEOXH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOYH(int) const { return One<T_t>(); }
  inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXHA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
};
template <class MeshTraits>
struct CartesianURM : public GenericURM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  inline void initializeGeneralVolume(
    Engine<dimensions, T_t, ConstantFunction> &e,
    const Centering<dimensions> &c) const
    {
      T_t volume = static_cast<T_t>(1);
      for (int i = 0; i < dimensions; i++)
        {
          if (c.orientation(0)[i].first() != 0)
            volume *= static_cast<const Mesh_t&>(*this).spacings()(i);
        }
      e.setConstant(volume);
    }
  typedef ConstantFunction CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      initializeGeneralVolume(e, c);
    }
  typedef ConstantFunction FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      initializeGeneralVolume(e, c);
    }
  typedef ConstantFunction EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      initializeGeneralVolume(e, c);
    }
  class SphericalPositionsFunctor {
  public:
    SphericalPositionsFunctor() {}
    SphericalPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
 origin_m(i) += spacings_m(i) *
   (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t x(origin_m + PointType_t(i0, i1) * spacings_m);
      return PointType_t(norm(x),
    atan2(x(0), x(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t x(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      T_t r = norm(x);
      return PointType_t(r,
    acos(x(2)/r),
    atan2(x(1), x(0)));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  class CylindricalPositionsFunctor {
  public:
    CylindricalPositionsFunctor() {}
    CylindricalPositionsFunctor(const Mesh_t &m,
           const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
 origin_m(i) += spacings_m(i) *
   (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      return origin_m + PointType_t(i0, i1) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t x(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      return PointType_t(norm(Vector<2, T_t>(x(0), x(1))),
    x(2),
    atan2(x(1), x(0)));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(0);
  }
  inline T_t VOLXA(const Loc<dimensions>&) const { return VOLXA(0); }
  inline T_t VOLYA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(1);
  }
  inline T_t VOLYA(const Loc<dimensions>&) const { return VOLYA(0); }
  inline T_t VOLZA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
  inline T_t VOLXB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(0);
  }
  inline T_t VOLXB(const Loc<dimensions>&) const { return VOLXB(0); }
  inline T_t VOLYB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(1);
  }
  inline T_t VOLYB(const Loc<dimensions>&) const { return VOLYB(0); }
  inline T_t VOLZB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
  inline One<T_t> SURXA(int) const { return One<T_t>(); }
  inline One<T_t> SURXA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURYA(int) const { return One<T_t>(); }
  inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURXB(int) const { return One<T_t>(); }
  inline One<T_t> SURXB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURYB(int) const { return One<T_t>(); }
  inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCXA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCXB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> GEOXG(int) const { return One<T_t>(); }
  inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXH(int) const { return One<T_t>(); }
  inline One<T_t> GEOXH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOYH(int) const { return One<T_t>(); }
  inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXHA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
};
template <class MeshTraits>
struct CylindricalRM : public GenericRM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  class GeneralVolumesFunctor {
  public:
    GeneralVolumesFunctor() { }
    GeneralVolumesFunctor(const Mesh_t &m,
     const Centering<dimensions> &c)
      : orientation_m(c.orientation(0))
      {
 for (int i=0; i<dimensions; i++) {
   spacings_m[i].engine() = m.spacings()[i].engine();
   positions_m[i].engine() = m.positions()[i].engine();
 }
      }
    GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
      : orientation_m(m.orientation_m)
      {
 for (int i=0; i<dimensions; i++) {
   spacings_m[i].engine() = m.spacings_m[i].engine();
   positions_m[i].engine() = m.positions_m[i].engine();
 }
      }
    GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
    {
      orientation_m = m.orientation_m;
      for (int i=0; i<dimensions; i++) {
 spacings_m[i].engine() = m.spacings_m[i].engine();
 positions_m[i].engine() = m.positions_m[i].engine();
      }
      return *this;
    }
    inline T_t r(int i0) const
      {
 return positions_m[0].read(i0);
      }
    inline T_t operator()(int i0) const
      {
 return spacings_m[0].read(i0);
      }
    inline T_t operator()(int i0, int i1) const
      {
 if (orientation_m[0].first() == 0)
   return spacings_m[1].read(i1);
 else if (orientation_m[1].first() == 0)
   return spacings_m[0].read(i0);
 else
   return spacings_m[0].read(i0) * spacings_m[1].read(i1);
      }
    inline T_t operator()(int i0, int i1, int i2) const
      {
 if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0
     && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1) * spacings_m[2].read(i2);
 } else if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0)
   return spacings_m[0].read(i0)*spacings_m[1].read(i1);
 else if (orientation_m[0].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m[2].read(i2);
 } else if (orientation_m[1].first() != 0
     && orientation_m[2].first() != 0)
   return r(i0)*spacings_m[1].read(i1)*spacings_m[2].read(i2);
 else if (orientation_m[0].first() != 0)
   return spacings_m[0].read(i0);
 else if (orientation_m[1].first() != 0)
   return spacings_m[1].read(i1);
 else if (orientation_m[2].first() != 0)
   return r(i0)*spacings_m[2].read(i2);
      }
  private:
    SpacingsType_t spacings_m;
    PositionsType_t positions_m;
    typename Centering<dimensions>::Orientation orientation_m;
  };
  typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  class CartesianPositionsFunctor {
  public:
    CartesianPositionsFunctor() {}
    CartesianPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    CartesianPositionsFunctor& operator=(const CartesianPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
    positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      return PointType_t(r(0)*cos(r(2)),
                         r(0)*sin(r(2)),
                         r(1));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  class SphericalPositionsFunctor {
  public:
    SphericalPositionsFunctor() {}
    SphericalPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    SphericalPositionsFunctor& operator=(const SphericalPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
      T_t R = hypot(r(0), r(1));
      return PointType_t(R,
    acos(r(1)/R));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      T_t R = hypot(r(0), r(1));
      return PointType_t(R,
    acos(r(1)/R),
                         r(2));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int i) const
  {
    return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2)
  - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 2));
  }
  inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
  inline T_t VOLYA(int j) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 1, j);
  }
  inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
  inline T_t VOLZA(int k) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k);
  }
  inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
  inline T_t VOLXB(int i) const
  {
    return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 2)
  - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2));
  }
  inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
  inline T_t VOLYB(int j) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 1, j);
  }
  inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
  inline T_t VOLZB(int k) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
  }
  inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
  inline T_t SURXA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
  inline One<T_t> SURYA(int) const { return One<T_t>(); }
  inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t SURXB(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
  inline One<T_t> SURYB(int) const { return One<T_t>(); }
  inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> CCXA(int) const { return One<T_t>(); }
  inline One<T_t> CCXA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> CCXB(int) const { return One<T_t>(); }
  inline One<T_t> CCXB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> GEOXG(int) const { return One<T_t>(); }
  inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t GEOXH(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline One<T_t> GEOYH(int) const { return One<T_t>(); }
  inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t GEOXHA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
};
template <class MeshTraits>
struct CylindricalURM : public GenericURM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  enum { dimensions = MeshTraits::dimensions };
  enum { coordinateDimensions = MeshTraits::coordinateDimensions };
  class GeneralVolumesFunctor {
  public:
    GeneralVolumesFunctor() { }
    GeneralVolumesFunctor(const Mesh_t &m,
     const Centering<dimensions> &c)
      : spacings_m(m.spacings()),
        orientation_m(c.orientation(0)),
        origin_m(m.origin())
      {
      }
    inline T_t r(int i0) const
      {
 return origin_m(0)+i0*spacings_m(0);
      }
    inline T_t operator()(int i0) const
      {
 return spacings_m(0);
      }
    inline T_t operator()(int i0, int i1) const
      {
 if (orientation_m[0].first() == 0)
   return spacings_m(1);
 else if (orientation_m[1].first() == 0)
   return spacings_m(0);
 else
   return spacings_m(0) * spacings_m(1);
      }
    inline T_t operator()(int i0, int i1, int i2) const
      {
 if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0
     && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m(1) * spacings_m(2);
 } else if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0)
   return spacings_m(0) * spacings_m(1);
 else if (orientation_m[0].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m(2);
 } else if (orientation_m[1].first() != 0
     && orientation_m[2].first() != 0)
   return r(i0)*spacings_m(1) * spacings_m(2);
 else if (orientation_m[0].first() != 0)
   return spacings_m(0);
 else if (orientation_m[1].first() != 0)
   return spacings_m(1);
 else if (orientation_m[2].first() != 0)
   return r(i0)*spacings_m(2);
      }
  private:
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Orientation orientation_m;
    PointType_t origin_m;
  };
  typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  class CartesianPositionsFunctor {
  public:
    CartesianPositionsFunctor() {}
    CartesianPositionsFunctor(const Mesh_t &m,
                              const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
        origin_m(i) += spacings_m(i) *
          (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      return origin_m + PointType_t(i0, i1) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      return PointType_t(r(0)*cos(r(2)),
                         r(0)*sin(r(2)),
                         r(1));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  class SphericalPositionsFunctor {
  public:
    SphericalPositionsFunctor() {}
    SphericalPositionsFunctor(const Mesh_t &m,
                              const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
        origin_m(i) += spacings_m(i) *
          (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
      T_t R = hypot(r(0), r(1));
      return PointType_t(R,
    acos(r(1)/R));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      T_t R = hypot(r(0), r(1));
      return PointType_t(R,
    acos(r(1)/R),
                         r(2));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int i) const
  {
    return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2)
  - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 2));
  }
  inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
  inline T_t VOLYA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(1);
  }
  inline T_t VOLYA(const Loc<dimensions>&) const { return VOLYA(0); }
  inline T_t VOLZA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
  inline T_t VOLXB(int i) const
  {
    return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 2)
  - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2));
  }
  inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
  inline T_t VOLYB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(1);
  }
  inline T_t VOLYB(const Loc<dimensions>&) const { return VOLYB(0); }
  inline T_t VOLZB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
  inline T_t SURXA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
  inline One<T_t> SURYA(int) const { return One<T_t>(); }
  inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t SURXB(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
  inline One<T_t> SURYB(int) const { return One<T_t>(); }
  inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> CCXA(int) const { return One<T_t>(); }
  inline One<T_t> CCXA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> CCXB(int) const { return One<T_t>(); }
  inline One<T_t> CCXB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline One<T_t> GEOXG(int) const { return One<T_t>(); }
  inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t GEOXH(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline One<T_t> GEOYH(int) const { return One<T_t>(); }
  inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
  inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t GEOXHA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
  inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
};
template <class MeshTraits>
struct SphericalRM : public GenericRM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  typedef typename MeshTraits::PositionsType_t PositionsType_t;
  enum { dimensions = MeshTraits::dimensions };
  class GeneralVolumesFunctor {
  public:
    GeneralVolumesFunctor() { }
    GeneralVolumesFunctor(const Mesh_t &m,
     const Centering<dimensions> &c)
      : orientation_m(c.orientation(0))
      {
 for (int i=0; i<dimensions; i++) {
   spacings_m[i].engine() = m.spacings()[i].engine();
   positions_m[i].engine() = m.positions()[i].engine();
 }
      }
    GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
      : orientation_m(m.orientation_m)
      {
 for (int i=0; i<dimensions; i++) {
   spacings_m[i].engine() = m.spacings_m[i].engine();
   positions_m[i].engine() = m.positions_m[i].engine();
 }
      }
    GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
    {
      orientation_m = m.orientation_m;
      for (int i=0; i<dimensions; i++) {
 spacings_m[i].engine() = m.spacings_m[i].engine();
 positions_m[i].engine() = m.positions_m[i].engine();
      }
      return *this;
    }
    inline T_t r(int i0) const
      {
 return positions_m[0].read(i0);
      }
    inline T_t theta(int i1) const
      {
 return positions_m[1].read(i1);
      }
    inline T_t phi(int i2) const
      {
 return positions_m[2].read(i2);
      }
    inline T_t operator()(int i0) const
      {
 return spacings_m[0].read(i0);
      }
    inline T_t operator()(int i0, int i1) const
      {
 if (orientation_m[0].first() == 0)
   return r(i0)*spacings_m[1].read(i1);
 else if (orientation_m[1].first() == 0)
   return spacings_m[0].read(i0);
 else {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1);
 }
      }
    inline T_t operator()(int i0, int i1, int i2) const
      {
 if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0
     && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return (r2*r2*r2 - r1*r1*r1)/3.0
     * (cos(theta(i1)) - cos(theta(i1+1)))
     * spacings_m[2].read(i2);
 } else if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1);
 } else if (orientation_m[0].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1)*sin(theta(i1)) * spacings_m[2].read(i2);
 } else if (orientation_m[1].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   return - r1*r1 * spacings_m[2].read(i2) * (cos(theta(i1+1)) - cos(theta(i1)));
 } else if (orientation_m[0].first() != 0)
   return spacings_m[0].read(i0);
 else if (orientation_m[1].first() != 0)
   return r(i0)*spacings_m[1].read(i1);
 else if (orientation_m[2].first() != 0)
   return r(i0)*sin(theta(i1)) * spacings_m[2].read(i2);
      }
  private:
    SpacingsType_t spacings_m;
    SpacingsType_t positions_m;
    typename Centering<dimensions>::Orientation orientation_m;
  };
  typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  class CartesianPositionsFunctor {
  public:
    CartesianPositionsFunctor() {}
    CartesianPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    CartesianPositionsFunctor& operator=(const CartesianPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      return PointType_t(r(0)*sin(r(1))*cos(r(2)),
    r(0)*sin(r(1))*sin(r(2)),
    r(0)*cos(r(1)));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  class CylindricalPositionsFunctor {
  public:
    CylindricalPositionsFunctor() {}
    CylindricalPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : centering_m(c.position(0))
    {
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions()[i].engine();
 spacings_m[i].engine() = m.spacings()[i].engine();
      }
    }
    CylindricalPositionsFunctor& operator=(const CylindricalPositionsFunctor& m)
    {
      centering_m = m.centering_m;
      for (int i = 0; i < dimensions; i++) {
 positions_m[i].engine() = m.positions_m[i].engine();
 spacings_m[i].engine() = m.spacings_m[i].engine();
      }
      return *this;
    }
    inline PointType_t operator()(int i0) const
    {
      return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
      positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
      positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)),
    r(2));
    }
  private:
    PositionsType_t positions_m;
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Position centering_m;
  };
  typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int i) const
  {
    return (1.0/3.0)*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3)
        - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 3));
  }
  inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
  inline T_t VOLYA(int j) const
  {
    return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
      - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
  inline T_t VOLZA(int k) const
  {
    return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k-1);
  }
  inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
  inline T_t VOLXB(int i) const
  {
    return (1.0/3.0)*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i+1), 3)
        - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3));
  }
  inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
  inline T_t VOLYB(int j) const
  {
    return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j))
      - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j+1));
   }
  inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
  inline T_t VOLZB(int k) const
  {
    return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
  }
  inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
  inline T_t SURXA(int i) const
  {
    return std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2);
  }
  inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
  inline T_t SURYA(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t SURYA(const Loc<dimensions>& l) const { return SURYA(l[1].first()); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t SURXB(int i) const
  {
    return std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2);
  }
  inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
  inline T_t SURYB(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t SURYB(const Loc<dimensions>& l) const { return SURYB(l[1].first()); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t CCXA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t CCXA(const Loc<dimensions>& l) const { return CCXA(l[0].first()); }
  inline T_t CCYA(int j) const
  {
    return 0.5*std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t CCYA(const Loc<dimensions>& l) const { return CCYA(l[1].first()); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline T_t CCXB(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t CCXB(const Loc<dimensions>& l) const { return CCXB(l[0].first()); }
  inline T_t CCYB(int j) const
  {
    return 0.5*std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t CCYB(const Loc<dimensions>& l) const { return CCYB(l[1].first()); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline T_t GEOXG(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXG(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
  inline T_t GEOXH(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline T_t GEOYH(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t GEOYH(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
  inline T_t GEOXGA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXGA(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
  inline T_t GEOXHA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline T_t GEOYHA(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t GEOYHA(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
};
template <class MeshTraits>
struct SphericalURM : public GenericURM<MeshTraits> {
  typedef typename MeshTraits::T_t T_t;
  typedef typename MeshTraits::Mesh_t Mesh_t;
  typedef typename MeshTraits::PointType_t PointType_t;
  typedef typename MeshTraits::VectorType_t VectorType_t;
  typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
  enum { dimensions = MeshTraits::dimensions };
  class GeneralVolumesFunctor {
  public:
    GeneralVolumesFunctor() { }
    GeneralVolumesFunctor(const Mesh_t &m,
     const Centering<dimensions> &c)
      : spacings_m(m.spacings()),
        orientation_m(c.orientation(0)),
        origin_m(m.origin())
      {
      }
    inline T_t r(int i0) const
      {
 return origin_m(0)+i0*spacings_m(0);
      }
    inline T_t theta(int i1) const
      {
 return origin_m(1)+i1*spacings_m(1);
      }
    inline T_t operator()(int i0) const
      {
 return spacings_m(0);
      }
    inline T_t operator()(int i0, int i1) const
      {
 if (orientation_m[0].first() == 0)
   return r(i0)*spacings_m(1);
 else if (orientation_m[1].first() == 0)
   return spacings_m(0);
 else {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1) * spacings_m(1);
 }
      }
    inline T_t operator()(int i0, int i1, int i2) const
      {
 if (orientation_m[0].first() != 0
     && orientation_m[1].first() != 0
     && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r1 + spacings_m(0);
   return (r2*r2*r2 - r1*r1*r1)/3.0
     * (cos(theta(i1)) - cos(theta(i1+1)))
     * spacings_m(2);
 } else if (orientation_m[0].first() != 0
   && orientation_m[1].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r1 + spacings_m(0);
   return 0.5*(r2*r2 - r1*r1) * spacings_m(1);
 } else if (orientation_m[0].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   T_t r2 = r(i0+1);
   return 0.5*(r2*r2 - r1*r1)*sin(theta(i1)) * spacings_m(2);
 } else if (orientation_m[1].first() != 0
   && orientation_m[2].first() != 0) {
   T_t r1 = r(i0);
   return - r1*r1 * spacings_m(2) * (cos(theta(i1+1)) - cos(theta(i1)));
 } else if (orientation_m[0].first() != 0)
   return spacings_m(0);
 else if (orientation_m[1].first() != 0)
   return r(i0)*spacings_m(1);
 else if (orientation_m[2].first() != 0)
   return r(i0)*sin(theta(i1)) * spacings_m(2);
      }
  private:
    SpacingsType_t spacings_m;
    typename Centering<dimensions>::Orientation orientation_m;
    PointType_t origin_m;
  };
  typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
  void initializeCellVolumes(
    Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
  void initializeFaceAreas(
    Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
  void initializeEdgeLengths(
    Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
    const Centering<dimensions> &c) const
    {
      ;
      ;
      e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
    }
  class CartesianPositionsFunctor {
  public:
    CartesianPositionsFunctor() {}
    CartesianPositionsFunctor(const Mesh_t &m,
         const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
 origin_m(i) += spacings_m(i) *
   (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      return PointType_t(r(0)*sin(r(1))*cos(r(2)),
    r(0)*sin(r(1))*sin(r(2)),
    r(0)*cos(r(1)));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  class CylindricalPositionsFunctor {
  public:
    CylindricalPositionsFunctor() {}
    CylindricalPositionsFunctor(const Mesh_t &m,
           const Centering<dimensions> &c)
      : origin_m(m.origin()), spacings_m(m.spacings())
    {
      for (int i = 0; i < dimensions; i++)
 origin_m(i) += spacings_m(i) *
   (c.position(0)(i) - m.physicalCellDomain()[i].first());
    }
    inline PointType_t operator()(int i0) const
    {
      return origin_m + PointType_t(i0) * spacings_m;
    }
    inline PointType_t operator()(int i0, int i1) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)));
    }
    inline PointType_t operator()(int i0, int i1, int i2) const
    {
      PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
      return PointType_t(r(0)*sin(r(1)),
    r(0)*cos(r(1)),
    r(2));
    }
  private:
    PointType_t origin_m;
    SpacingsType_t spacings_m;
  };
  typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
  typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
  typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> SphericalPositionsEngineTag_t;
  inline T_t VOLXA(int i) const
  {
    return (std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3)
     - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 3))
      / 3.0;
  }
  inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
  inline T_t VOLYA(int j) const
  {
    return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
      - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
  inline T_t VOLZA(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
  inline T_t VOLXB(int i) const
  {
    return (std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 3)
     - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 3))
      / 3.0;
  }
  inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
  inline T_t VOLYB(int j) const
  {
    return std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j))
      - std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j+1));
  }
  inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
  inline T_t VOLZB(int) const
  {
    return static_cast<const Mesh_t&>(*this).spacings()(2);
  }
  inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
  inline T_t SURXA(int i) const
  {
    return std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2);
  }
  inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
  inline T_t SURYA(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t SURYA(const Loc<dimensions>& l) const { return SURYA(l[1].first()); }
  inline One<T_t> SURZA(int) const { return One<T_t>(); }
  inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t SURXB(int i) const
  {
    return std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2);
  }
  inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
  inline T_t SURYB(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t SURYB(const Loc<dimensions>& l) const { return SURYB(l[1].first()); }
  inline One<T_t> SURZB(int) const { return One<T_t>(); }
  inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
  inline T_t CCXA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t CCXA(const Loc<dimensions>& l) const { return CCXA(l[0].first()); }
  inline T_t CCYA(int j) const
  {
    return 0.5*std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t CCYA(const Loc<dimensions>& l) const { return CCYA(l[1].first()); }
  inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline T_t CCXB(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t CCXB(const Loc<dimensions>& l) const { return CCXB(l[0].first()); }
  inline T_t CCYB(int j) const
  {
    return 0.5*std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t CCYB(const Loc<dimensions>& l) const { return CCYB(l[1].first()); }
  inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
  inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
  inline T_t GEOXG(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXG(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
  inline T_t GEOXH(int i) const
  {
    return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
  }
  inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline T_t GEOYH(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
  }
  inline T_t GEOYH(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
  inline T_t GEOXGA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXGA(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
  inline T_t GEOXHA(int i) const
  {
    return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
  }
  inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
  inline T_t GEOYHA(int j) const
  {
    return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
  }
  inline T_t GEOYHA(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
};
template<class Mesh, class T, class EngineTag> class Field;
namespace Pooma {
template<class Mesh>
struct PositionsTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::PointType_t,
    typename Mesh::PositionsEngineTag_t> Type_t;
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::PointType_t,
    typename Mesh::CartesianPositionsEngineTag_t> CartesianType_t;
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::PointType_t,
    typename Mesh::CylindricalPositionsEngineTag_t> CylindricalType_t;
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::PointType_t,
    typename Mesh::SphericalPositionsEngineTag_t> SphericalType_t;
};
template<class Mesh, class T, class EngineTag>
typename PositionsTraits<Mesh>::Type_t
positions(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  typename PositionsTraits<Mesh>::Type_t
    of(f.numMaterials(), f.centering(), f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh, int Dim>
typename PositionsTraits<Mesh>::Type_t
positions(const Mesh &mesh, Centering<Dim> c)
{
  GuardLayers<Mesh::dimensions> g;
  for (int i = 0; i < Mesh::dimensions; ++i) {
    g.lower(i) = mesh.physicalVertexDomain()[i].min() - mesh.totalVertexDomain()[i].min();
    g.upper(i) = mesh.totalVertexDomain()[i].max() - mesh.physicalVertexDomain()[i].max();
  }
  DomainLayout<Mesh::dimensions> layout(mesh.physicalVertexDomain(), g);
  NoMesh<Mesh::dimensions> m(layout);
  typename PositionsTraits<Mesh>::Type_t
    of(1, c, layout, m);
  for (int j = 0; j < of.centeringSize(); j++)
    mesh.initializePositions(of.subField(0, j).engine(), of.centering(j));
  return of;
}
template<class Mesh, class T, class EngineTag>
typename PositionsTraits<Mesh>::CartesianType_t
cartesianPositions(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  typename PositionsTraits<Mesh>::CartesianType_t
    of(f.numMaterials(), f.centering(), f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh, class T, class EngineTag>
typename PositionsTraits<Mesh>::CylindricalType_t
cylindricalPositions(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  typename PositionsTraits<Mesh>::CylindricalType_t
    of(f.numMaterials(), f.centering(), f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh, class T, class EngineTag>
typename PositionsTraits<Mesh>::SphericalType_t
sphericalPositions(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  typename PositionsTraits<Mesh>::SphericalType_t
    of(f.numMaterials(), f.centering(), f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh>
struct SpacingsTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::VectorType_t,
    typename Mesh::SpacingsEngineTag_t> Type_t;
};
template<class Mesh, class T, class EngineTag>
typename SpacingsTraits<Mesh>::Type_t
spacings(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  typename SpacingsTraits<Mesh>::Type_t
    of(f.numMaterials(), f.centering(), f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializeSpacings(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh, int Dim>
typename SpacingsTraits<Mesh>::Type_t
spacings(const Mesh &mesh, Centering<Dim> c)
{
  GuardLayers<Mesh::dimensions> g;
  for (int i = 0; i < Mesh::dimensions; ++i) {
    g.lower(i) = mesh.physicalVertexDomain()[i].min() - mesh.totalVertexDomain()[i].min();
    g.upper(i) = mesh.totalVertexDomain()[i].max() - mesh.physicalVertexDomain()[i].max();
  }
  DomainLayout<Mesh::dimensions> layout(mesh.physicalVertexDomain(), g);
  NoMesh<Mesh::dimensions> m(layout);
  typename SpacingsTraits<Mesh>::Type_t
    of(1, c, layout, m);
  for (int j = 0; j < of.centeringSize(); j++)
    mesh.initializeSpacings(of.subField(0, j).engine(), of.centering(j));
  return of;
}
template<class Mesh>
struct NormalsTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::VectorType_t,
    typename Mesh::NormalsEngineTag_t> Type_t;
};
template<class Mesh, class T, class EngineTag>
typename NormalsTraits<Mesh>::Type_t
outwardNormals(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  Centering<Mesh::dimensions> c =
    canonicalCentering<Mesh::dimensions>(FaceType, Discontinuous);
  typename NormalsTraits<Mesh>::Type_t
    of(f.numMaterials(), c, f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializeNormals(of.subField(i, j).engine(), of.centering(j), true);
  return of;
}
template<class Mesh, class T, class EngineTag>
typename NormalsTraits<Mesh>::Type_t
coordinateNormals(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  Centering<Mesh::dimensions> c =
    canonicalCentering<Mesh::dimensions>(FaceType, Continuous);
  typename NormalsTraits<Mesh>::Type_t
    of(f.numMaterials(), c, f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializeNormals(of.subField(i, j).engine(), of.centering(j), false);
  return of;
}
template<class Mesh>
struct CellVolumesTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::Scalar_t,
    typename Mesh::CellVolumesEngineTag_t> Type_t;
};
template<class Mesh, class T, class EngineTag>
typename CellVolumesTraits<Mesh>::Type_t
cellVolumes(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  Centering<Mesh::dimensions> c =
    canonicalCentering<Mesh::dimensions>(CellType, Continuous);
  typename CellVolumesTraits<Mesh>::Type_t
    of(f.numMaterials(), c, f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    f.mesh().initializeCellVolumes(of.subField(i, 0).engine(), of.centering(0));
  return of;
}
template<class Mesh>
struct FaceAreasTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::Scalar_t,
    typename Mesh::FaceAreasEngineTag_t> Type_t;
};
template<class Mesh, class T, class EngineTag>
typename FaceAreasTraits<Mesh>::Type_t
faceAreas(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  Centering<Mesh::dimensions> c =
    canonicalCentering<Mesh::dimensions>(FaceType, Continuous);
  typename FaceAreasTraits<Mesh>::Type_t
    of(f.numMaterials(), c, f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializeFaceAreas(of.subField(i, j).engine(), of.centering(j));
  return of;
}
template<class Mesh>
struct EdgeLengthsTraits {
  typedef Field<NoMesh<Mesh::dimensions>,
    typename Mesh::Scalar_t,
    typename Mesh::EdgeLengthsEngineTag_t> Type_t;
};
template<class Mesh, class T, class EngineTag>
typename EdgeLengthsTraits<Mesh>::Type_t
edgeLengths(const Field<Mesh, T, EngineTag> &f)
{
  NoMesh<Mesh::dimensions> m(f.layout());
  Centering<Mesh::dimensions> c =
    canonicalCentering<Mesh::dimensions>(EdgeType, Continuous);
  typename EdgeLengthsTraits<Mesh>::Type_t
    of(f.numMaterials(), c, f.layout(), m);
  for (int i = 0; i < of.numMaterials(); i++)
    for (int j = 0; j < of.centeringSize(); j++)
      f.mesh().initializeEdgeLengths(of.subField(i, j).engine(), of.centering(j));
  return of;
}
}
using Pooma::PositionsTraits;
using Pooma::positions;
using Pooma::NormalsTraits;
using Pooma::outwardNormals;
using Pooma::coordinateNormals;
using Pooma::CellVolumesTraits;
using Pooma::cellVolumes;
using Pooma::FaceAreasTraits;
using Pooma::faceAreas;
using Pooma::EdgeLengthsTraits;
using Pooma::edgeLengths;
class InfluenceRelation : public RelationListItem
{
public:
  template<class Target>
  InfluenceRelation(const Target &t)
  : RelationListItem(),
    list_m(const_cast<RelationList*>(&t.fieldEngine().relations()))
    {
      setPriority(100u);
    }
  InfluenceRelation(const InfluenceRelation &model)
  : RelationListItem(model), list_m(model.list_m)
    { }
  InfluenceRelation() { }
  void setDirty()
    {
      if (!dirty())
        {
          RelationListItem::setDirty();
          list_m->setDirty();
        }
    }
  void apply() { }
private:
  RelationList *list_m;
};
template<class Target, class RelationFunctor>
class Relation0: public RelationBase<Target, RelationFunctor>
{
public:
  Relation0(const Target &t, const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f)
  { }
  ~Relation0()
  { }
  void apply()
  {
    this->functor_m(this->target_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    return new Relation0<Target, RelationFunctor>(target, this->functor_m);
  }
};
template<class Target, class R1, class RelationFunctor>
class Relation1: public RelationBase<Target, RelationFunctor>
{
public:
  Relation1(const Target &t, const R1 &r,
    const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f), r1_m(r)
  { }
  ~Relation1()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    return new Relation1<Target, R1, RelationFunctor>
                 (target, r1_m, this->functor_m);
  }
protected:
  R1 r1_m;
};
template<class Target, class R1, class R2, class RelationFunctor>
class Relation2: public RelationBase<Target, RelationFunctor>
{
public:
  Relation2(const Target &t, const R1 &r1, const R2 &r2,
    const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f), r1_m(r1), r2_m(r2)
  { }
  ~Relation2()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m, r2_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    r2_m.addRelation(new InfluenceRelation(target));
    return new Relation2<Target, R1, R2, RelationFunctor>
                 (target, r1_m, r2_m, this->functor_m);
  }
protected:
  R1 r1_m;
  R2 r2_m;
};
template<class Target, class R1, class R2, class R3, class RelationFunctor>
class Relation3: public RelationBase<Target, RelationFunctor>
{
public:
  Relation3(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
            const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f),
    r1_m(r1),
    r2_m(r2),
    r3_m(r3)
  { }
  ~Relation3()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m, r2_m, r3_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    r2_m.addRelation(new InfluenceRelation(target));
    r3_m.addRelation(new InfluenceRelation(target));
    return new Relation3<Target, R1, R2, R3, RelationFunctor>
      (target, r1_m, r2_m, r3_m, this->functor_m);
  }
protected:
  R1 r1_m;
  R2 r2_m;
  R3 r3_m;
};
template<class Target, class R1, class R2, class R3, class R4,
         class RelationFunctor>
class Relation4: public RelationBase<Target, RelationFunctor>
{
public:
  Relation4(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
            const R4 &r4, const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f),
    r1_m(r1),
    r2_m(r2),
    r3_m(r3),
    r4_m(r4)
  { }
  ~Relation4()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    r2_m.addRelation(new InfluenceRelation(target));
    r3_m.addRelation(new InfluenceRelation(target));
    r4_m.addRelation(new InfluenceRelation(target));
    return new Relation4<Target, R1, R2, R3, R4, RelationFunctor>
      (target, r1_m, r2_m, r3_m, r4_m, this->functor_m);
  }
protected:
  R1 r1_m;
  R2 r2_m;
  R3 r3_m;
  R4 r4_m;
};
template<class Target, class R1, class R2, class R3, class R4, class R5,
         class RelationFunctor>
class Relation5: public RelationBase<Target, RelationFunctor>
{
public:
  Relation5(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
            const R4 &r4, const R5 &r5, const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f),
    r1_m(r1),
    r2_m(r2),
    r3_m(r3),
    r4_m(r4),
    r5_m(r5)
  { }
  ~Relation5()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m, r5_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    r2_m.addRelation(new InfluenceRelation(target));
    r3_m.addRelation(new InfluenceRelation(target));
    r4_m.addRelation(new InfluenceRelation(target));
    r5_m.addRelation(new InfluenceRelation(target));
    return new Relation5<Target, R1, R2, R3, R4, R5, RelationFunctor>
      (target, r1_m, r2_m, r3_m, r4_m, r5_m, this->functor_m);
  }
protected:
  R1 r1_m;
  R2 r2_m;
  R3 r3_m;
  R4 r4_m;
  R5 r5_m;
};
template<class Target, class R1, class R2, class R3, class R4, class R5,
         class R6, class RelationFunctor>
class Relation6: public RelationBase<Target, RelationFunctor>
{
public:
  Relation6(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
            const R4 &r4, const R5 &r5, const R6 &r6, const RelationFunctor &f)
  : RelationBase<Target, RelationFunctor>(t, f),
    r1_m(r1),
    r2_m(r2),
    r3_m(r3),
    r4_m(r4),
    r5_m(r5),
    r6_m(r6)
  { }
  ~Relation6()
  { }
  void apply()
  {
    this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m, r5_m, r6_m);
  }
  virtual RelationListItem *retarget(const Target &target) const
  {
    r1_m.addRelation(new InfluenceRelation(target));
    r2_m.addRelation(new InfluenceRelation(target));
    r3_m.addRelation(new InfluenceRelation(target));
    r4_m.addRelation(new InfluenceRelation(target));
    r5_m.addRelation(new InfluenceRelation(target));
    r6_m.addRelation(new InfluenceRelation(target));
    return new Relation6<Target, R1, R2, R3, R4, R5, R6, RelationFunctor>
      (target, r1_m, r2_m, r3_m, r4_m, r5_m, r6_m, this->functor_m);
  }
protected:
  R1 r1_m;
  R2 r2_m;
  R3 r3_m;
  R4 r4_m;
  R5 r5_m;
  R6 r6_m;
};
template<class L>
class RelationFunctionPtr0 {
public:
  RelationFunctionPtr0(void (*f)(const L &))
  : f_m(f)
  { }
  RelationFunctionPtr0(const RelationFunctionPtr0<L> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l)
  {
    f_m(l);
  }
private:
  void (*f_m)(const L &);
};
template<class L, class R1>
class RelationFunctionPtr1 {
public:
  RelationFunctionPtr1(void (*f)(const L &, const R1 &))
  : f_m(f)
  { }
  RelationFunctionPtr1(const RelationFunctionPtr1<L, R1> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1)
  {
    f_m(l, r1);
  }
private:
  void (*f_m)(const L &, const R1 &);
};
template<class L, class R1, class R2>
class RelationFunctionPtr2 {
public:
  RelationFunctionPtr2(void (*f)(const L &, const R1 &, const R2 &))
  : f_m(f)
  { }
  RelationFunctionPtr2(const RelationFunctionPtr2<L, R1, R2> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2)
  {
    f_m(l, r1, r2);
  }
private:
  void (*f_m)(const L &, const R1 &, const R2 &);
};
template<class L, class R1, class R2, class R3>
class RelationFunctionPtr3 {
public:
  RelationFunctionPtr3(void (*f)(const L &,
    const R1 &, const R2 &, const R3 &))
  : f_m(f)
  { }
  RelationFunctionPtr3(
    const RelationFunctionPtr3<L, R1, R2, R3> &model)
  : f_m(model.f_m)
  { }
  RelationFunctionPtr3(
    const RelationFunctionPtr3<L, R1, R2, R3> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3)
  {
    f_m(l, r1, r2, r3);
  }
private:
  void (*f_m)(const L &, const R1 &, const R2 &, const R3 &);
};
template<class L, class R1, class R2, class R3, class R4>
class RelationFunctionPtr4 {
public:
  RelationFunctionPtr4(void (*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &))
  : f_m(f)
  { }
  RelationFunctionPtr4(
    const RelationFunctionPtr4<L, R1, R2, R3, R4> &model)
  : f_m(model.f_m)
  { }
  RelationFunctionPtr4(
    const RelationFunctionPtr4<L, R1, R2, R3, R4> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4)
  {
    f_m(l, r1, r2, r3, r4);
  }
private:
  void (*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &);
};
template<class L,
  class R1, class R2, class R3, class R4, class R5>
class RelationFunctionPtr5 {
public:
  RelationFunctionPtr5(void (*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &, const R5 &))
  : f_m(f)
  { }
  RelationFunctionPtr5(
    const RelationFunctionPtr5<L, R1, R2, R3, R4, R5> &model)
  : f_m(model.f_m)
  { }
  RelationFunctionPtr5(
    const RelationFunctionPtr5<L, R1, R2, R3, R4, R5> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4, const R5 &r5)
  {
    f_m(l, r1, r2, r3, r4, r5);
  }
private:
  void (*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &, const R5 &);
};
template<class L,
  class R1, class R2, class R3, class R4, class R5, class R6>
class RelationFunctionPtr6 {
public:
  RelationFunctionPtr6(void (*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &, const R5 &, const R6 &))
  : f_m(f)
  { }
  RelationFunctionPtr6(
    const RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6> &model)
  : f_m(model.f_m)
  { }
  RelationFunctionPtr6(
    const RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6> &init, const L &)
  : f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
  {
    f_m(l, r1, r2, r3, r4, r5, r6);
  }
private:
  void (*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &, const R5 &, const R6 &);
};
template<class C, class L>
class RelationMemberPtr0 {
public:
  RelationMemberPtr0(const C &obj, void (C::*f)(const L &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr0(const RelationMemberPtr0<C, L> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr0(const RelationMemberPtr0<C, L> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l)
  {
    (obj_m.*f_m)(l);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &);
};
template<class C, class L, class R1>
class RelationMemberPtr1 {
public:
  RelationMemberPtr1(const C &obj, void (C::*f)(const L &,
    const R1 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr1(const RelationMemberPtr1<C, L, R1> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr1(const RelationMemberPtr1<C, L, R1> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1)
  {
    (obj_m.*f_m)(l, r1);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &);
};
template<class C, class L, class R1, class R2>
class RelationMemberPtr2 {
public:
  RelationMemberPtr2(const C &obj, void (C::*f)(const L &,
    const R1 &, const R2 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr2(const RelationMemberPtr2<C, L, R1, R2> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr2(const RelationMemberPtr2<C, L, R1, R2> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2)
  {
    (obj_m.*f_m)(l, r1, r2);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &, const R2 &);
};
template<class C, class L, class R1, class R2, class R3>
class RelationMemberPtr3 {
public:
  RelationMemberPtr3(const C &obj, void (C::*f)(const L &,
    const R1 &, const R2 &, const R3 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr3(
    const RelationMemberPtr3<C, L, R1, R2, R3> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr3(
    const RelationMemberPtr3<C, L, R1, R2, R3> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3)
  {
    (obj_m.*f_m)(l, r1, r2, r3);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &, const R2 &, const R3 &);
};
template<class C, class L, class R1, class R2, class R3, class R4>
class RelationMemberPtr4 {
public:
  RelationMemberPtr4(const C &obj, void (C::*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr4(
    const RelationMemberPtr4<C, L, R1, R2, R3, R4> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr4(
    const RelationMemberPtr4<C, L, R1, R2, R3, R4> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4)
  {
    (obj_m.*f_m)(l, r1, r2, r3, r4);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &);
};
template<class C, class L,
  class R1, class R2, class R3, class R4, class R5>
class RelationMemberPtr5 {
public:
  RelationMemberPtr5(const C &obj, void (C::*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &, const R5 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr5(
    const RelationMemberPtr5<C, L, R1, R2, R3, R4, R5> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr5(
    const RelationMemberPtr5<C, L, R1, R2, R3, R4, R5> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4, const R5 &r5)
  {
    (obj_m.*f_m)(l, r1, r2, r3, r4, r5);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &, const R5 &);
};
template<class C, class L,
  class R1, class R2, class R3, class R4, class R5, class R6>
class RelationMemberPtr6 {
public:
  RelationMemberPtr6(const C &obj, void (C::*f)(const L &,
    const R1 &, const R2 &, const R3 &, const R4 &, const R5 &, const R6 &))
  : obj_m(obj), f_m(f)
  { }
  RelationMemberPtr6(
    const RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6> &model)
  : obj_m(model.obj_m), f_m(model.f_m)
  { }
  RelationMemberPtr6(
    const RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6> &init, const L &)
  : obj_m(init.obj_m), f_m(init.f_m)
  { }
  inline void operator()(const L &l, const R1 &r1, const R2 &r2,
    const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
  {
    (obj_m.*f_m)(l, r1, r2, r3, r4, r5, r6);
  }
private:
  C obj_m;
  void (C::*f_m)(const L &, const R1 &, const R2 &,
    const R3 &, const R4 &, const R5 &, const R6 &);
};
template<class RelationFunctor>
struct RelationFunctorTraits {
  enum { defaultPriority = 0 };
};
namespace Pooma {
  template<class RelationFunctor, class L>
  void newRelation(const RelationFunctor &f, const L &l)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            RelationListItem *r = new Relation0<L, RelationFunctor>(lsub, f);
            r->setPriority(RelationFunctorTraits<RelationFunctor>::defaultPriority);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r = new
              Relation1<L, R1, RelationFunctor>
                (lsub, r1sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1, class R2>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1, const R2 &r2)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            const R2 &r2sub = r2.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            r2sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r =
              new Relation2<L, R1, R2, RelationFunctor>(lsub, r1sub, r2sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1, class R2, class R3>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1, const R2 &r2, const R3 &r3)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            const R2 &r2sub = r2.subField(m, c);
            const R3 &r3sub = r3.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            r2sub.addRelation(new InfluenceRelation(lsub));
            r3sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r = new
              Relation3<L, R1, R2, R3, RelationFunctor>
                (lsub, r1sub, r2sub, r3sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1, class R2, class R3,
    class R4>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1, const R2 &r2,
                   const R3 &r3, const R4 &r4)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            const R2 &r2sub = r2.subField(m, c);
            const R3 &r3sub = r3.subField(m, c);
            const R4 &r4sub = r4.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            r2sub.addRelation(new InfluenceRelation(lsub));
            r3sub.addRelation(new InfluenceRelation(lsub));
            r4sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r = new
              Relation4<L, R1, R2, R3, R4, RelationFunctor>
                (lsub, r1sub, r2sub, r3sub, r4sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1, class R2, class R3,
    class R4, class R5>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1, const R2 &r2,
                   const R3 &r3, const R4 &r4, const R5 &r5)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            const R2 &r2sub = r2.subField(m, c);
            const R3 &r3sub = r3.subField(m, c);
            const R4 &r4sub = r4.subField(m, c);
            const R5 &r5sub = r5.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            r2sub.addRelation(new InfluenceRelation(lsub));
            r3sub.addRelation(new InfluenceRelation(lsub));
            r4sub.addRelation(new InfluenceRelation(lsub));
            r5sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r = new
              Relation5<L, R1, R2, R3, R4, R5, RelationFunctor>
                (lsub, r1sub, r2sub, r3sub, r4sub, r5sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class RelationFunctor, class L, class R1, class R2, class R3,
    class R4, class R5, class R6>
  void newRelation(const RelationFunctor &f, const L &l,
                   const R1 &r1, const R2 &r2,
                   const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
  {
    for (int m = 0; m < l.numMaterials(); ++m)
      {
        for (int c = 0; c < l.centeringSize(); ++c)
          {
            const L &lsub = l.subField(m, c);
            const R1 &r1sub = r1.subField(m, c);
            const R2 &r2sub = r2.subField(m, c);
            const R3 &r3sub = r3.subField(m, c);
            const R4 &r4sub = r4.subField(m, c);
            const R5 &r5sub = r5.subField(m, c);
            const R6 &r6sub = r6.subField(m, c);
            r1sub.addRelation(new InfluenceRelation(lsub));
            r2sub.addRelation(new InfluenceRelation(lsub));
            r3sub.addRelation(new InfluenceRelation(lsub));
            r4sub.addRelation(new InfluenceRelation(lsub));
            r5sub.addRelation(new InfluenceRelation(lsub));
            r6sub.addRelation(new InfluenceRelation(lsub));
            RelationListItem *r = new
              Relation6<L, R1, R2, R3, R4, R5, R6, RelationFunctor>
                (lsub, r1sub, r2sub, r3sub, r4sub, r5sub, r6sub, f);
            lsub.addRelation(r);
          }
      }
  }
  template<class L>
  RelationFunctionPtr0<L>
  functionPtr(void (*f)(const L &))
  {
    return RelationFunctionPtr0<L>(f);
  }
  template<class L, class R1>
  RelationFunctionPtr1<L, R1>
  functionPtr(void (*f)(const L &, const R1 &))
  {
    return RelationFunctionPtr1<L, R1>(f);
  }
  template<class L, class R1, class R2>
  RelationFunctionPtr2<L, R1, R2>
  functionPtr(void (*f)(const L &, const R1 &, const R2 &))
  {
    return RelationFunctionPtr2<L, R1, R2>(f);
  }
  template<class L, class R1, class R2, class R3>
  RelationFunctionPtr3<L, R1, R2, R3>
  functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &))
  {
    return RelationFunctionPtr3<L, R1, R2, R3>(f);
  }
  template<class L, class R1, class R2, class R3, class R4>
  RelationFunctionPtr4<L, R1, R2, R3, R4>
  functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4))
  {
    return RelationFunctionPtr4<L, R1, R2, R3, R4>(f);
  }
  template<class L, class R1, class R2, class R3,
    class R4, class R5>
  RelationFunctionPtr5<L, R1, R2, R3, R4, R5>
  functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4, const R5 &r5))
  {
    return RelationFunctionPtr5<L, R1, R2, R3, R4, R5>(f);
  }
  template<class L, class R1, class R2, class R3,
    class R4, class R5, class R6>
  RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6>
  functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4, const R5 &r5, const R6 &r6))
  {
    return RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6>(f);
  }
  template<class C, class L>
  RelationMemberPtr0<C, L>
  memberPtr(const C &obj, void (C::*f)(const L &))
  {
    return RelationMemberPtr0<C, L>(obj, f);
  }
  template<class C, class L, class R1>
  RelationMemberPtr1<C, L, R1>
  memberPtr(const C &obj, void (C::*f)(const L &, const R1 &))
  {
    return RelationMemberPtr1<C, L, R1>(obj, f);
  }
  template<class C, class L, class R1, class R2>
  RelationMemberPtr2<C, L, R1, R2>
  memberPtr(const C &obj, void (C::*f)(const L &, const R1 &, const R2 &))
  {
    return RelationMemberPtr2<C, L, R1, R2>(obj, f);
  }
  template<class C, class L, class R1, class R2, class R3>
  RelationMemberPtr3<C, L, R1, R2, R3>
  memberPtr(const C &obj,
    void (C::*f)(const L &, const R1 &, const R2 &, const R3 &))
  {
    return RelationMemberPtr3<C, L, R1, R2, R3>(obj, f);
  }
  template<class C, class L, class R1, class R2, class R3,
    class R4>
  RelationMemberPtr4<C, L, R1, R2, R3, R4>
  memberPtr(const C &obj,
    void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4))
  {
    return RelationMemberPtr4<C, L, R1, R2, R3, R4>(obj, f);
  }
  template<class C, class L, class R1, class R2, class R3,
    class R4, class R5>
  RelationMemberPtr5<C, L, R1, R2, R3, R4, R5>
  memberPtr(const C &obj,
    void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4, const R5 &r5))
  {
    return RelationMemberPtr5<C, L, R1, R2, R3, R4, R5>(obj, f);
  }
  template<class C, class L, class R1, class R2, class R3,
    class R4, class R5, class R6>
  RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6>
  memberPtr(const C &obj,
    void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
    const R4 &r4, const R5 &r5, const R6 &r6))
  {
    return RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6>(obj, f);
  }
}
template<int Dim, class T>
class ConstantFaceBC
{
public:
  ConstantFaceBC(int face, const T &constant,
    bool enforceConstantBoundary = false)
  : domain_m(Pooma::NoInit()),
    face_m(face),
    constant_m(constant),
    enforceConstantBoundary_m(enforceConstantBoundary)
    { }
  ConstantFaceBC(const ConstantFaceBC<Dim, T> &model)
  : domain_m(model.domain_m),
    face_m(model.face_m),
    constant_m(model.constant_m),
    enforceConstantBoundary_m(model.enforceConstantBoundary_m)
    { }
  template<class Target>
  ConstantFaceBC(const ConstantFaceBC<Dim, T> &init, const Target &t)
  : domain_m(t.totalDomain()),
    face_m(init.face_m),
    constant_m(init.constant_m),
    enforceConstantBoundary_m(init.enforceConstantBoundary_m)
  {
    ;
    int d = face_m / 2;
    int adjust;
    if (enforceConstantBoundary_m &&
        t.centering().orientation(0)[d].min() == 0)
      adjust = 0;
    else
      adjust = 1;
    if (face_m & 1)
      {
        int nGuards = t.fieldEngine().guardLayers().upper(d);
        domain_m[d] = Interval<1>(domain_m[d].max() - nGuards + adjust,
             domain_m[d].max());
      }
    else
      {
        int nGuards = t.fieldEngine().guardLayers().lower(d);
        domain_m[d] = Interval<1>(domain_m[d].min(),
      domain_m[d].min() + nGuards - adjust);
      }
  }
  ConstantFaceBC<Dim, T> &operator=(const ConstantFaceBC<Dim, T> &rhs)
  {
    domain_m = rhs.domain_m;
    face_m = rhs.face_m;
    constant_m = rhs.constant_m;
    enforceConstantBoundary_m = rhs.enforceConstantBoundary_m;
    return *this;
  }
  T constant() const { return constant_m; }
  void setConstant(T newConstant) { constant_m = newConstant; }
  int face() const { return face_m; }
  template<class Target>
  void operator()(const Target &t) const
  {
    t(domain_m) = constant_m;
  }
private:
  Interval<Dim> domain_m;
  int face_m;
  T constant_m;
  bool enforceConstantBoundary_m;
};
template<int Dim, class T>
struct RelationFunctorTraits<ConstantFaceBC<Dim, T> > {
  enum { defaultPriority = 100 };
};
namespace Pooma {
  template<class Target, class T>
  void addConstantFaceBC(const Target &f, int face, const T &constant,
    bool enforceConstantBoundary = false)
  {
    newRelation(ConstantFaceBC<Target::dimensions, T>
      (face, constant, enforceConstantBoundary), f);
  }
  template<class Target, class T>
  void addAllConstantFaceBC(const Target &f, const T &constant,
    bool enforceConstantBoundary = false)
  {
    for (int i = 0; i < 2 * Target::dimensions; i++)
      {
        addConstantFaceBC(f, i, constant, enforceConstantBoundary);
      }
  }
}
template<int Dim>
class ReflectFaceBase
{
public:
  ReflectFaceBase(int face, bool enforceZeroBoundary = false)
  : domain_m(Pooma::NoInit()),
    vertFaceDomain_m(Pooma::NoInit()),
    srcRange_m(Pooma::NoInit()),
    face_m(face),
    enforceZeroBoundary_m(enforceZeroBoundary)
    { }
  ReflectFaceBase(const ReflectFaceBase<Dim> &model)
  : domain_m(model.domain_m),
    vertFaceDomain_m(model.vertFaceDomain_m),
    srcRange_m(model.srcRange_m),
    face_m(model.face_m),
    enforceZeroBoundary_m(model.enforceZeroBoundary_m)
    { }
  template<class Target>
  ReflectFaceBase(const ReflectFaceBase<Dim> &init, const Target &t)
  : domain_m(t.totalDomain()),
    vertFaceDomain_m(t.totalDomain()),
    srcRange_m(Pooma::NoInit()),
    face_m(init.face_m),
    enforceZeroBoundary_m(init.enforceZeroBoundary_m)
  {
    ;
    for (int dd = 0; dd < Dim; ++dd)
      {
        srcRange_m[dd] =
          Range<1>(domain_m[dd].min(), domain_m[dd].max(), 1);
      }
    int d = face_m / 2;
    int adjust = 1 - t.centering().orientation(0)[d].min();
    if (face_m & 1)
      {
        int nGuards = t.fieldEngine().guardLayers().upper(d);
 if (adjust == 1)
   {
            vertFaceDomain_m[d] =
       Interval<1>(t.physicalDomain()[d].max(),
     t.physicalDomain()[d].max());
          }
        srcRange_m[d] =
          Range<1>(t.physicalDomain()[d].max() - adjust,
     t.physicalDomain()[d].max() - adjust - (nGuards - 1),
     -1);
        domain_m[d] = Interval<1>(domain_m[d].max() - (nGuards - 1),
      domain_m[d].max());
      }
    else
      {
        int nGuards = t.fieldEngine().guardLayers().lower(d);
 if (adjust == 1)
   {
            vertFaceDomain_m[d] =
              Interval<1>(t.physicalDomain()[d].min(),
     t.physicalDomain()[d].min());
    }
        srcRange_m[d] =
          Range<1>(t.physicalDomain()[d].min() + adjust +
     (nGuards - 1),
     t.physicalDomain()[d].min() + adjust, -1);
 domain_m[d] = Interval<1>(domain_m[d].min(),
      domain_m[d].min() + (nGuards - 1));
      }
  }
  ReflectFaceBase<Dim> &operator=(const ReflectFaceBase<Dim> &rhs)
  {
    domain_m = rhs.domain_m;
    vertFaceDomain_m = rhs.vertFaceDomain_m;
    srcRange_m = rhs.srcRange_m;
    face_m = rhs.face_m;
    enforceZeroBoundary_m = rhs.enforceZeroBoundary_m;
    return *this;
  }
  int face() const { return face_m; }
  bool enforceZeroBoundary() const { return enforceZeroBoundary_m; }
protected:
  Interval<Dim> domain_m, vertFaceDomain_m;
  Range<Dim> srcRange_m;
  int face_m;
  bool enforceZeroBoundary_m;
};
template<int Dim>
class PosReflectFaceBC : public ReflectFaceBase<Dim>
{
public:
  PosReflectFaceBC(int face, bool enforceZeroBoundary = false)
    : ReflectFaceBase<Dim>(face, enforceZeroBoundary)
  {}
  template<class Target>
  PosReflectFaceBC(const PosReflectFaceBC<Dim>& init, const Target &t)
    : ReflectFaceBase<Dim>(init, t)
  {}
  template<class Target>
  void operator()(const Target &t) const
  {
    t(this->domain_m) = t(this->srcRange_m);
    if (this->enforceZeroBoundary_m &&
        t.centering().orientation(0)[this->face_m / 2].min() == 0)
      {
        typedef typename Target::Element_t T;
        t(this->vertFaceDomain_m) = T(0.0);
      }
  }
};
template<int Dim>
class NegReflectFaceBC : public ReflectFaceBase<Dim>
{
public:
  NegReflectFaceBC(int face, bool enforceZeroBoundary = false)
    : ReflectFaceBase<Dim>(face, enforceZeroBoundary)
  {}
  template<class Target>
  NegReflectFaceBC(const NegReflectFaceBC<Dim>& init, const Target &t)
    : ReflectFaceBase<Dim>(init, t)
  {}
  template<class Target>
  void operator()(const Target &t) const
  {
    t(this->domain_m) = -t(this->srcRange_m);
    if (this->enforceZeroBoundary_m &&
        t.centering().orientation(0)[this->face_m / 2].min() == 0)
      {
        typedef typename Target::Element_t T;
        t(this->vertFaceDomain_m) = T(0.0);
      }
  }
};
template<int Dim>
struct RelationFunctorTraits<PosReflectFaceBC<Dim> > {
  enum { defaultPriority = 100 };
};
template<int Dim>
struct RelationFunctorTraits<NegReflectFaceBC<Dim> > {
  enum { defaultPriority = 100 };
};
namespace Pooma {
  template<class Target>
  void addPosReflectFaceBC(const Target &f, int face,
    bool enforceZeroBoundary = false)
  {
      newRelation(PosReflectFaceBC<Target::dimensions>
        (face, enforceZeroBoundary), f);
  }
  template<class Target>
  void addAllPosReflectFaceBC(const Target &f, bool enforceZeroBoundary = false)
  {
    for (int i = 0; i < 2 * Target::dimensions; i++)
      {
        addPosReflectFaceBC(f, i, enforceZeroBoundary);
      }
  }
  template<class Target>
  void addNegReflectFaceBC(const Target &f, int face,
    bool enforceZeroBoundary = false)
  {
      newRelation(NegReflectFaceBC<Target::dimensions>
        (face, enforceZeroBoundary), f);
  }
  template<class Target>
  void addAllNegReflectFaceBC(const Target &f, bool enforceZeroBoundary = false)
  {
    for (int i = 0; i < 2 * Target::dimensions; i++)
      {
        addNegReflectFaceBC(f, i, enforceZeroBoundary);
      }
  }
}
template<int Dim>
class PeriodicFaceBC
{
public:
  PeriodicFaceBC(int face)
  : domain_m(Pooma::NoInit()),
    srcDomain_m(Pooma::NoInit()),
    face_m(face)
    { }
  PeriodicFaceBC(const PeriodicFaceBC<Dim> &model)
  : domain_m(model.domain_m),
    srcDomain_m(model.srcDomain_m),
    face_m(model.face_m)
    { }
  template<class Target>
  PeriodicFaceBC(const PeriodicFaceBC<Dim> &init, const Target &t)
  : domain_m(t.totalDomain()),
    srcDomain_m(t.totalDomain()),
    face_m(init.face_m)
  {
    ;
    int d = face_m / 2;
    int adjust = 1 - t.centering().orientation(0)[d].min();
    if (face_m & 1)
      {
        int nGuards = t.fieldEngine().guardLayers().upper(d);
 domain_m[d] =
          Interval<1>(domain_m[d].max() - nGuards,
               domain_m[d].max());
 srcDomain_m[d] =
   Interval<1>(domain_m[d].min() -
        (t.physicalDomain()[d].length() - 1 - adjust),
         domain_m[d].max() -
         (t.physicalDomain()[d].length() - 1 - adjust));
      }
    else
      {
        int nGuards = t.fieldEngine().guardLayers().lower(d);
 domain_m[d] = Interval<1>(domain_m[d].min(),
      domain_m[d].min() + (nGuards - 1) + adjust);
 srcDomain_m[d] =
   Interval<1>(domain_m[d].min() +
        (t.physicalDomain()[d].length() - 1 - adjust),
        domain_m[d].max() +
         (t.physicalDomain()[d].length() - 1 - adjust));
      }
  }
  PeriodicFaceBC<Dim> &operator=(const PeriodicFaceBC<Dim> &rhs)
  {
    if (&rhs != this)
      {
        domain_m = rhs.domain_m;
        srcDomain_m = rhs.srcDomain_m;
        face_m = rhs.face_m;
      }
    return *this;
  }
  int face() const { return face_m; }
  template<class Target>
  void operator()(const Target &t) const
  {
    t(domain_m) = t(srcDomain_m);
  }
private:
  Interval<Dim> domain_m, srcDomain_m;
  int face_m;
};
template<int Dim>
struct RelationFunctorTraits<PeriodicFaceBC<Dim> > {
  enum { defaultPriority = 100 };
};
namespace Pooma {
  template<class Target>
  void addPeriodicFaceBC(const Target &f, int face)
  {
    newRelation(PeriodicFaceBC<Target::dimensions>(face), f);
  }
  template<class Target>
  void addAllPeriodicFaceBC(const Target &f)
  {
    for (int i = 0; i < 2 * Target::dimensions; i++)
      {
        addPeriodicFaceBC(f, i);
      }
  }
}
template<int Dim>
class ZeroGradientFaceBC
{
public:
  ZeroGradientFaceBC(int face)
  : srcDomain_m(Pooma::NoInit()),
    face_m(face)
    { }
  ZeroGradientFaceBC(const ZeroGradientFaceBC<Dim> &model)
  : srcDomain_m(model.srcDomain_m),
    domains_m(model.domains_m),
    face_m(model.face_m)
    { }
  template<class Target>
  ZeroGradientFaceBC(const ZeroGradientFaceBC<Dim> &init, const Target &t)
  : srcDomain_m(t.totalDomain()),
    face_m(init.face_m)
  {
    ;
    int d = face_m / 2;
    int adjust = 1 - t.centering().orientation(0)[d].min();
    if (face_m & 1)
      {
        int nGuards = t.fieldEngine().guardLayers().upper(d);
 domains_m.resize(nGuards+adjust, t.totalDomain());
 srcDomain_m[d] =
          Interval<1>(t.physicalDomain()[d].max() - adjust,
               t.physicalDomain()[d].max() - adjust);
 for (int i=0; i<nGuards+adjust; i++)
   domains_m[i][d] =
     Interval<1>(t.physicalDomain()[d].max() -adjust + i + 1,
   t.physicalDomain()[d].max() -adjust + i + 1);
      }
    else
      {
        int nGuards = t.fieldEngine().guardLayers().lower(d);
 domains_m.resize(nGuards+adjust, t.totalDomain());
 srcDomain_m[d] = Interval<1>(t.physicalDomain()[d].min()+adjust,
          t.physicalDomain()[d].min()+adjust);
 for (int i=0; i<nGuards+adjust; i++)
   domains_m[i][d] =
     Interval<1>(t.physicalDomain()[d].min() +adjust - i - 1,
   t.physicalDomain()[d].min() +adjust - i - 1);
      }
  }
  ZeroGradientFaceBC<Dim> &operator=(const ZeroGradientFaceBC<Dim> &rhs)
  {
    if (&rhs != this)
      {
        domains_m = rhs.domains_m;
        srcDomain_m = rhs.srcDomain_m;
        face_m = rhs.face_m;
      }
    return *this;
  }
  int face() const { return face_m; }
  template<class Target>
  void operator()(const Target &t) const
  {
    for (int i=0; i<domains_m.size(); i++) {
      t(domains_m[i]) = t(srcDomain_m);
    }
  }
private:
  Interval<Dim> srcDomain_m;
  std::vector<Interval<Dim> > domains_m;
  int face_m;
};
template<int Dim>
struct RelationFunctorTraits<ZeroGradientFaceBC<Dim> > {
  enum { defaultPriority = 100 };
};
namespace Pooma {
  template<class Target>
  void addZeroGradientFaceBC(const Target &f, int face)
  {
    newRelation(ZeroGradientFaceBC<Target::dimensions>(face), f);
  }
  template<class Target>
  void addAllZeroGradientFaceBC(const Target &f)
  {
    for (int i = 0; i < 2 * Target::dimensions; i++)
      {
        addZeroGradientFaceBC(f, i);
      }
  }
}
template<class Functor, class Expression>
struct FieldStencilSimple
{
  typedef typename Expression::MeshTag_t MeshTag_t;
  enum { outputDim = Expression::dimensions };
  typedef typename Functor::OutputElement_t OutputElement_t;
  typedef StencilEngine<Functor, Expression> OutputEngineTag_t;
  typedef Field<MeshTag_t, OutputElement_t, OutputEngineTag_t> Type_t;
  typedef Engine<outputDim, OutputElement_t, OutputEngineTag_t> SEngine_t;
  static inline
  Type_t make(const Functor &stencil, const Expression &f)
  {
 return make(stencil, f, f.physicalDomain());
  }
  static inline
  Type_t make(const Functor &stencil, const Expression &f, const Interval<outputDim> &domain)
  {
 Type_t h(stencil.outputCentering(), f.layout(), f.mesh());
 h.fieldEngine().engine() = SEngine_t(stencil, f, domain);
 return h;
  }
  template<class Accumulate>
  static inline
  Type_t make(const Expression &f,
              const std::vector<FieldOffsetList<outputDim> > &nn,
              const Centering<outputDim> &outputCentering,
              Accumulate accumulate = Accumulate())
  {
    ;
    Type_t h(outputCentering, f.layout(), f.mesh());
    h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
    h.fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
    if (outputCentering.size() == 1)
    {
      h.fieldEngine().engine()
        = SEngine_t(Functor(nn[0], outputCentering, f.centering(),
                            accumulate),
                    f, h.physicalDomain());
    }
    else
    {
      int oc;
      for (oc = 0; oc < nn.size(); ++oc)
      {
        h[oc].fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
        h[oc].fieldEngine().engine()
          = SEngine_t(Functor(nn[oc], outputCentering[oc], f.centering(),
                              accumulate),
                      f, h[oc].physicalDomain());
      }
    }
    return h;
  }
};
template<class T2, class Mesh>
class DivVertToCell;
template<class T2, int Dim, class TM>
class DivVertToCell<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM, UniformRectilinearTag, CartesianTag> > >
{
public:
  typedef T2 OutputElement_t;
  Centering<Dim> outputCentering() const
  {
    return canonicalCentering<Dim>(CellType, Continuous, AllDim);
  }
  Centering<Dim> inputCentering() const
  {
    return canonicalCentering<Dim>(VertexType, Continuous, AllDim);
  }
  DivVertToCell()
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 1.0;
    }
  }
  template<class FE>
  DivVertToCell(const FE &fieldEngine)
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 1 / fieldEngine.mesh().spacings()(d);
    }
  }
  int lowerExtent(int d) const { return 0; }
  int upperExtent(int d) const { return 1; }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1) const
  {
    return OutputElement_t
      (fact_m(0)*(f.read(i1+1)(0) - f.read(i1)(0)));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2) const
  {
    return OutputElement_t
      (0.5*(fact_m(0)*(f.read(i1+1,i2)(0) - f.read(i1,i2)(0)
       + f.read(i1+1,i2+1)(0) - f.read(i1,i2+1)(0))
   + fact_m(1)*(f.read(i1, i2+1)(1) - f.read(i1, i2)(1)
       + f.read(i1+1,i2+1)(1) - f.read(i1+1,i2)(1))));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2, int i3) const
  {
    return OutputElement_t
      (0.25*(fact_m(0)*(f.read(i1+1,i2, i3)(0) - f.read(i1,i2, i3)(0)
        + f.read(i1+1,i2+1,i3)(0) - f.read(i1,i2+1,i3)(0)
        + f.read(i1+1,i2, i3+1)(0) - f.read(i1,i2, i3+1)(0)
        + f.read(i1+1,i2+1,i3+1)(0) - f.read(i1,i2+1,i3+1)(0))
    + fact_m(1)*(f.read(i1, i2+1,i3)(1) - f.read(i1, i2,i3)(1)
        + f.read(i1+1,i2+1,i3)(1) - f.read(i1+1,i2,i3)(1)
        + f.read(i1, i2+1,i3+1)(1) - f.read(i1, i2,i3+1)(1)
        + f.read(i1+1,i2+1,i3+1)(1) - f.read(i1+1,i2,i3+1)(1))
    + fact_m(2)*(f.read(i1, i2, i3+1)(2) - f.read(i1, i2, i3)(2)
        + f.read(i1+1,i2, i3+1)(2) - f.read(i1+1,i2, i3)(2)
        + f.read(i1, i2+1,i3+1)(2) - f.read(i1, i2+1,i3)(2)
        + f.read(i1+1,i2+1,i3+1)(2) - f.read(i1+1,i2+1,i3)(2))));
  }
private:
  Vector<Dim, TM> fact_m;
};
template<class T2, class Mesh>
class DivCellToVert;
template<class T2, int Dim, class TM>
class DivCellToVert<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM> > >
{
public:
  typedef T2 OutputElement_t;
  Centering<Dim> outputCentering() const
  {
    return canonicalCentering<Dim>(CellType, Continuous, AllDim);
  }
  Centering<Dim> inputCentering() const
  {
    return canonicalCentering<Dim>(VertexType, Continuous, AllDim);
  }
  DivCellToVert()
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 1.0;
    }
  }
  template<class FE>
  DivCellToVert(const FE &fieldEngine)
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 1 / fieldEngine.mesh().spacings()(d);
    }
  }
  int lowerExtent(int d) const { return 0; }
  int upperExtent(int d) const { return 1; }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1) const
  {
    return OutputElement_t
      (fact_m(0)*(f.read(i1)(0) - f.read(i1-1)(0)));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2) const
  {
    return OutputElement_t
      (0.5*(fact_m(0)*(f.read(i1,i2-1)(0) - f.read(i1-1,i2-1)(0)
       + f.read(i1,i2)(0) - f.read(i1-1,i2)(0))
   + fact_m(1)*(f.read(i1-1,i2)(1) - f.read(i1-1,i2-1)(1)
       + f.read(i1, i2)(1) - f.read(i1, i2-1)(1))));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2, int i3) const
  {
    return OutputElement_t
      (0.25*(fact_m(0)*(f.read(i1,i2-1,i3-1)(0) - f.read(i1-1,i2-1,i3-1)(0)
        + f.read(i1,i2, i3-1)(0) - f.read(i1-1,i2, i3-1)(0)
        + f.read(i1,i2-1,i3)(0) - f.read(i1-1,i2-1,i3)(0)
        + f.read(i1,i2, i3)(0) - f.read(i1-1,i2, i3)(0))
    + fact_m(1)*(f.read(i1-1,i2,i3-1)(1) - f.read(i1-1,i2-1,i3-1)(1)
        + f.read(i1, i2,i3-1)(1) - f.read(i1, i2-1,i3-1)(1)
        + f.read(i1-1,i2,i3)(1) - f.read(i1-1,i2-1,i3)(1)
        + f.read(i1, i2,i3)(1) - f.read(i1, i2-1,i3)(1))
    + fact_m(2)*(f.read(i1-1,i2-1,i3)(2) - f.read(i1-1,i2-1,i3-1)(2)
        + f.read(i1, i2-1,i3)(2) - f.read(i1, i2-1,i3-1)(2)
        + f.read(i1-1,i2, i3)(2) - f.read(i1-1,i2, i3-1)(2)
        + f.read(i1, i2, i3)(2) - f.read(i1, i2, i3-1)(2))));
  }
private:
  Vector<Dim, TM> fact_m;
};
template<class T2, class Mesh, CenteringType OC>
class DivSameToSame;
template<class T2, int Dim, class TM, CenteringType OC>
class DivSameToSame<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM, UniformRectilinearTag, CartesianTag> >, OC>
{
public:
  typedef T2 OutputElement_t;
  Centering<Dim> outputCentering() const
  {
    return canonicalCentering<Dim>(OC, Continuous);
  }
  Centering<Dim> inputCentering() const
  {
    return canonicalCentering<Dim>(OC, Continuous);
  }
  DivSameToSame()
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 0.5;
    }
  }
  template<class FE>
  DivSameToSame(const FE &fieldEngine)
  {
    for (int d = 0; d < Dim; ++d)
    {
      fact_m(d) = 0.5 / fieldEngine.mesh().spacings()(d);
    }
  }
  int lowerExtent(int d) const { return 1; }
  int upperExtent(int d) const { return 1; }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1) const
  {
    return OutputElement_t
      (fact_m(0)*(f.read(i1+1)(0) - f.read(i1-1)(0)));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2) const
  {
    return OutputElement_t
      (fact_m(0)*(f.read(i1+1,i2)(0) - f.read(i1-1,i2)(0))
     + fact_m(1)*(f.read(i1, i2+1)(1) - f.read(i1, i2-1)(1)));
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2, int i3) const
  {
    return OutputElement_t
      (fact_m(0)*(f.read(i1+1,i2, i3)(0) - f.read(i1-1,i2, i3)(0))
     + fact_m(1)*(f.read(i1, i2+1,i3)(1) - f.read(i1, i2-1,i3)(1))
     + fact_m(2)*(f.read(i1, i2, i3+1)(2) - f.read(i1, i2, i3-1)(2)));
  }
private:
  Vector<Dim, TM> fact_m;
};
template<class T2, class Mesh>
class DivCellToVert;
template<class T2, class Mesh>
class DivVertToCell;
template<class T2, class Mesh, CenteringType OC>
class DivSameToSame;
template<class Mesh, class T, class EngineTag>
typename
FieldStencilSimple<DivSameToSame<T, Mesh, CellType>,
  Field<Mesh, T, EngineTag> >::Type_t
divCellToCell(const Field<Mesh, T, EngineTag> &f)
{
  typedef DivSameToSame<T, Mesh, CellType> Div_t;
  typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
  return Ret_t::make(Div_t(f.fieldEngine()), f);
}
template<class Mesh, class T, class EngineTag>
typename
FieldStencilSimple<DivVertToCell<T, Mesh>,
  Field<Mesh, T, EngineTag> >::Type_t
divVertToCell(const Field<Mesh, T, EngineTag> &f)
{
  typedef DivVertToCell<T, Mesh> Div_t;
  typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
  return Ret_t::make(Div_t(f.fieldEngine()), f);
}
template<class Mesh, class T, class EngineTag>
typename
FieldStencilSimple<DivCellToVert<T, Mesh>,
  Field<Mesh, T, EngineTag> >::Type_t
divCellToVert(const Field<Mesh, T, EngineTag> &f)
{
  typedef DivCellToVert<T, Mesh> Div_t;
  typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
  return Ret_t::make(Div_t(f.fieldEngine()), f);
}
template<class Mesh, class T, class EngineTag>
typename
FieldStencilSimple<DivSameToSame<T, Mesh, VertexType>,
  Field<Mesh, T, EngineTag> >::Type_t
divVertToVert(const Field<Mesh, T, EngineTag> &f)
{
  typedef DivSameToSame<T, Mesh, VertexType> Div_t;
  typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
  return Ret_t::make(Div_t(f.fieldEngine()), f);
}
template<class D1,class T1,class E1>
inline typename MakeReturn<BinaryNode<FnMin,
  typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> >::Expression_t
min(const Field<D1,T1,E1> & l,const Field<D1,T1,E1> & r)
{
  typedef BinaryNode<FnMin,
    typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<D1,T1,E1> >::make(l),
    CreateLeaf<Field<D1,T1,E1> >::make(r)));
}
template<class D1,class T1,class E1>
inline typename MakeReturn<BinaryNode<FnMax,
  typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
  typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> >::Expression_t
max(const Field<D1,T1,E1> & l,const Field<D1,T1,E1> & r)
{
  typedef BinaryNode<FnMax,
    typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
    typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<D1,T1,E1> >::make(l),
    CreateLeaf<Field<D1,T1,E1> >::make(r)));
}
template <int Dim>
class DomainLayout;
template<class Functor> class FieldShift;
template <class Expression>
struct FieldShift;
template<int Dim, class T, class Expression>
class Engine<Dim, T, FieldShift<Expression> >
{
public:
  typedef FieldShift<Expression> Tag_t;
  typedef Expression Expression_t;
  typedef Engine<Dim, T, Tag_t> This_t;
  typedef This_t Engine_t;
  typedef Interval<Dim> Domain_t;
  typedef T Element_t;
  typedef ErrorType ElementRef_t;
  typedef typename Expression_t::Engine_t ExprEngine_t;
  typedef DomainLayout<Dim> Layout_t;
  enum { dimensions = Dim };
  enum { hasDataObject = ExprEngine_t::hasDataObject };
  enum { dynamic = false };
  enum { zeroBased = false };
  enum { multiPatch = ExprEngine_t::multiPatch };
  Engine()
    : domain_m(Pooma::NoInit()), exprEngine_m()
  {
  }
  template<class Layout>
  explicit Engine(const Layout &layout)
    : domain_m(layout.domain()), exprEngine_m()
  {
  }
  Engine(const Expression_t &f, const Loc<Dim> &offset, Domain_t domain)
    : domain_m(domain),
      offset_m(offset),
      exprEngine_m(f)
  {
  }
  Engine(const This_t &model)
    : domain_m(model.domain()),
      offset_m(model.offset_m),
      exprEngine_m(model.exprEngine())
  {
  }
  This_t &operator=(const This_t &model)
  {
    domain_m = model.domain();
    offset_m = model.offset_m;
    exprEngine_m = model.exprEngine();
    return *this;
  }
  inline Element_t read(int i) const
  {
    return exprEngine()(i + offset_m[0].first());
  }
  inline Element_t read(int i, int j) const
  {
    return exprEngine()(i + offset_m[0].first(),
                        j + offset_m[1].first());
  }
  inline Element_t read(int i, int j, int k) const
  {
    return exprEngine()(i + offset_m[0].first(),
                        j + offset_m[1].first(),
                        k + offset_m[2].first());
  }
  inline Element_t read(const Loc<Dim> &loc) const
  {
    return exprEngine()(loc + offset_m);
  }
  inline Element_t operator()(int i) const
  {
    return read(i);
  }
  inline Element_t operator()(int i, int j) const
  {
    return read(i, j);
  }
  inline Element_t operator()(int i, int j, int k) const
  {
    return read(i, j, k);
  }
  inline Element_t operator()(const Loc<Dim> &loc) const
  {
    return read(loc);
  }
  inline const Domain_t &domain() const { return domain_m; }
  inline Loc<Dim> offset() const
  {
    return offset_m;
  }
  inline const Expression_t &exprEngine() const { return exprEngine_m; }
  template<class RequestType>
  inline
  typename DataObjectRequest<RequestType>::Type_t
  dataObjectRequest(const DataObjectRequest<RequestType> &req) const
  {
    return exprEngine().engine().dataObjectRequest(req);
  }
  inline
  Interval<Dim> viewDomain(const Interval<Dim> &domain) const
  {
    Interval<Dim> ret;
    int d;
    for (d = 0; d < Dim; ++d)
    {
      ret[d] =
 Interval<1>(
      domain[d].first() + offset_m[d].first(),
      domain[d].last() + offset_m[d].first()
      );
    }
    return ret;
  }
  inline
  INode<Dim> viewDomain(const INode<Dim> &inode) const
  {
    return INode<Dim>(inode, viewDomain(inode.domain()));
  }
  inline
  Interval<Dim> intersectDomain() const
  {
    Interval<Dim> ret;
    int d;
    for (d = 0; d < Dim; ++d)
    {
      ret[d] =
 Interval<1>(
      domain_m[d].first() + offset_m[d].first(),
                    domain_m[d].last() + offset_m[d].first()
      );
    }
    return ret;
  }
private:
  Interval<Dim> domain_m;
  Loc<Dim> offset_m;
  Expression_t exprEngine_m;
};
template <int Dim, class T, class E>
struct NewEngine<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
{
  typedef typename NewEngine<E, Interval<Dim> >::Type_t Type_t;
};
template <int Dim, class T, class E>
struct NewEngineEngine<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
{
  typedef typename NewEngineEngine<E, Interval<Dim> >::Type_t Type_t;
  static inline
  Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const Interval<Dim> &d)
  {
    return NewEngineEngine<E, Interval<Dim> >::apply(e.exprEngine(),
                                                     e.viewDomain(d));
  }
};
template <int Dim, class T, class E>
struct NewEngineDomain<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
{
  typedef typename NewEngineDomain<E, Interval<Dim> >::Type_t Type_t;
  static inline
  Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const Interval<Dim> &d)
  {
    return NewEngineDomain<E, Interval<Dim> >::apply(e.exprEngine(),
                                                     e.viewDomain(d));
  }
};
template <int Dim, class T, class E>
struct NewEngine<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
{
  typedef typename NewEngine<E, INode<Dim> >::Type_t Type_t;
};
template <int Dim, class T, class E>
struct NewEngineEngine<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
{
  typedef typename NewEngineEngine<E, INode<Dim> >::Type_t Type_t;
  static inline
  Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const INode<Dim> &d)
  {
    return NewEngineEngine<E, INode<Dim> >::apply(e.exprEngine(),
                                                  e.viewDomain(d));
  }
};
template <int Dim, class T, class E>
struct NewEngineDomain<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
{
  typedef typename NewEngineDomain<E, INode<Dim> >::Type_t Type_t;
  static inline
  Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const INode<Dim> &d)
  {
    return NewEngineDomain<E, INode<Dim> >::apply(e.exprEngine(),
                                                  e.viewDomain(d));
  }
};
template<class Expression>
struct FieldShiftSimple
{
  typedef typename Expression::MeshTag_t MeshTag_t;
  typedef typename Expression::Element_t OutputElement_t;
  enum { outputDim = Expression::dimensions };
  typedef typename Expression::Engine_t InputEngine_t;
  typedef FieldShift<InputEngine_t> OutputEngineTag_t;
  typedef Field<MeshTag_t, OutputElement_t, OutputEngineTag_t> Type_t;
  typedef Engine<outputDim, OutputElement_t, OutputEngineTag_t> SEngine_t;
  static inline
  Type_t make(const Expression &f,
       const FieldOffset<outputDim> &s1,
              const Centering<outputDim> &centering)
  {
    Type_t h(centering, f.layout(), f.mesh());
    h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
    Expression fld =
      (f.numSubFields() > 1) ? f[s1.subFieldNumber()] : f;
    const Loc<outputDim> &offset = s1.cellOffset();
    GuardLayers<outputDim> og(fld.fieldEngine().guardLayers());
    for (int d = 0; d < outputDim; d++)
      {
 og.lower(d) += offset[d].first();
 og.upper(d) -= offset[d].first();
      }
    h.fieldEngine().guardLayers() = og;
    h.fieldEngine().engine() = SEngine_t(fld.engine(), offset, fld.domain());
    return h;
  }
  static inline
  Type_t make(const Expression &f,
       const std::vector<FieldOffset<outputDim> > &vs1,
              const Centering<outputDim> &centering)
  {
    typedef typename std::vector<FieldOffset<outputDim> >::size_type size_type;
    Type_t h(centering, f.layout(), f.mesh());
    h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
    if (__builtin_expect(!!(vs1.size() == centering.size()), true)) {} else Pooma::toss_cookies("The FieldOffset vector's length must match the centering's size.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/DiffOps/FieldShiftEngine.h", 433);
    for (size_type s1Index = 0; s1Index < vs1.size(); ++s1Index) {
      const FieldOffset<outputDim> s1 = vs1[s1Index];
      Type_t hField = (h.numSubFields() > 1) ? h[s1Index] : h;
      Expression fld =
 (f.numSubFields() > 1) ? f[s1.subFieldNumber()] : f;
      const Loc<outputDim> &offset = s1.cellOffset();
      GuardLayers<outputDim> og(fld.fieldEngine().guardLayers());
      for (int d = 0; d < outputDim; d++)
 {
   og.lower(d) += offset[d].first();
   og.upper(d) -= offset[d].first();
 }
      hField.fieldEngine().guardLayers() = og;
      hField.fieldEngine().engine() =
 SEngine_t(fld.engine(), offset, fld.domain());
    }
    return h;
  }
};
template<class Expression>
struct EvaluatorEngineTraits<FieldShift<Expression> >
{
  typedef typename CreateLeaf<Expression>::Leaf_t Expr_t;
  typedef typename
    ForEach<Expr_t, EvaluatorTypeTag, EvaluatorCombineTag>::Type_t
      Evaluator_t;
};
template<int Dim, class Intersect>
class FieldShiftIntersector
{
public:
  typedef typename Intersect::IntersectorData_t IntersectorData_t;
  typedef FieldShiftIntersector<Dim, Intersect> This_t;
  typedef typename IntersectorData_t::const_iterator const_iterator;
  typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
  typedef Interval<Dim> Domain_t;
  enum { dimensions = Intersect::dimensions };
  FieldShiftIntersector(const This_t &model)
    : domain_m(model.domain_m), intersector_m(model.intersector_m)
  { }
  FieldShiftIntersector(const Domain_t &dom, const Intersect &intersect)
    : domain_m(dom), intersector_m(intersect)
  { }
  This_t &operator=(const This_t &model)
  {
    if (this != &model)
    {
      domain_m = model.domain_m;
      intersector_m = model.intersector_m;
    }
    return *this;
  }
  ~FieldShiftIntersector() { }
  inline DataPtr_t &data() { return intersector_m.data(); }
  inline const DataPtr_t &data() const { return intersector_m.data(); }
  inline const_iterator begin() const { return data()->inodes_m.begin(); }
  inline const_iterator end() const { return data()->inodes_m.end(); }
  template<class Engine>
  inline void intersect(const Engine &engine)
  {
    typedef typename NewEngine<Engine, Interval<Dim> >::Type_t NewEngine_t;
    NewEngine_t newEngine(engine, domain_m);
    intersector_m.intersect(newEngine);
    data()->shared(engine.layout().ID(), newEngine.layout().ID());
  }
  template<class Engine, int Dim2>
  inline bool intersect(const Engine &engine, const GuardLayers<Dim2> &)
  {
    intersect(engine);
    return true;
  }
private:
  Interval<Dim> domain_m;
  Intersect intersector_m;
};
template <int Dim, class T, class Expression, class Intersect>
struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
  ExpressionApply<IntersectorTag<Intersect> > >
{
  typedef int Type_t;
  static
  int apply(const Engine<Dim, T, FieldShift<Expression> >
     &engine, const ExpressionApply<IntersectorTag<Intersect> > &tag)
  {
    typedef FieldShiftIntersector<Dim, Intersect> NewIntersector_t;
    NewIntersector_t newIntersector(engine.intersectDomain(),
        tag.tag().intersector_m);
    expressionApply(engine.field(),
      IntersectorTag<NewIntersector_t>(newIntersector));
    return 0;
  }
};
template<class RequestType> class DataObjectRequest;
template <int Dim, class T, class Expression, class RequestType>
struct EngineFunctor<Engine<Dim, T, FieldShift<Expression> >,
  DataObjectRequest<RequestType> >
{
  typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
  static Type_t
  apply(const Engine<Dim, T, FieldShift<Expression> > &engine,
 const DataObjectRequest<RequestType> &tag)
  {
    return engineFunctor(engine.field().engine(), tag);
  }
};
template <int Dim, class T, class Expression, class Tag>
struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
  EngineView<Tag> >
{
  typedef LeafFunctor<Expression, EngineView<Tag> > LeafFunctor_t;
  typedef typename LeafFunctor_t::Type_t NewViewed_t;
  typedef Engine<Dim, T, FieldShift<NewViewed_t> > Type_t;
  static
  Type_t apply(const Engine<Dim, T,
        FieldShift<Expression> > &engine,
        const EngineView<Tag> &tag)
  {
    return Type_t(LeafFunctor_t::apply(engine.field(), tag), engine);
  }
};
template <int Dim, class T, class Expression, class Tag>
struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
                   ExpressionApply<Tag> >
{
  typedef LeafFunctor<Expression, ExpressionApply<Tag> > LeafFunctor_t;
  typedef int Type_t;
  static
  Type_t apply(const Engine<Dim, T,
        FieldShift<Expression> > &engine,
        const ExpressionApply<Tag> &tag)
  {
    return LeafFunctor_t::apply(engine.field(), tag);
  }
};
template<class MeshTag, class T, class EngineTag, int Dim>
struct View2<Field<MeshTag, T, EngineTag>, FieldOffset<Dim>,
             Centering<Dim> >
{
  typedef Field<MeshTag, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef Field<MeshTag, T, FieldShift<Engine_t> > ReadType_t;
  typedef Field<MeshTag, T, FieldShift<Engine_t> > Type_t;
  inline static
  Type_t make(const Subject_t &f, const FieldOffset<Dim> &s1,
              const Centering<Dim> &c)
  {
    PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
    return FieldShiftSimple<Subject_t>::make(f, s1, c);
  }
  inline static
  ReadType_t makeRead(const Subject_t &f, const FieldOffset<Dim> &s1,
                      const Centering<Dim> &c)
  {
    PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
    return FieldShiftSimple<Subject_t>::make(f, s1, c);
  }
};
template<class MeshTag, class T, class EngineTag, int Dim>
struct View2<Field<MeshTag, T, EngineTag>, std::vector<FieldOffset<Dim> >,
             Centering<Dim> >
{
  typedef Field<MeshTag, T, EngineTag> Subject_t;
  typedef typename Subject_t::Engine_t Engine_t;
  typedef Field<MeshTag, T, FieldShift<Engine_t> > ReadType_t;
  typedef Field<MeshTag, T, FieldShift<Engine_t> > Type_t;
  inline static
  Type_t make(const Subject_t &f,
       const std::vector<FieldOffset<Dim> > &s1,
              const Centering<Dim> &c)
  {
    PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
    return FieldShiftSimple<Subject_t>::make(f, s1, c);
  }
  inline static
  ReadType_t makeRead(const Subject_t &f,
        const std::vector<FieldOffset<Dim> > &s1,
                      const Centering<Dim> &c)
  {
    PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
    return FieldShiftSimple<Subject_t>::make(f, s1, c);
  }
};
template<class T, int Dim, class Accumulate>
class FieldOffsetReduction
{
public:
  typedef T OutputElement_t;
  const Centering<Dim> &outputCentering() const
  {
    return outputCentering_m;
  }
  const Centering<Dim> &inputCentering() const
  {
    return inputCentering_m;
  }
  int lowerExtent(int d) const { return lower_m[d]; }
  int upperExtent(int d) const { return upper_m[d]; }
  FieldOffsetReduction()
  {
  }
  FieldOffsetReduction(const FieldOffsetList<Dim> &neighbors,
                       const Centering<Dim> &outputCentering,
                       const Centering<Dim> &inputCentering,
                       Accumulate accumulate = Accumulate())
    : neighbors_m(neighbors),
      outputCentering_m(outputCentering),
      inputCentering_m(inputCentering),
      accumulate_m(accumulate)
  {
    if (__builtin_expect(!!(neighbors.size() > 0), true)) {} else Pooma::toss_cookies("no support for empty accumulation", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/DiffOps/FieldOffsetReduction.h", 115);
    ;
    int d, i;
    for (d = 0; d < Dim; ++d)
    {
      upper_m[d] = 0;
      lower_m[d] = 0;
    }
    for (i = 0; i < neighbors_m.size(); ++i)
    {
      for (d = 0; d < Dim; ++d)
      {
        if (-neighbors_m[i].cellOffset()[d].first() > lower_m[d])
        {
          lower_m[d] = -neighbors_m[i].cellOffset()[d].first();
        }
        if (neighbors_m[i].cellOffset()[d].first() > upper_m[d])
        {
          upper_m[d] = neighbors_m[i].cellOffset()[d].first();
        }
      }
    }
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1) const
  {
    T ret = f(neighbors_m[0], Loc<1>(i1));
    for (int i = 1; i < neighbors_m.size(); ++i)
    {
      ret = accumulate_m(ret, f(neighbors_m[i], Loc<1>(i1)));
    }
    return ret;
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2) const
  {
    T ret = f(neighbors_m[0], Loc<2>(i1, i2));
    for (int i = 1; i < neighbors_m.size(); ++i)
    {
      ret = accumulate_m(ret, f(neighbors_m[i], Loc<2>(i1, i2)));
    }
    return ret;
  }
  template<class F>
  inline OutputElement_t
  operator()(const F &f, int i1, int i2, int i3) const
  {
    T ret = f(neighbors_m[0], Loc<3>(i1, i2, i3));
    for (int i = 1; i < neighbors_m.size(); ++i)
    {
      ret = accumulate_m(ret, f(neighbors_m[i], Loc<3>(i1, i2, i3)));
    }
    return ret;
  }
private:
  FieldOffsetList<Dim> neighbors_m;
  Centering<Dim> outputCentering_m;
  Centering<Dim> inputCentering_m;
  Accumulate accumulate_m;
  int lower_m[Dim];
  int upper_m[Dim];
};
template<class GeometryTag, class T, class EngineTag, int Dim>
typename FieldStencilSimple<FieldOffsetReduction<T, Dim, OpAdd>,
                            Field<GeometryTag, T, EngineTag> >::Type_t
sum(const Field<GeometryTag, T, EngineTag> &f,
    const std::vector<FieldOffsetList<Dim> > &nn,
    const Centering<Dim> &outputCentering)
{
  typedef FieldOffsetReduction<T, Dim, OpAdd> Functor_t;
  typedef Field<GeometryTag, T, EngineTag> Field_t;
  return FieldStencilSimple<Functor_t, Field_t>::make(f, nn, outputCentering,
                                                      OpAdd());
}
template <int Dim>
struct Deltas
{
  static const DomainDelta<Dim, 0> dX;
  static const DomainDelta<Dim, 1> dY;
  static const DomainDelta<Dim, 2> dZ;
};
template <int Dim>
const DomainDelta<Dim, 0> Deltas<Dim>::dX;
template <int Dim>
const DomainDelta<Dim, 1> Deltas<Dim>::dY;
template <int Dim>
const DomainDelta<Dim, 2> Deltas<Dim>::dZ;
static const DomainDelta<3, 0> dX;
static const DomainDelta<3, 1> dY;
static const DomainDelta<3, 2> dZ;
template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
struct SerialTraits {
  typedef MeshTag MeshTag_t;
  typedef CoordinateSystemTag CoordinateSystemTag_t;
  enum { Dim = dim };
  typedef DomainLayout<dim> Layout_t;
  typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
  typedef typename MeshTraits_t::Mesh_t Mesh_t;
  typedef Brick Engine_t;
  typedef CompressibleBrick CompressibleEngine_t;
  static void createLayout(DomainLayout<Dim>& l,
      const Grid<Dim>&, const Interval<Dim>& domain,
      const GuardLayers<Dim>&, const GuardLayers<Dim>& egc)
  {
    l = DomainLayout<Dim>(domain, egc);
  }
};
template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
struct ParallelTraits {
  typedef MeshTag MeshTag_t;
  typedef CoordinateSystemTag CoordinateSystemTag_t;
  enum { Dim = dim };
  typedef GridLayout<dim> Layout_t;
  typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
  typedef typename MeshTraits_t::Mesh_t Mesh_t;
  typedef MultiPatch<GridTag, Remote<Brick> > Engine_t;
  typedef MultiPatch<GridTag, Remote<CompressibleBrick> > CompressibleEngine_t;
  static void createLayout(GridLayout<Dim>& l,
      const Grid<Dim>& grid, const Interval<Dim>&,
      const GuardLayers<Dim>& igc, const GuardLayers<Dim>& egc)
  {
    l = GridLayout<Dim>(grid, igc, egc, DistributedTag());
  }
};
template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
struct SerialMPTraits {
  typedef MeshTag MeshTag_t;
  typedef CoordinateSystemTag CoordinateSystemTag_t;
  enum { Dim = dim };
  typedef GridLayout<dim> Layout_t;
  typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
  typedef typename MeshTraits_t::Mesh_t Mesh_t;
  typedef MultiPatch<GridTag, Brick> Engine_t;
  typedef MultiPatch<GridTag, CompressibleBrick> CompressibleEngine_t;
  static void createLayout(GridLayout<Dim>& l,
      const Grid<Dim>& grid, const Interval<Dim>&,
      const GuardLayers<Dim>& igc, const GuardLayers<Dim>& egc)
  {
    l = GridLayout<Dim>(grid, igc, egc, DistributedTag());
  }
};
template <class ComputeTraits>
struct RhalkTraits : public ComputeTraits {
  typedef ComputeTraits ComputeTraits_t;
  typedef typename ComputeTraits::Layout_t Layout_t;
  typedef typename ComputeTraits::Mesh_t Mesh_t;
  typedef typename ComputeTraits::Engine_t Engine_t;
  typedef typename ComputeTraits::CompressibleEngine_t CompressibleEngine_t;
  enum { Dim = ComputeTraits::Dim };
  typedef Centering<Dim> Centering_t;
  typedef typename Mesh_t::PositionsType_t Positions_t;
  typedef typename Mesh_t::SpacingsType_t Spacings_t;
  typedef Interval<Dim> Domain_t;
  typedef Loc<Dim> Loc_t;
  typedef Field<Mesh_t, double, Engine_t> Scalar_t;
  typedef Field<Mesh_t, Vector<Dim, double>, Engine_t> Vector_t;
};
enum { Dim = 3 };
typedef RhalkTraits<ParallelTraits<Dim, UniformRectilinearTag, CartesianTag> > Traits_t;
extern GuardLayers<Dim> corr_v[Dim];
extern bool a_dump_debug_f;
inline void enable_fp_exceptions(void)
{
  fexcept_t f;
  fegetexceptflag(&f, FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW);
  fesetexceptflag(&f, FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW);
}
inline void disable_fp_exceptions(void)
{
  feclearexcept((FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID));
}
#include <fstream>
namespace Pooma {
Inform pinfo("Pooma");
Inform pwarn("Warning", std::cerr, Inform::allContexts);
Inform perr("Error", std::cerr, Inform::allContexts);
Inform pdebug("** Debug **", std::cerr, Inform::allContexts);
Context_t myContext_g = 0;
int numContexts_g = 1;
int expression_g = 0;
  namespace {
    bool initialized_s = false;
    bool weInitializedRTS_s = false, weInitializedArch_s = false;
    Options options_s;
    Scheduler_t mainScheduler_s;
    Statistics statistics_s;
    std::ofstream *logstream_s = 0;
    Inform::ID_t pinfoLogID_s;
    Inform::ID_t pwarnLogID_s;
    Inform::ID_t perrLogID_s;
    Inform::ID_t pdebugLogID_s;
    void defAbortHandler_s()
    {
      std::cerr << "In default abort handler." << std::endl;
    }
    AbortHandler_t currentAbortHandler_s = defAbortHandler_s;
    long reductionFilter_s(long val)
    {
      ReduceOverContexts<long, OpAddAssign> reduce(val, 0);
      return reduce;
    }
    void cleanup_s()
    {
      if (printStats())
        statistics_s.print(pinfo, reductionFilter_s);
      logMessages(0);
      infoMessages(false);
      warnMessages(false);
      errorMessages(false);
      debugLevel(Inform::off);
    }
  }
namespace { Pooma::StatisticsData *statNumExpressions_s = statistics_s.add("Number of expressions evaluated"); } void incrementNumExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumExpressions_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumZBExpressions_s = statistics_s.add("Number of zero-based expressions evaluated"); } void incrementNumZBExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumZBExpressions_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumMultiPatchExpressions_s = statistics_s.add("Number of multi-patch expressions evaluated"); } void incrementNumMultiPatchExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumMultiPatchExpressions_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumCompressedAssigns_s = statistics_s.add("Number of fully compressed assignments"); } void incrementNumCompressedAssigns(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumCompressedAssigns_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumAssignsRequiringUnCompression_s = statistics_s.add("Number of assignments requiring uncompression"); } void incrementNumAssignsRequiringUnCompression(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumAssignsRequiringUnCompression_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumInlineEvaluations_s = statistics_s.add("Number of assignments using the inline evaluator"); } void incrementNumInlineEvaluations(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumInlineEvaluations_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumLocalPatchesEvaluated_s = statistics_s.add("Number of local patches evaluated"); } void incrementNumLocalPatchesEvaluated(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumLocalPatchesEvaluated_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumReductions_s = statistics_s.add("Number of reductions performed"); } void incrementNumReductions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumReductions_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumUnCompresses_s = statistics_s.add("Number of times a compressible block uncompresses"); } void incrementNumUnCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumUnCompresses_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumUnsuccessfulTryCompresses_s = statistics_s.add("Number of times a compression attempt fails"); } void incrementNumUnsuccessfulTryCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumUnsuccessfulTryCompresses_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumSuccessfulTryCompresses_s = statistics_s.add("Number of times a compression attempt succeeds"); } void incrementNumSuccessfulTryCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumSuccessfulTryCompresses_s->increment(val); mutex.unlock(); }
namespace { Pooma::StatisticsData *statNumPolls_s = statistics_s.add("Number of calls to Pooma::poll()"); } void incrementNumPolls(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumPolls_s->increment(val); mutex.unlock(); }
bool initialize(int &argc, char ** &argv, bool initRTS, bool getCLArgsArch,
  bool initArch)
{
  if (getCLArgsArch)
    Pooma::Arch::getCommandLineArguments(argc, argv);
  Options opts(argc, argv);
  return initialize(opts, initRTS, initArch);
}
bool initialize(Options &opts, bool initRTS, bool initArch)
{
  if (__builtin_expect(!!(!initialized_s), true)) {} else Pooma::toss_cookies("You can only call Pooma::initialize once.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Pooma/Pooma.cmpl.cpp", 306);
  initialized_s = true;
  weInitializedRTS_s = initRTS;
  weInitializedArch_s = initArch;
  if (initArch)
    Pooma::Arch::initialize();
  debugLevel(opts.debug());
  options_s = opts;
  if (initRTS)
  {
    Smarts::concurrency(opts.concurrency());
  }
  myContext_g = 0;
  numContexts_g = 1;
  logstream_s = 0;
  logMessages(opts.logfile().c_str());
  infoMessages(opts.printInfo());
  warnMessages(opts.printWarnings());
  errorMessages(opts.printErrors());
  Inform::setContext(myContext_g);
  Inform::setNumContexts(numContexts_g);
  return true;
}
bool finalize()
{
  return finalize(weInitializedRTS_s, weInitializedArch_s);
}
bool finalize(bool quitRTS, bool quitArch)
{
  Pooma::blockAndEvaluate();
  if (initialized_s)
  {
    Smarts::wait();
    cleanup_s();
    if (quitRTS)
    {
    }
  }
  if (quitArch)
    Pooma::Arch::finalize();
  return true;
}
void pAbort(int errorcode)
{
  pAbort("Pooma::pAbort called.", errorcode);
}
void pAbort(const char *msg, int)
{
  if (msg != 0)
    std::cerr << msg << std::endl;
  currentAbortHandler_s();
  if (initialized_s)
  {
    cleanup_s();
  }
  ::abort();
}
AbortHandler_t abortHandler()
{
  return currentAbortHandler_s;
}
AbortHandler_t abortHandler(AbortHandler_t ah)
{
  AbortHandler_t oldah = currentAbortHandler_s;
  currentAbortHandler_s = ah;
  return oldah;
}
AbortHandler_t resetAbortHandler()
{
  return abortHandler(defAbortHandler_s);
}
const char *version()
{
  ;
  return "FreePOOMA 2.4.devel";
}
int majorVersion()
{
  ;
  return 2;
}
int minorVersion()
{
  ;
  return 4;
}
const char *buildDate()
{
  ;
  return "Wed Mar 23 16:19:43 CET 2005";
}
bool printStats()
{
  ;
  return options_s.printStats();
}
void printStats(bool on)
{
  ;
  options_s.printStats(on);
}
bool infoMessages()
{
  ;
  return (pinfo.outputLevel() >= 0);
}
void infoMessages(bool on)
{
  ;
  pinfo.setOutputLevel(on ? Inform::on : Inform::off);
}
bool warnMessages()
{
  ;
  return (pwarn.outputLevel() >= 0);
}
void warnMessages(bool on)
{
  ;
  pwarn.setOutputLevel(on ? Inform::on : Inform::off);
}
bool errorMessages()
{
  ;
  return (perr.outputLevel() >= 0);
}
void errorMessages(bool on)
{
  ;
  perr.setOutputLevel(on ? Inform::on : Inform::off);
}
void logMessages(const char *filename)
{
  ;
  if (logstream_s != 0)
    {
      pinfo.close(pinfoLogID_s);
      pwarn.close(pwarnLogID_s);
      perr.close(perrLogID_s);
      pdebug.close(pdebugLogID_s);
      delete logstream_s;
      logstream_s = 0;
    }
  if (filename != 0 && *filename != 0)
    {
      logstream_s = new std::ofstream(filename, std::ios::out);
      pinfoLogID_s = pinfo.open(*logstream_s);
      pwarnLogID_s = pwarn.open(*logstream_s);
      perrLogID_s = perr.open(*logstream_s);
      pdebugLogID_s = pdebug.open(*logstream_s);
      pinfo.setOutputLevel(pinfo.outputLevel());
      pwarn.setOutputLevel(pwarn.outputLevel());
      perr.setOutputLevel(perr.outputLevel());
      pdebug.setOutputLevel(pdebug.outputLevel());
    }
}
int debugLevel()
{
  ;
  return pdebug.outputLevel();
}
void debugLevel(int level)
{
  ;
  pdebug.setOutputLevel(level);
}
bool neverCompress()
{
  ;
  return options_s.neverCompress();
}
void neverCompress(bool p)
{
  ;
  options_s.neverCompress(p);
}
bool deferredGuardFills()
{
  ;
  return options_s.deferredGuardFills();
}
void deferredGuardFills(bool p)
{
  ;
  options_s.deferredGuardFills(p);
}
Scheduler_t &scheduler()
{
  ;
  return mainScheduler_s;
}
void blockAndEvaluate()
{
  ;
  mainScheduler_s.blockingEvaluate();
}
bool hardInit()
{
  ;
  return options_s.hardInit();
}
void hardInit(bool on)
{
  ;
  options_s.hardInit(on);
}
bool hardRun()
{
  ;
  return options_s.hardRun();
}
void hardRun(bool on)
{
  ;
  options_s.hardRun(on);
}
bool lockThreads()
{
  ;
  return options_s.lockThreads();
}
void lockThreads(bool on)
{
  ;
  options_s.lockThreads(on);
}
bool blockingExpressions()
{
  ;
  return options_s.blockingExpressions();
}
void blockingExpressions(bool on)
{
  ;
  options_s.blockingExpressions(on);
}
}
extern "C" void pooma_stop_here();
void Pooma::stopHere()
{
  ::pooma_stop_here();
}
extern "C" void pooma_stop_here()
{
}
namespace Pooma {
class PatchSizeSyncer
{
public:
  typedef Grid<1> Grid_t;
  PatchSizeSyncer(int contextKey, Grid_t &localGrid);
  ~PatchSizeSyncer();
 void calcGlobalGrid(Grid_t &globalGrid);
private:
  int myContext_m;
  int numContexts_m;
  int localKey_m;
  Grid_t localGrid_m;
  typedef std::pair<int,Grid_t *> Elem_t;
  std::vector<Elem_t> gridList_m;
  PatchSizeSyncer(const PatchSizeSyncer &);
  PatchSizeSyncer &operator=(const PatchSizeSyncer &);
  static int tag_s;
};
}
template<class T>
class CollectFromContexts
{
public:
  CollectFromContexts(const T &val, int context = 0, bool valid = true)
    {
      ;
      ;
      value_m = val;
    }
  T &operator[](int i)
    {
      ;
      return value_m;
    }
  T operator[](int i) const
    {
      ;
      return value_m;
    }
private:
  T value_m;
};
namespace Pooma {
PatchSizeSyncer::PatchSizeSyncer(int contextKey, Grid_t &localGrid)
  : myContext_m(Pooma::context()),
    numContexts_m(Pooma::contexts()),
    localKey_m(contextKey),
    localGrid_m(localGrid)
{
  if (myContext_m == 0) gridList_m.reserve(numContexts_m);
}
PatchSizeSyncer::~PatchSizeSyncer()
{
  ;
  for (int i = 0; i < gridList_m.size(); ++i)
    delete gridList_m[i].second;
}
namespace {
struct ElemCompare
{
  typedef std::pair<int,Grid<1>*> Elem_t;
  inline bool operator()(const Elem_t &l, const Elem_t &r)
  {
    return l.first < r.first;
  }
};
}
void PatchSizeSyncer::calcGlobalGrid(Grid_t &globalGrid)
{
  globalGrid = localGrid_m;
}
}
TagGenerator tagGenerator_g;
namespace Pooma {
int expectedMessages_g = 0;
void initializeCheetahHelpers(int contexts)
{
  tagGenerator_g = TagGenerator(contexts);
  expectedMessages_g = 0;
}
void finalizeCheetahHelpers()
{
  ;
}
int sendTag(int context)
{
  return tagGenerator_g.send(context);
}
int receiveTag(int context)
{
  return tagGenerator_g.receive(context);
}
}
const unsigned int Inform::bufSize = 32000;
Pooma::Mutex_t Inform::outputMutex_s;
Inform::Context_t Inform::context_s = 0;
Inform::Context_t Inform::nContexts_s = 1;
class InformStream
{
public:
  InformStream(std::ostream *s, Inform::Context_t oc)
    : stream_m(s), close_m(false), outputContext_m(oc), level_m(0)
  {
    ;
  }
  InformStream(const char *fname, int mode, Inform::Context_t oc)
    : stream_m(0), close_m(true), outputContext_m(oc), level_m(0)
  {
    ;
    ;
    if (oc < 0 || oc == Inform::context()) {
      if (mode == Inform::out)
 stream_m = new std::ofstream(fname, std::ios::out);
      else
 stream_m = new std::ofstream(fname, std::ios::app);
    }
  }
  ~InformStream()
  {
    if (close_m && stream_m != 0)
      delete stream_m;
  }
  Inform::Context_t outputContext() const
  {
    return outputContext_m;
  }
  void setOutputContext(Inform::Context_t val)
  {
    outputContext_m = val;
  }
  Inform::Level_t outputLevel() const
  {
    return level_m;
  }
  void setOutputLevel(Inform::Level_t val)
  {
    level_m = val;
  }
  void print(Inform::Level_t l, const std::string &prefix, const char *msg)
  {
    if (shouldPrint(l))
      {
        if (prefix.length() > 0)
          {
            *stream_m << prefix;
            if (Inform::numContexts() > 1)
              {
                if ((outputContext_m == Inform::allContexts) ||
                    (outputContext_m == Inform::context()))
                  {
                    *stream_m << "{" << Inform::context() << "}";
                  }
              }
            *stream_m << "> ";
          }
        *stream_m << msg << "\n";
        stream_m->flush();
      }
  }
private:
  std::ostream *stream_m;
  bool close_m;
  Inform::Context_t outputContext_m;
  Inform::Level_t level_m;
  bool shouldPrint(Inform::Level_t level)
  {
    ;
    if (stream_m == 0)
      return false;
    return (level <= level_m &&
     (outputContext_m == Inform::context() ||
      outputContext_m == Inform::allContexts));
  }
};
namespace std {
  Inform &endl(Inform &inf)
  {
    inf.flush();
    return inf;
  }
  Inform &flush(Inform &inf)
  {
    inf.flush();
    return inf;
  }
  Inform &lock(Inform &inf)
  {
    inf.lock();
    return inf;
  }
  Inform &unlock(Inform &inf)
  {
    inf.unlock();
    return inf;
  }
}
Inform::Inform(const char *prefix, Context_t outputContext)
  : prefix_m(""), outputContext_m(outputContext), level_m(0),
    message_m(0), buffer_m(0), nextID_m(0)
{
  open(outputContext);
  setup(prefix);
}
Inform::Inform(const char *prefix, const char *fname, int writemode,
        Context_t outputContext)
  : prefix_m(""), outputContext_m(outputContext), level_m(0),
    message_m(0), buffer_m(0), nextID_m(0)
{
  open(fname, writemode, outputContext);
  setup(prefix);
}
Inform::Inform(const char *prefix, std::ostream &outstream,
               Context_t outputContext)
  : prefix_m(""), outputContext_m(outputContext), level_m(0),
    message_m(0), buffer_m(0), nextID_m(0)
{
  open(outstream, outputContext);
  setup(prefix);
}
Inform::~Inform()
{
  close();
  delete message_m;
  if (buffer_m != 0)
    delete [] buffer_m;
}
Inform::ID_t Inform::open(Context_t oc)
{
  streams_m.insert(Value_t(nextID_m, new InformStream(&std::cout, oc)));
  return nextID_m++;
}
Inform::ID_t Inform::open(const char *fname, int mode, Context_t oc)
{
  streams_m.insert(Value_t(nextID_m, new InformStream(fname, mode, oc)));
  return nextID_m++;
}
Inform::ID_t Inform::open(std::ostream &outstream, Context_t oc)
{
  streams_m.insert(Value_t(nextID_m, new InformStream(&outstream, oc)));
  return nextID_m++;
}
void Inform::close(ID_t id)
{
  iterator s = streams_m.find(id);
  ;
  delete ((*s).second);
  streams_m.erase(s);
}
void Inform::close()
{
  for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
    delete ((*a).second);
  streams_m.erase(streams_m.begin(), streams_m.end());
}
Inform::Level_t Inform::outputLevel(ID_t id) const
{
  InformStream *s = findStream(id);
  ;
  return s->outputLevel();
}
void Inform::setOutputLevel(Level_t newval, ID_t id)
{
  InformStream *s = findStream(id);
  ;
  s->setOutputLevel(newval);
}
void Inform::setOutputLevel(Level_t newval)
{
  for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
    (*a).second->setOutputLevel(newval);
}
Inform::Context_t Inform::outputContext(ID_t id) const
{
  InformStream *s = findStream(id);
  ;
  return s->outputContext();
}
void Inform::setOutputContext(Context_t outputContext, ID_t id)
{
  InformStream *s = findStream(id);
  ;
  s->setOutputContext(outputContext);
}
void Inform::setOutputContext(Context_t outputContext)
{
  for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
    (*a).second->setOutputContext(outputContext);
}
void Inform::flush()
{
  *message_m << std::ends;
  outputMutex_s.lock();
  std::string formatstr = message_m->str();
  char *outputbuf = new char[formatstr.length() + 2];
  char *endbuf = outputbuf;
  char *begbuf = outputbuf;
  const char *formatbuf = formatstr.c_str();
  do {
    while (*formatbuf != '\n' && *formatbuf != '\0')
      *endbuf++ = *formatbuf++;
    *endbuf = '\0';
    if (*formatbuf == '\n')
      ++formatbuf;
    for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
      (*a).second->print(level_m, prefix_m, begbuf);
    begbuf = endbuf;
  } while (*formatbuf != '\0');
  message_m->str( std::string() );
  delete [] outputbuf;
  outputMutex_s.unlock();
}
InformStream *Inform::findStream(ID_t id) const
{
  const_iterator s = streams_m.find(id);
  if (s != streams_m.end())
    return (*s).second;
  else
    return 0;
}
void Inform::setup(const char *prefix)
{
  setPrefix(prefix);
  buffer_m = 0;
  message_m = new std::ostringstream(std::ios::out);
}
void Inform::setPrefix(const char *prefix)
{
  if (prefix == 0 || *prefix == '\0')
    prefix_m = "";
  else
    prefix_m = prefix;
}
Pool::Pool(size_t sz)
  :
  head_m(0),
  outstandingAllocs_m(0),
  bsize_m(roundToAlign(sz)),
  nblock_m(blocksInPage(bsize_m))
{
}
Pool::Pool()
  :
  head_m(0),
  outstandingAllocs_m(0),
  bsize_m(0),
  nblock_m(0)
{
}
Pool::~Pool()
{
  if (__builtin_expect(!!(outstandingAllocs_m==0), true)) {} else Pooma::toss_cookies("Not all of the pooled memory was freed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/Pool.cmpl.cpp", 73);
  for (std::vector<char*>::iterator p=chunks_m.begin(); p!=chunks_m.end(); ++p)
    delete [] *p;
}
void Pool::grow()
{
  size_t alloc_this;
  if ( bsize_m>page )
    alloc_this = bsize_m;
  else
    alloc_this = page;
  char *start = new char[alloc_this];
  chunks_m.push_back(start);
  char *last = start + (nblock_m-1)*bsize_m;
  for (char *p=start; p!=last; p+=bsize_m)
    ((Link*)p)->next_m = (Link*)(p+bsize_m);
  ((Link*)last)->next_m = head_m;
  head_m = (Link*)start;
}
//#include <execinfo.h>
namespace Pooma {
Assertion::Assertion(const char *msg, const char *file, int line)
{
  msg_m = new char[strlen(msg) + 1];
  strcpy(msg_m, msg);
  file_m = new char[strlen(file) + 1];
  strcpy(file_m, file);
  line_m = line;
}
Assertion::Assertion(const Assertion &a)
{
  msg_m = new char[strlen(a.what())+1];
  strcpy(msg_m, a.what());
  file_m = new char[strlen(a.file())+1];
  strcpy(file_m, a.file());
  line_m = a.line();
}
Assertion &Assertion::operator=(const Assertion &a)
{
  msg_m = new char[strlen(a.what())+1];
  strcpy(msg_m, a.what());
  file_m = new char[strlen(a.file())+1];
  strcpy(file_m, a.file());
  line_m = a.line();
  return *this;
}
void toss_cookies(const char *msg, const char *file, int line ...)
{
  va_list ap;
  va_start(ap,line);
  char buf[256];
  vsprintf(buf, msg, ap);
  va_end(ap);
  Assertion a(buf, file, line);
  Pooma::stopHere();
  fprintf(stderr, "### POOMA Assertion Failure on context %i ###\n", Pooma::context());
  fprintf(stderr, "### %s\n", a.what());
  fprintf(stderr, "### File %s; Line %d.\n", a.file(), a.line());
  Pooma::pAbort();
}
}
Unique::Value_t Unique::next_s = 0;
Pooma::Mutex_t Unique::mutex_s;
bool findLeftCommonEndpoint(int a0, int a1, int s, int b0, int b1, int t,
       int &endpoint)
{
  ;
  if (s < 0) s = -s;
  if (t < 0) t = -t;
  if (a0 > b0) {
    int tmp;
    tmp = a0; a0 = b0; b0 = tmp;
    tmp = a1; a1 = b1; b1 = tmp;
    tmp = s; s = t; t = tmp;
  }
  int i1 = b0 - ((b0 - a0) % s);
  int i2 = b0;
  int maxdiff = 0;
  int minright = a1;
  if (b1 < a1)
    minright = b1;
  while (i1 <= minright && i2 <= minright) {
    while (i1 < i2)
      i1 += s;
    int newdiff = i1 - i2;
    if (i1 == i2 || newdiff == maxdiff) {
      break;
    } else if (newdiff > maxdiff) {
      maxdiff = newdiff;
    }
    i2 += t;
  }
  if (i1 == i2 && i1 <= minright) {
    endpoint = i1;
    return true;
  } else {
    return false;
  }
}
int findLCM(int s, int t)
{
  ;
  int i1 = s, i2 = t;
  if (s > t) {
    s = t;
    t = i1;
    i1 = s;
    i2 = t;
  }
  while (i1 != i2) {
    while (i1 < i2)
      i1 += s;
    if (i1 > i2)
      i2 += t;
  }
  return i1;
}
bool findIntersectionEndpoints(int a0, int a1, int s, int b0, int b1, int t,
                               int &left, int &right, int &stride)
{
  ;
  if (s < 0) s = -s;
  if (t < 0) t = -t;
  if (!findLeftCommonEndpoint(a0, a1, s, b0, b1, t, left))
    return false;
  stride = findLCM(s, t);
  int m = a1;
  if (b1 < a1)
    m = b1;
  right = m - ((m - left) % stride);
  return true;
}
GlobalIDDataBase::NodeKey_t
GlobalIDDataBase::push(LayoutID_t layoutID, int context, GlobalID_t globalID)
{
  int ret = data_m.size();
  data_m.push_back(Pack(layoutID, context, globalID, nullNodeKey()));
  return ret;
}
GlobalIDDataBase::NodeKey_t
GlobalIDDataBase::push(LayoutID_t layoutID,
         int context,
         GlobalID_t globalID,
         NodeKey_t parentNode)
{
  int ret = data_m.size();
  data_m.push_back(Pack(layoutID, context, globalID, parentNode));
  return ret;
}
void
GlobalIDDataBase::shared(LayoutID_t idNew, LayoutID_t idOld)
{
  Shared_t::const_iterator p = shared_m.find(idOld);
  if (p != shared_m.end())
  {
    idOld = p->second;
  }
  Shared_t::value_type i(idNew, idOld);
  shared_m.insert(i);
}
GlobalIDDataBase::GlobalID_t
GlobalIDDataBase::globalID(LayoutID_t layoutID, NodeKey_t key) const
{
  Shared_t::const_iterator p = shared_m.find(layoutID);
  if (p != shared_m.end())
  {
    layoutID = p->second;
  }
  while( key != nullNodeKey() )
  {
    if (data_m[key].layoutID() == layoutID)
    {
      return data_m[key].globalID();
    }
    else
    {
      key = data_m[key].parent();
    }
  }
  ;
  return -1;
}
int
GlobalIDDataBase::context(LayoutID_t layoutID, NodeKey_t key) const
{
  Shared_t::const_iterator p = shared_m.find(layoutID);
  if (p != shared_m.end())
  {
    layoutID = p->second;
  }
  while( key != nullNodeKey() )
  {
    if (data_m[key].layoutID() == layoutID)
    {
      return data_m[key].context();
    }
    else
    {
      key = data_m[key].parent();
    }
  }
  ;
  return -1;
}
int
GlobalIDDataBase::context(NodeKey_t key) const
{
  ;
  return data_m[key].context();
}
bool
GlobalIDDataBase::contextParticipates(int context, NodeKey_t key) const
{
  while( key != nullNodeKey() )
  {
    if (data_m[key].context() == context)
    {
      return true;
    }
    else
    {
      key = data_m[key].parent();
    }
  }
  return false;
}
namespace Pooma {
  namespace {
    unsigned int activeGroups_g = 1;
    unsigned int numGroups_g = 1;
  }
  unsigned int activeRelationGroups()
    {
      return activeGroups_g;
    }
  bool isRelationGroupActive(unsigned int groups)
    {
      return (groups & activeGroups_g) != 0;
    }
  void activateRelationGroup(unsigned int group)
    {
      blockAndEvaluate();
      activeGroups_g |= group;
    }
  void deactivateRelationGroup(unsigned int group)
    {
      blockAndEvaluate();
      activeGroups_g &= ~group;
    }
  unsigned int newRelationGroup()
    {
      unsigned int n = (1 << numGroups_g++);
      activateRelationGroup(n);
      return n;
    }
}
template <int Dim>
CanonicalCentering<Dim>::CanonicalCentering()
{
  Centering<Dim> centering;
  typename Centering<Dim>::Orientation orientation;
  typename Centering<Dim>::Position position;
  typename Centering<Dim>::Orientations orientations[Dim][2];
  typename Centering<Dim>::Positions positions[Dim][2];
  enum { x = 0, y, z };
  if (class_count_m == 0) {
    centering_table_m = new Centering<Dim>**[CellType+1];
    for (int i = 0; i <= CellType; ++i) {
      centering_table_m[i] = new Centering<Dim>*[2];
      for (int j = 0; j < 2; ++j)
 centering_table_m[i][j] = new Centering<Dim>[1<<Dim];
    }
  }
  ++class_count_m;
  centering = Centering<Dim>(CellType, Continuous);
  orientation = 1;
  position = 0.5;
  centering.addValue(orientation, position);
  centering_table_m[CellType][Continuous][AllDim%(1<<Dim)] = centering;
  orientation = 0; orientation[0] = 1;
  position = 0.0; position(0) = 0.5;
  addValue(orientations[x][Continuous],
    positions[x][Continuous],
    orientation, position);
  orientations[x][Discontinuous] =
    orientations[x][Continuous];
  positions[x][Discontinuous] =
    positions[x][Continuous];
  if (Dim > 1) {
    position(1) = 1.0;
    addValue(orientations[x][Discontinuous],
      positions[x][Discontinuous],
      orientation, position);
    if (Dim > 2) {
      position(2) = 1.0;
      addValue(orientations[x][Discontinuous],
        positions[x][Discontinuous],
        orientation, position);
      position(1) = 0.0;
      addValue(orientations[x][Discontinuous],
        positions[x][Discontinuous],
        orientation, position);
    }
  }
  if (Dim > 1) {
    orientation = 0; orientation[1] = 1;
    position = 0.0; position(1) = 0.5;
    addValue(orientations[y][Continuous],
      positions[y][Continuous],
      orientation, position);
    orientations[y][Discontinuous] =
      orientations[y][Continuous];
    positions[y][Discontinuous] =
      positions[y][Continuous];
    position(0) = 1.0;
    addValue(orientations[y][Discontinuous],
      positions[y][Discontinuous],
      orientation, position);
    if (Dim > 2) {
      position(2) = 1.0;
      addValue(orientations[y][Discontinuous],
        positions[y][Discontinuous],
        orientation, position);
      position(0) = 0.0;
      addValue(orientations[y][Discontinuous],
        positions[y][Discontinuous],
        orientation, position);
    }
  }
  if (Dim > 2) {
    orientation = 0; orientation[2] = 1;
    position = 0.0; position(2) = 0.5;
    addValue(orientations[z][Continuous],
      positions[z][Continuous],
      orientation, position);
    orientations[z][Discontinuous] =
      orientations[z][Continuous];
    positions[z][Discontinuous] =
      positions[z][Continuous];
    position(0) = 1.0;
    addValue(orientations[z][Discontinuous],
      positions[z][Discontinuous],
      orientation, position);
    position(1) = 1.0;
    addValue(orientations[z][Discontinuous],
      positions[z][Discontinuous],
      orientation, position);
    position(0) = 0.0;
    addValue(orientations[z][Discontinuous],
      positions[z][Discontinuous],
      orientation, position);
  }
  for (int cont = 0; cont < 2; ++cont) {
    centering_table_m[EdgeType][cont][XDim] =
      Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
       orientations[x][cont], positions[x][cont]);
    if (Dim > 1) {
      centering_table_m[EdgeType][cont][YDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         orientations[y][cont], positions[y][cont]);
      centering_table_m[EdgeType][cont][XDim|YDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],orientations[y][cont]),
         combine(positions[x][cont], positions[y][cont]));
    }
    if (Dim > 2) {
      centering_table_m[EdgeType][cont][ZDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         orientations[z][cont], positions[z][cont]);
      centering_table_m[EdgeType][cont][XDim|ZDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],orientations[z][cont]),
         combine(positions[x][cont], positions[z][cont]));
      centering_table_m[EdgeType][cont][YDim|ZDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         combine(orientations[y][cont],orientations[z][cont]),
         combine(positions[y][cont], positions[z][cont]));
      centering_table_m[EdgeType][cont][XDim|YDim|ZDim] =
 Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],
          combine(orientations[y][cont],orientations[z][cont])),
         combine(positions[x][cont],
          combine(positions[y][cont], positions[z][cont])));
    }
  }
  for (int dim = 0; dim < Dim; ++dim)
    for (int cont = 0; cont < 2; ++cont)
      {
 orientations[dim][cont].clear();
 positions[dim][cont].clear();
      }
  orientation = 1; orientation[0] = 0;
  position = 0.5; position(0) = 0.0;
  addValue(orientations[x][Continuous],
    positions[x][Continuous],
    orientation, position);
  orientations[x][Discontinuous] =
    orientations[x][Continuous];
  positions[x][Discontinuous] =
    positions[x][Continuous];
  position(0) = 1.0;
  addValue(orientations[x][Discontinuous],
    positions[x][Discontinuous],
    orientation, position);
  if (Dim > 1) {
    orientation = 1; orientation[1] = 0;
    position = 0.5; position(1) = 0.0;
    addValue(orientations[y][Continuous],
      positions[y][Continuous],
      orientation, position);
    orientations[y][Discontinuous] =
      orientations[y][Continuous];
    positions[y][Discontinuous] =
      positions[y][Continuous];
    position(1) = 1.0;
    addValue(orientations[y][Discontinuous],
      positions[y][Discontinuous],
      orientation, position);
  }
  if (Dim > 2) {
    orientation = 1; orientation[2] = 0;
    position = 0.5; position(2) = 0.0;
    addValue(orientations[z][Continuous],
      positions[z][Continuous],
      orientation, position);
    orientations[z][Discontinuous] =
      orientations[z][Continuous];
    positions[z][Discontinuous] =
      positions[z][Continuous];
    position(2) = 1.0;
    addValue(orientations[z][Discontinuous],
      positions[z][Discontinuous],
      orientation, position);
  }
  for (int cont = 0; cont < 2; ++cont) {
    centering_table_m[FaceType][cont][XDim] =
      Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
       orientations[x][cont], positions[x][cont]);
    if (Dim > 1) {
      centering_table_m[FaceType][cont][XDim|YDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],orientations[y][cont]),
         combine(positions[x][cont], positions[y][cont]));
      centering_table_m[FaceType][cont][YDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         orientations[y][cont], positions[y][cont]);
    }
    if (Dim > 2) {
      centering_table_m[FaceType][cont][ZDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         orientations[z][cont], positions[z][cont]);
      centering_table_m[FaceType][cont][XDim|ZDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],orientations[z][cont]),
         combine(positions[x][cont], positions[z][cont]));
      centering_table_m[FaceType][cont][YDim|ZDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         combine(orientations[y][cont],orientations[z][cont]),
         combine(positions[y][cont], positions[z][cont]));
      centering_table_m[FaceType][cont][XDim|YDim|ZDim] =
 Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
         combine(orientations[x][cont],
          combine(orientations[y][cont],orientations[z][cont])),
         combine(positions[x][cont],
          combine(positions[y][cont], positions[z][cont])));
    }
  }
  for (int dim = 0; dim < Dim; ++dim)
    for (int cont = 0; cont < 2; ++cont)
      {
 orientations[dim][cont].clear();
 positions[dim][cont].clear();
      }
  centering = Centering<Dim>(VertexType, Continuous);
  orientation = 0;
  position = 0.0;
  centering.addValue(orientation, position);
  centering_table_m[VertexType][Continuous][AllDim%(1<<Dim)] =
    centering;
  centering = Centering<Dim>(VertexType, Discontinuous);
  orientation = 0;
  position = 0.0;
  centering.addValue(orientation, position);
  position(0) = 1.0; centering.addValue(orientation, position);
  if (Dim > 1) {
    position(1) = 1.0; centering.addValue(orientation, position);
    position(0) = 0.0; centering.addValue(orientation, position);
    if (Dim > 2) {
      position(2) = 1.0; centering.addValue(orientation, position);
      position(0) = 1.0; centering.addValue(orientation, position);
      position(1) = 0.0; centering.addValue(orientation, position);
      position(0) = 0.0; centering.addValue(orientation, position);
    }
  }
  centering_table_m[VertexType][Discontinuous][AllDim%(1<<Dim)] =
    centering;
  return;
}
const CanonicalCentering<1> canonicalCenteringOne_g;
const CanonicalCentering<2> canonicalCenteringTwo_g;
const CanonicalCentering<3> canonicalCenteringThree_g;
template <int Dim>
const Centering<Dim> canonicalCentering
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension);
template <>
const Centering<1> canonicalCentering<1>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension)
{
  return canonicalCenteringOne_g(type, discontinuous, dimension);
}
template <>
const Centering<2> canonicalCentering<2>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension)
{
  return canonicalCenteringTwo_g(type, discontinuous, dimension);
}
template <>
const Centering<3> canonicalCentering<3>
    (const enum CenteringType type,
     const enum ContinuityType discontinuous,
     const int dimension)
{
  return canonicalCenteringThree_g(type, discontinuous, dimension);
}
template class CanonicalCentering<1>;
template class CanonicalCentering<2>;
template class CanonicalCentering<3>;
void UniformMapper::map(const List_t& templist) const
{
  int contexts = Pooma::contexts();
  int npc = blocks_m.first() / contexts;
  int remainder = blocks_m.first() % contexts;
  int index = 0;
  for (int c=0; c<contexts; ++c)
  {
    for (int i=0; i<npc; ++i)
      templist[index++]->context() = c;
    if (c < remainder)
      templist[index++]->context() = c;
  }
  setAffinity(templist);
}
namespace Pooma {
Options::Options()
{
  reset();
}
Options::Options(int &argc, char ** argv)
{
  reset();
  parse(argc, argv);
}
Options::Options(const Options &opts)
{
  *this = opts;
}
Options &Options::operator=(const Options &opts)
{
  concurrency_m = opts.concurrency();
  info_m = opts.printInfo();
  warn_m = opts.printWarnings();
  err_m = opts.printErrors();
  logfile_m = opts.logfile();
  stats_m = opts.printStats();
  debug_m = opts.debug();
  neverCompress_m = opts.neverCompress();
  deferredFills_m = opts.deferredGuardFills();
  hardinit_m = opts.hardInit();
  hardrun_m = opts.hardRun();
  lockthreads_m = opts.lockThreads();
  blockingExpressions_m = opts.blockingExpressions();
  return *this;
}
Options::~Options()
{
}
void Options::usage()
{
  Inform msg("POOMA Usage", std::cerr);
  msg << ">>>-----------------------------------<<<\n";
  msg << ">>> POOMA command-line option summary <<<\n";
  msg << ">>>-----------------------------------<<<\n";
  msg << "Standard options:\n";
  msg << "--pooma-threads <N> ......... set concurrency level (N >= 1)\n";
  msg << "--pooma-info ................ turn on output of info messages\n";
  msg << "--pooma-warn ................ turn on output of warning messages\n";
  msg << "--pooma-err ................. turn on output of error messages\n";
  msg << "--pooma-log <file> .......... turn on logging of output to <file>\n";
  msg << "--pooma-stats ............... turn on output of stats at end\n";
  msg << "--pooma-nocompress .......... disable compression of\n";
  msg << "                              compressible brick-engines\n";
  msg << "--pooma-help ................ print out this summary\n";
  msg << "Developer options:\n";
  msg << "--pooma-debug <N> ........... set debug output level to <N>\n";
  msg << "--pooma-smarts-hardinit\n";
  msg << "--pooma-smarts-hardrun\n";
  msg << "--pooma-smarts-lockthreads\n";
  msg << "--pooma-blocking-expressions\n";
  msg << "All options exist as \"yes\" and \"no\" pairs.\n";
  msg << "For example --pooma-info and --pooma-noinfo.\n";
  msg << "The \"no\" versions listed above imply that \"yes\" is the default.";
  msg << std::endl;
}
void Options::reset()
{
  concurrency_m = 1;
  info_m = true;
  warn_m = true;
  err_m = true;
  logfile_m = "";
  stats_m = false;
  debug_m = Inform::off;
  neverCompress_m = false;
  deferredFills_m = true;
  hardinit_m = true;
  hardrun_m = false;
  lockthreads_m = false;
  blockingExpressions_m = false;
}
void Options::parse(int &argc, char ** &argv)
{
  if (argc < 2)
    return;
  int retargc = 1;
  char **retargv = new char *[argc];
  retargv[0] = argv[0];
  int i = 1;
  while (i < argc)
    {
      bool argok = true;
      bool argvalerr = false;
      std::string word(argv[i]);
      if (word == "--pooma-threads")
 {
   argok = intArgument(argc, argv, i+1, concurrency_m);
   argvalerr = (concurrency_m < 1);
   ++i;
 }
      else if (word == "--pooma-nothreads")
 {
   concurrency_m = 1;
 }
      else if (word == "--pooma-info" || word == "--pooma-noinfo")
 {
   info_m = (word == "--pooma-info");
 }
      else if (word == "--pooma-nocompress" || word == "--pooma-compress")
 {
   neverCompress_m = (word == "--pooma-nocompress");
 }
      else if (word == "--pooma-nodeferred-guardfills" ||
               word == "--pooma-deferred-guardfills")
 {
   deferredFills_m = (word == "--pooma-deferred-guardfills");
 }
      else if (word == "--pooma-warn" || word == "--pooma-nowarn")
 {
   warn_m = (word == "--pooma-warn");
 }
      else if (word == "--pooma-err" || word == "--pooma-noerr")
 {
   err_m = (word == "--pooma-err");
 }
      else if (word == "--pooma-stats" || word == "--pooma-nostats")
 {
   stats_m = (word == "--pooma-stats");
 }
      else if (word == "--pooma-log")
 {
   argok = stringArgument(argc, argv, i+1, logfile_m);
   ++i;
 }
      else if (word == "--pooma-debug")
 {
   argok = intArgument(argc, argv, i+1, debug_m);
   ++i;
 }
      else if (word == "--pooma-nodebug")
 {
   debug_m = Inform::off;
 }
      else if (word == "--pooma-smarts-hardinit")
 {
   hardinit_m = true;
 }
      else if (word == "--pooma-smarts-nohardinit")
 {
   hardinit_m = false;
 }
      else if (word == "--pooma-smarts-hardrun")
 {
   hardrun_m = true;
 }
      else if (word == "--pooma-smarts-nohardrun")
 {
   hardrun_m = false;
 }
      else if (word == "--pooma-smarts-lockthreads")
 {
   lockthreads_m = true;
 }
      else if (word == "--pooma-smarts-nolockthreads")
 {
   lockthreads_m = false;
 }
      else if (word == "--pooma-blocking-expressions")
 {
   blockingExpressions_m = true;
 }
      else if (word == "--pooma-noblocking-expressions")
 {
   blockingExpressions_m = false;
 }
      else if (word == "--pooma-help")
 {
   usage();
   exit(0);
 }
      else
 {
   retargv[retargc++] = argv[i];
 }
      if (!argok)
 {
   std::cerr << "\nERROR: Bad format for POOMA command-line option '";
   std::cerr << word.c_str() << "'.\n" << std::endl;
   usage();
   exit(0);
 }
      if (argvalerr)
 {
   std::cerr << "\n";
   std::cerr << "ERROR: Illegal value for POOMA command-line option '";
   std::cerr << word.c_str() << "'.\n" << std::endl;
   usage();
   exit(0);
 }
      ++i;
    }
  argc = retargc;
  for (i = 0; i < retargc; ++i) argv[i] = retargv[i];
  delete [] retargv;
}
bool intArgument(int argc, char **argv, int pos, int &val)
{
  if (pos >= argc)
    return false;
  char firstchar = argv[pos][0];
  if (firstchar < '0' || firstchar > '9')
    {
      if ((firstchar != '-' && firstchar != '+') || argv[pos][1] == 0 ||
   (argv[pos][1] < '0' || argv[pos][1] > '9'))
 return false;
    }
  val = atoi(argv[pos]);
  return true;
}
bool stringArgument(int argc, char **argv, int pos, std::string &val)
{
  if (pos >= argc)
    return false;
  val = argv[pos];
  return true;
}
bool doubleArgument(int argc, char **argv, int pos, double &val)
{
  if (pos >= argc)
    return false;
  val = atof(argv[pos]);
  return true;
}
}
namespace Pooma {
Statistics::Statistics()
{
}
Statistics::~Statistics()
{
  for (int i = 0; i < statList_m.size(); ++i)
    {
      delete statList_m[i];
    }
}
long Statistics::defaultFilter(long val)
{
  return val;
}
void Statistics::print(Inform &o, long (*filter)(long))
{
  int i, j;
  if (statList_m.size() == 0)
    return;
  o << "Runtime statistics summary:" << std::endl;
  for (i = 0; i < statList_m.size(); ++i)
    {
      o << statList_m[i]->description() << " ";
      int numperiods = 53 - strlen(statList_m[i]->description().c_str());
      if (numperiods < 2)
        numperiods = 2;
      for (j = 0; j < numperiods; ++j)
        o << ".";
      o << " " << std::setw(12) << filter(statList_m[i]->value()) << std::endl;
    }
}
}
namespace EOS {
  typedef enum {
    IdealAdiabatic = 0,
    Last = 4
  } Eos_t;
  struct pg_ig
  {
    pg_ig() {}
    template <class F1>
    pg_ig(const pg_ig& f, const F1&) {}
    template <class F1, class F2, class F3, class F4>
    void operator()(const F1& pg, const F2& T, const F3& rh, const F4& xmue) const
    {
      Interval<F1::dimensions> I = pg.totalDomain();
      pg(I) = (T*rh/xmue)(I);
    }
  };
  struct cs_adiabatic
  {
    cs_adiabatic() {}
    cs_adiabatic(double gamma) : gamma_m(gamma) {}
    template <class F>
    cs_adiabatic(const cs_adiabatic& f, const F&)
      : gamma_m(f.gamma_m) {}
    template <class F1, class F2, class F3>
    void operator()(const F1& cs, const F2& pg, const F3& rh) const
    {
      Interval<F1::dimensions> I = cs.totalDomain();
      cs(I) = (sqrt(gamma_m * pg/rh))(I);
    }
    double gamma_m;
  };
}
namespace Hacks {
  struct limit_rh
  {
    limit_rh() {}
    limit_rh(double rhomin) : rhomin_m(rhomin) {}
    template <class F>
    limit_rh(const limit_rh& l, const F&) : rhomin_m(l.rhomin_m) {}
    template <class F>
    void operator()(const F& rh);
    double rhomin_m;
  };
  template <class F>
  void checkRegularity(const F& f);
};
namespace Hacks {
  template <class F>
  void limit_rh::operator()(const F& rh)
  {
    Interval<F::dimensions> I = rh.physicalDomain();
    rh(I) = where(rh(I) < rhomin_m, rhomin_m);
  }
  template <int Dim>
  struct CheckRegularity {
    CheckRegularity() {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 1> &i) const
    {
      i.write(0, false);
      i.useGuards(0, false);
    }
    template <class F1>
    inline void operator()(const F1 &f, const Loc<Dim>& I) const
    {
      if (std::isnan(f(I)))
 Pooma::pAbort("NaN detected");
      if (std::isinf(f(I)))
 Pooma::pAbort("Inf detected");
    }
  };
  template <class F>
  void checkRegularity(const F& f)
  {
    ScalarCode<CheckRegularity<F::dimensions> >()(f);
  }
};
namespace CFL {
  template <int Dim>
  struct CflFunctor : public Deltas<Dim> {
    CflFunctor(double omrot, bool vis) : omrot_m(omrot), vis_m(vis) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
    {
      for (int d=0; d<Dim; ++d)
 i.extent().upper(d) = 1;
      i.write(0, true, false);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.useGuards(1, false);
      i.useGuards(2, false);
      i.useGuards(3, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4>
    inline void operator()(const F1 &dt, const F2 &cs, const F3 &nue, const F4 &v,
      const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = dt.mesh();
      double dtmin = m.vertexSpacing(0, I[0].first()+1)
 / (std::max(fabs(v.fieldEngine().engine(0, 0).read(I)), fabs(v.fieldEngine().engine(0, 0).read(I+dX)))
    + cs.read(I));
      if (Dim > 1)
 dtmin = std::min(dtmin,
    m.vertexSpacing(1, I[1].first()+1)
    / (std::max(fabs(v.fieldEngine().engine(0, 1).read(I)), fabs(v.fieldEngine().engine(0, 1).read(I+dY)))
       + cs.read(I)/m.GEOXG(I)));
      if (Dim > 2)
 dtmin = std::min(dtmin,
    m.vertexSpacing(2, I[2].first()+1)
    / (std::max(fabs(v.fieldEngine().engine(0, 2).read(I))+omrot_m, fabs(v.fieldEngine().engine(0, 2).read(I+dZ))+omrot_m)
       + cs.read(I)/(m.GEOXH(I)*m.GEOYH(I))));
 dt(I) = dtmin;
    }
    const double omrot_m;
    const bool vis_m;
  };
  template <int Dim, class F1, class F2, class F3, class F4>
  double schritt(const F1 &v, const F2 &cs, const F3 &nue,
   const F4 &scratch, double omrot, bool vis_f)
  {
    Interval<Dim> I(cs.physicalDomain());
    ScalarCode<CflFunctor<Dim> >(CflFunctor<Dim>(omrot, vis_f))(scratch, I, cs, nue, v);
    return min(scratch(I));
  }
}
GuardLayers<Dim> corr_v[Dim];
Interval<Dim> vertexDomain;
Vector<Dim> origin;
Traits_t::Spacings_t spacings;
double gamma_, K, cartvis_nr, cartvis_av;
Vector<2> smooth;
std::string commandline;
Vector<Dim, int> periodicity;
std::vector<Loc<Dim> > dump_points;
EOS::Eos_t eos;
bool a_nr_f = false;
int a_nr = std::numeric_limits<int>::max();
bool a_end_t_f = false;
double a_end_t = std::numeric_limits<double>::max();
bool a_blocks_f = false;
Loc<Dim> a_blocks;
bool a_cfl_f = false;
double a_cfl = 0.5;
bool a_constant_timestep_f = false;
double dt;
bool a_min_dt_f = false;
double a_min_dt = 0.0;
bool a_max_dt_f = false;
double a_max_dt = std::numeric_limits<double>::max();
bool a_cartvis_f = false;
bool a_eos_f = false;
EOS::Eos_t a_eos;
bool a_rhomin_f = false;
double a_rhomin = 1e-6;
namespace Adv5 {
  template<class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
  void advect(double dt,
       const F1 &rh, const F2 &v, double omrot_, const F3 &T,
       const F4 &flm, const F5 &fle, const F6 &flvv,
       const F7 &flvc, const F8 &cv, const F9 &ekin,
       bool eeq, bool ietot);
}
namespace Adv5 {
  template <int Dim>
  struct Ekin : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &ekin, const F2 &v, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = ekin.mesh();
      double ek = (v.fieldEngine().engine(0, 0).read(I)+v.fieldEngine().engine(0, 0).read(I+dX)) * (v.fieldEngine().engine(0, 0).read(I)+v.fieldEngine().engine(0, 0).read(I+dX));
      if (Dim > 1)
 ek += (v.fieldEngine().engine(0, 1).read(I)+v.fieldEngine().engine(0, 1).read(I+dY)) * (v.fieldEngine().engine(0, 1).read(I)+v.fieldEngine().engine(0, 1).read(I+dY)) * std::pow(m.GEOXG(I), 2);
      if (Dim > 2)
 ek += (v.fieldEngine().engine(0, 2).read(I)+v.fieldEngine().engine(0, 2).read(I+dZ)) * (v.fieldEngine().engine(0, 2).read(I)+v.fieldEngine().engine(0, 2).read(I+dZ)) * std::pow(m.GEOXH(I)*m.GEOYH(I), 2);
      ekin(I) = ek / 8.0;
    }
  };
  template <int Dim>
  struct VelupdX : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent().lower(0) = 1;
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &vx, const F2 &rh, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vx(I) = vx(I)
 / (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX));
    }
  };
  template <int Dim>
  struct VelupdY : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent().lower(1) = 1;
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &vy, const F2 &rh, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vy(I) = vy(I)
 / ((m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
    * std::pow(m.GEOXG(I), 2));
    }
  };
  template <int Dim>
  struct VelupdZ : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent().lower(2) = 1;
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &vz, const F2 &rh, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vz(I) = vz(I)
 / ((m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
    * std::pow(m.GEOXH(I),2) * std::pow(m.GEOYH(I),2));
    }
  };
  namespace X {
    template <int Dim>
    struct Massflow : public Deltas<Dim> {
      Massflow(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(0) = 2;
 i.extent().upper(0) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vx, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 double s = vx(I)*dt;
 Loc<Dim> IND = s > 0.0 ? I-dX : I;
 double grad1 = (rh(IND)-rh(IND-dX)) * (rh(IND+dX)-rh(IND));
 double grad = grad1 > 0.0
   ? 2.0*grad1 / ((rh(IND)-rh(IND-dX))*m.cellSpacing(IND+dX)(0)
    + (rh(IND+dX)-rh(IND))*m.cellSpacing(IND)(0))
   : 0.0;
 flmx(I) = (m.SURXA(I)-m.CCXA(I)*s) * s
   * (rh(IND)
      + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux : public Deltas<Dim> {
      Energyflux(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(0) = 2;
 i.extent().upper(0) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
 i.useGuards(3, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flex, const F2 &T, const F3 &vx, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = vx(I)*dt;
 IND = s > 0.0 ? I-dX : I;
 ddm1 = T(IND-dX);
 dd = T(IND);
 ddp1 = T(IND+dX);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
    + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
   : 0.0;
 flex(I) = flmx(I)
   * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxX : public Deltas<Dim> {
      MomentumfluxX(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(0) = 1;
 i.extent().upper(0) = 2;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flx, const F2 &vx, const F3 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (vx(I) + vx(I+dX)) * 0.5*dt;
 IND = s > 0.0 ? I : I+dX;
 ddm1 = vx(IND-dX);
 dd = vx(IND);
 ddp1 = vx(IND+dX);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(0)
    + (dd-ddm1)*m.vertexSpacing(IND+dX)(0))
   : 0.0;
 flx(I) = 0.5*(flmx(I) + flmx(I+dX))
   * (dd + (m.cellPosition(I)(0) - m.vertexPosition(IND)(0) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxY : public Deltas<Dim> {
      MomentumfluxY(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(0) = 2;
 i.extent().upper(0) = 1;
 i.extent().lower(1) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vx, const F3 &vy, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDY1(I)*vx(I) + m.DDY0(I)*vx(I-dY)) * dt;
 IND = s > 0.0 ? I-dX : I;
 ddm1 = vy(IND-dX) * std::pow(m.GEOXG(IND-dX), 2);
 dd = vy(IND) * std::pow(m.GEOXG(IND), 2);
 ddp1 = vy(IND+dX) * std::pow(m.GEOXG(IND+dX), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
    + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
   : 0.0;
 flx(I) = (m.DDY1(I)*flmx(I) + m.DDY0(I)*flmx(I-dY))
   * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxZ : public Deltas<Dim> {
      MomentumfluxZ(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(0) = 2;
 i.extent().upper(0) = 1;
 i.extent().lower(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vx, const F3 &vz, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDZ1(I)*vx(I)
      + m.DDZ0(I)*vx(I-dZ)) * dt;
 IND = s > 0.0 ? I-dX : I;
 ddm1 = vz.read(IND-dX)
   * std::pow(m.GEOXH(IND-dX), 2) * std::pow(m.GEOYH(I), 2);
 dd = vz.read(IND)
   * std::pow(m.GEOXH(IND), 2) * std::pow(m.GEOYH(I), 2);
 ddp1 = vz.read(IND+dX)
   * std::pow(m.GEOXH(IND+dX), 2) * std::pow(m.GEOYH(I), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
    + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
   : 0.0;
 flx(I) = (m.DDZ1(I)*flmx(I) + m.DDZ0(I)*flmx(I-dZ))
   * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux2 : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(0) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, false);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 T(I) = T(I)*rh(I)
   - (flex(I+dX) - flex(I)) / m.VOLXB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2X : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(0) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vx(I) = vx(I)
   * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
   - (flx(I) - flx(I-dX)) / m.VOLXA(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Y : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(0) = 1;
 i.extent().lower(1) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
   * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
   - (flx(I+dX) - flx(I)) / m.VOLXB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Z : public Deltas<Dim> {
      Momentumflux2Z(double omrot) : omrot_m(omrot) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(0) = 1;
 i.extent().lower(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vz(I) = (vz(I) + omrot_m) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
   * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
   - (flx(I+dX) - flx(I)) / m.VOLXB(I);
      }
      const double omrot_m;
    };
    template <int Dim>
    struct Densupd : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
      {
 i.extent().upper(0) = 1;
 i.write(0, true);
 i.write(1, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
      }
      using Deltas<Dim>::dX;
      template <class F1, class F2>
      inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 rh(I) = rh(I) - (flmx(I+dX)-flmx(I))/m.VOLXB(I);
      }
    };
    template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
    inline
    void advect(double dt,
  const F1 &rh, const F2 &v, const F3 &T,
  const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
  const F8 &cv, const F9 &ekin,
  double omrot, bool eeq, bool ietot)
    {
      (ScalarCode<Massflow<Dim> >(dt))(flm.center(0),
           rh, v.center(0));
      if (eeq) {
 if (ietot) {
   Interval<Dim> I(T.physicalDomain());
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = (cv*T + ekin)(I);
 }
 (ScalarCode<Energyflux<Dim> >(dt))(fle.center(0),
        T, v.center(0), flm.center(0));
 ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(),
     rh, fle.center(0));
      }
      (ScalarCode<MomentumfluxX<Dim> >(dt))(flvc,
         v.center(0), flm.center(0));
      if (Dim > 1)
 (ScalarCode<MomentumfluxY<Dim> >(dt))(flvv.comp(1), shrink(flvv.physicalDomain(), corr_v[1]),
           v.center(0), v.center(1), flm.center(0));
      if (Dim > 2)
 (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvv.comp(2), shrink(flvv.physicalDomain(), corr_v[2]),
           v.center(0), v.center(2)+omrot, flm.center(0));
      ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
      rh, flvc);
      if (Dim > 1)
 ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
        rh, flvv.comp(1));
      if (Dim > 2)
 (ScalarCode<Momentumflux2Z<Dim> >(omrot))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
        rh, flvv.comp(2));
      ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(0));
      ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
      if (Dim > 1)
 ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
      if (Dim > 2) {
 ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
 if (omrot != 0.0)
   v.center(2)(shrink(v.center(2).physicalDomain(), corr_v[2])) -= omrot;
      }
      if (eeq) {
 Interval<Dim> I(T.physicalDomain());
 if (!ietot)
   T(I) = (T / rh)(I);
 else {
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = ((T / rh - ekin)/cv)(I);
 }
      }
    }
  };
  namespace Y {
    template <int Dim>
    struct Massflow : public Deltas<Dim> {
      Massflow(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(1) = 2;
 i.extent().upper(1) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vy, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 double s = vy(I)*dt;
 Loc<Dim> IND = s > 0.0 ? I-dY : I;
 double grad1 = (rh(IND)-rh(IND-dY)) * (rh(IND+dY)-rh(IND));
 double grad = grad1 > 0.0
   ? 2.0*grad1 / ((rh(IND)-rh(IND-dY))*m.cellSpacing(IND+dY)(1)
    + (rh(IND+dY)-rh(IND))*m.cellSpacing(IND)(1))
   : 0.0;
 flmx(I) = (m.SURYA(I)+m.CCYA(I)*s) * s
   * (rh(IND)
      + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux : public Deltas<Dim> {
      Energyflux(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(1) = 2;
 i.extent().upper(1) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
 i.useGuards(3, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flex, const F2 &T, const F3 &vy, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = vy(I)*dt;
 IND = s > 0.0 ? I-dY : I;
 ddm1 = T(IND-dY);
 dd = T(IND);
 ddp1 = T(IND+dY);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
    + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
   : 0.0;
 flex(I) = flmx(I)
   * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxX : public Deltas<Dim> {
      MomentumfluxX(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(0) = 1;
 i.extent().lower(1) = 2;
 i.extent().upper(1) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vy, const F3 &vx, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDX1(I)*vy(I) + m.DDX0(I)*vy(I-dX)) * dt;
 IND = s > 0.0 ? I-dY : I;
 ddm1 = vx(IND-dY);
 dd = vx(IND);
 ddp1 = vx(IND+dY);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
    + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
   : 0.0;
 flx(I) = (m.DDX1(I)*flmx(I) + m.DDX0(I)*flmx(I-dX))
   * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxY : public Deltas<Dim> {
      MomentumfluxY(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(1) = 1;
 i.extent().upper(1) = 2;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flx, const F2 &vy, const F3 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (vy(I) + vy(I+dY)) * 0.5 * dt;
 IND = s > 0.0 ? I : I+dY;
 ddm1 = vy(IND-dY) * std::pow(m.GEOXG(I), 2);
 dd = vy(IND) * std::pow(m.GEOXG(I), 2);
 ddp1 = vy(IND+dY) * std::pow(m.GEOXG(I), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(1)
    + (dd-ddm1)*m.vertexSpacing(IND+dY)(1))
   : 0.0;
 flx(I) = 0.5*(flmx(I) + flmx(I+dY))
   * (dd + (m.cellPosition(I)(1) - m.vertexPosition(IND)(1) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxZ : public Deltas<Dim> {
      MomentumfluxZ(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(1) = 2;
 i.extent().upper(1) = 1;
 i.extent().lower(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vy, const F3 &vz, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDZ1(I)*vy(I)
      + m.DDZ0(I)*vy(I-dZ)) * dt;
 IND = s > 0.0 ? I-dY : I;
 ddm1 = vz.read(IND-dY)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND-dY), 2);
 dd = vz.read(IND)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND), 2);
 ddp1 = vz.read(IND+dY)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND+dY), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
    + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
   : 0.0;
 flx(I) = (m.DDZ1(I)*flmx(I) + m.DDZ0(I)*flmx(I-dZ))
   * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux2 : public Deltas<Dim> {
      Energyflux2() {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(1) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, false);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dY;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 T(I) = T(I)*rh(I)
   - (flex(I+dY) - flex(I)) / m.VOLYB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2X : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(0) = 1;
 i.extent().upper(1) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vx(I) = vx(I)
   * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
   - (flx(I+dY) - flx(I)) / m.VOLYB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Y : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(1) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
   * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
   - (flx(I) - flx(I-dY)) / m.VOLYA(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Z : public Deltas<Dim> {
      Momentumflux2Z(double omrot) : omrot_m(omrot) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(1) = 1;
 i.extent().lower(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vz(I) = (vz(I)+omrot_m) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
   * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
   - (flx(I+dY) - flx(I)) / m.VOLYB(I);
      }
      const double omrot_m;
    };
    template <int Dim>
    struct Densupd : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
      {
 i.extent().upper(1) = 1;
 i.write(0, true);
 i.write(1, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
      }
      using Deltas<Dim>::dY;
      template <class F1, class F2>
      inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 rh(I) = rh(I) - (flmx(I+dY)-flmx(I))/m.VOLYB(I);
      }
    };
    template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
    inline
    void advect(double dt,
  const F1 &rh, const F2 &v, const F3 &T,
  const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
  const F8 &cv, const F9 &ekin,
  double omrot, bool eeq, bool ietot)
    {
      (ScalarCode<Massflow<Dim> >(dt))(flm.center(1),
           rh, v.center(1));
      if (eeq) {
 if (ietot) {
   Interval<Dim> I(T.physicalDomain());
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = (cv*T + ekin)(I);
 }
 (ScalarCode<Energyflux<Dim> >(dt))(fle.center(1),
        T, v.center(1), flm.center(1));
 ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(),
     rh, fle.center(1));
      }
      (ScalarCode<MomentumfluxX<Dim> >(dt))(flvv.comp(0), shrink(flvv.physicalDomain(), corr_v[0]),
         v.center(1), v.center(0), flm.center(1));
      if (Dim > 1)
 (ScalarCode<MomentumfluxY<Dim> >(dt))(flvc,
           v.center(1), flm.center(1));
      if (Dim > 2)
 (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvv.comp(2), shrink(flvv.physicalDomain(), corr_v[2]),
           v.center(1), v.center(2)+omrot, flm.center(1));
      ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
      rh, flvv.comp(0));
      if (Dim > 1)
 ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
        rh, flvc);
      if (Dim > 2)
 (ScalarCode<Momentumflux2Z<Dim> >(omrot))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
        rh, flvv.comp(2));
      ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(1));
      ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
      if (Dim > 1)
 ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
      if (Dim > 2) {
 ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
 if (omrot != 0.0)
   v.center(2)(shrink(v.center(2).physicalDomain(), corr_v[2])) -= omrot;
      }
      if (eeq) {
 Interval<Dim> I(T.physicalDomain());
 if (!ietot)
   T(I) = (T / rh)(I);
 else {
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = ((T / rh - ekin)/cv)(I);
 }
      }
    }
  };
  namespace Z {
    template <int Dim>
    struct Massflow : public Deltas<Dim> {
      Massflow(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(2) = 2;
 i.extent().upper(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vz, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 double s = vz(I)*dt;
 Loc<Dim> IND = s > 0.0 ? I-dZ : I;
 double grad1 = (rh(IND)-rh(IND-dZ)) * (rh(IND+dZ)-rh(IND));
 double grad = grad1 > 0.0
   ? 2.0*grad1 / ((rh(IND)-rh(IND-dZ))*m.cellSpacing(IND+dZ)(2)
    + (rh(IND+dZ)-rh(IND))*m.cellSpacing(IND)(2))
   : 0.0;
 flmx(I) = (m.SURZA(I)-m.CCZA(I)*s) * s
   * (rh(IND)
      + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux : public Deltas<Dim> {
      Energyflux(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(2) = 2;
 i.extent().upper(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, false);
 i.useGuards(3, false);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flex, const F2 &T, const F3 &vz, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = vz(I)*dt;
 IND = s > 0.0 ? I-dZ : I;
 ddm1 = T(IND-dZ);
 dd = T(IND);
 ddp1 = T(IND+dZ);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
    + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
   : 0.0;
 flex(I) = flmx(I)
   * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxX : public Deltas<Dim> {
      MomentumfluxX(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(0) = 1;
 i.extent().lower(2) = 2;
 i.extent().upper(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vz, const F3 &vx, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDX1(I)*vz(I) + m.DDX0(I)*vz(I-dX)) * dt;
 IND = s > 0.0 ? I-dZ : I;
 ddm1 = vx(IND-dZ);
 dd = vx(IND);
 ddp1 = vx(IND+dZ);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
    + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
   : 0.0;
 flx(I) = (m.DDX1(I)*flmx(I) + m.DDX0(I)*flmx(I-dX))
   * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxY : public Deltas<Dim> {
      MomentumfluxY(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
      {
 i.extent().lower(1) = 1;
 i.extent().lower(2) = 2;
 i.extent().upper(2) = 1;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.write(3, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
 i.useGuards(3, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3, class F4>
      inline void operator()(const F1 &flx, const F2 &vz, const F3 &vy, const F4 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (m.DDY1(I)*vz(I)
      + m.DDY0(I)*vz(I-dY)) * dt;
 IND = s > 0.0 ? I-dZ : I;
 ddm1 = vy(IND-dZ) * std::pow(m.GEOXG(I), 2);
 dd = vy(IND) * std::pow(m.GEOXG(I), 2);
 ddp1 = vy(IND+dZ) * std::pow(m.GEOXG(I), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
    + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
   : 0.0;
 flx(I) = (m.DDY1(I)*flmx(I) + m.DDY0(I)*flmx(I-dY))
   * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct MomentumfluxZ : public Deltas<Dim> {
      MomentumfluxZ(double dt_) : dt(dt_) {}
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(2) = 1;
 i.extent().upper(2) = 2;
 i.write(0, true, false);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      double dt;
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &flx, const F2 &vz, const F3 &flmx,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = flx.mesh();
 Loc<Dim> IND = Pooma::NoInit();
 double s, ddm1, dd, ddp1, grad1, grad;
 s = (vz(I) + vz(I+dZ)) * 0.5*dt;
 IND = s > 0.0 ? I : I+dZ;
 ddm1 = vz(IND-dZ)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
 dd = vz(IND)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
 ddp1 = vz(IND+dZ)
   * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
 grad1 = (dd-ddm1)*(ddp1-dd);
 grad = grad1 > 0.0
   ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(2)
    + (dd-ddm1)*m.vertexSpacing(IND+dZ)(2))
   : 0.0;
 flx(I) = 0.5*(flmx(I) + flmx(I+dZ))
   * (dd + (m.cellPosition(I)(2) - m.vertexPosition(IND)(2) - 0.5*s) * grad);
      }
    };
    template <int Dim>
    struct Energyflux2 : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().upper(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, false);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
        const Loc<Dim>& I) const
      {
 const typename F3::Mesh_t &m = T.mesh();
 T(I) = T(I)*rh(I)
   - (flex(I+dZ) - flex(I)) / m.VOLZB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2X : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(0) = 1;
 i.extent().upper(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vx(I) = vx(I)
   * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
   - (flx(I+dZ) - flx(I)) / m.VOLZA(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Y : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(1) = 1;
 i.extent().upper(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
   * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
   - (flx(I+dZ) - flx(I)) / m.VOLZB(I);
      }
    };
    template <int Dim>
    struct Momentumflux2Z : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
      {
 i.extent().lower(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.write(2, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
 i.useGuards(2, true);
      }
      using Deltas<Dim>::dX;
      using Deltas<Dim>::dY;
      using Deltas<Dim>::dZ;
      template <class F1, class F2, class F3>
      inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
        const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 vz(I) = vz(I) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
   * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
   - (flx(I) - flx(I-dZ)) / m.VOLZB(I);
      }
    };
    template <int Dim>
    struct Densupd : public Deltas<Dim> {
      inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
      {
 i.extent().upper(2) = 1;
 i.write(0, true);
 i.write(1, false);
 i.useGuards(0, false);
 i.useGuards(1, true);
      }
      using Deltas<Dim>::dZ;
      template <class F1, class F2>
      inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
      {
 const typename F1::Mesh_t &m = rh.mesh();
 rh(I) = rh(I) - (flmx(I+dZ)-flmx(I))/m.VOLZB(I);
      }
    };
    template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
    inline
    void advect(double dt,
  const F1 &rh, const F2 &v, const F3 &T,
  const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
  const F8 &cv, const F9 &ekin,
  bool eeq, bool ietot)
    {
      (ScalarCode<Massflow<Dim> >(dt))(flm.center(2),
           rh, v.center(2));
      if (eeq) {
 if (ietot) {
   Interval<Dim> I(T.physicalDomain());
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = (cv*T + ekin)(I);
 }
 (ScalarCode<Energyflux<Dim> >(dt))(fle.center(2),
        T, v.center(2), flm.center(2));
 ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(), rh, fle.center(2));
      }
      (ScalarCode<MomentumfluxX<Dim> >(dt))(flvv.comp(0), shrink(flvv.physicalDomain(), corr_v[0]),
         v.center(2), v.center(0), flm.center(2));
      if (Dim > 1)
 (ScalarCode<MomentumfluxY<Dim> >(dt))(flvv.comp(1), shrink(flvv.physicalDomain(), corr_v[1]),
           v.center(2), v.center(1), flm.center(2));
      if (Dim > 2)
 (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvc,
           v.center(2), flm.center(2));
      ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
      rh, flvv.comp(0));
      if (Dim > 1)
 ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
        rh, flvv.comp(1));
      if (Dim > 2)
 ScalarCode<Momentumflux2Z<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
        rh, flvc);
      ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(2));
      ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
      if (Dim > 1)
 ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
      if (Dim > 2)
 ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
      if (eeq) {
 Interval<Dim> I(T.physicalDomain());
 if (!ietot)
   T(I) = (T / rh)(I);
 else {
   ScalarCode<Ekin<Dim> >()(ekin, v);
   T(I) = ((T / rh - ekin)/cv)(I);
 }
      }
    }
  };
  template <class CoordinateSystemTag>
  double omrotForAdvect(double omrot) { return omrot; }
  template <>
  double omrotForAdvect<CartesianTag>(double omrot) { return 0.0; }
  template<class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
  void advect(double dt,
       const F1 &rh, const F2 &v, double omrot_, const F3 &T,
       const F4 &flm, const F5 &fle, const F6 &flvv,
       const F7 &flvc, const F8 &cv, const F9 &ekin,
       bool eeq, bool ietot)
  {
    static int it = 0;
    enum { Dim = F1::dimensions };
    double omrot = omrotForAdvect<typename F1::Mesh_t::MeshTraits_t::CoordinateSystemTag_t>(omrot_);
    if (it++ % 2 == 0) {
      X::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
      Y::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
      Z::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, eeq, ietot);
    } else {
      Z::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, eeq, ietot);
      Y::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
      X::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
    }
  }
};
namespace Forgas {
  template <class F1, class F2, class F3, class F4, class F5,
     class F6, class F7, class F8, class F9, class F10,
     class F11, class F12, class F13,
     class F14, class F15, class F16, class F17>
  void force(double dt, const F1 &rh, F2 &T, F3 &v, double omrot, F4 &pg, const F5 &ph,
      const F11& cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
      const F9 &vint, F10 &cent, const F12 &a_pg, const F13 &gradv,
      const F14 &Tii, const F15 &Tij, const F16 &fvis, const F17 &eta, bool vis,
      double c_nr, bool cartvis_f, bool eeq);
  template <class F1, class F2, class F3, class F4, class F5,
     class F6, class F7, class F8, class F9, class F10, class F11,
     class F12, class F13, class F14, class F15>
  void force(double dt, const F1 &rh, const F2 &T, const F3 &v, double omrot, F4 &pg, const F5 &ph,
      const F11 &cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
      const F9 &vint, const F10 &cent,
      const F12 &Tii, const F13 &Tij, const F14 &fvis, const F15 &eta, bool vis,
      double c_nr, double c_av, bool cartvis_f, bool eeq);
}
namespace Forgas {
template <class F>
struct IsSpherical {
  enum { result = false };
};
template <template <class> class Mesh, int Dim, class MeshTag, class T, class E>
struct IsSpherical<Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >, T, E> > {
  enum { result = true };
};
template <class F>
static bool isSpherical()
{
  return IsSpherical<F>::result;
}
template <class F>
struct IsNotCartesian {
  enum { result = true };
};
template <template <class> class Mesh, int Dim, class MeshTag, class T, class E>
struct IsNotCartesian<Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >, T, E> > {
  enum { result = false };
};
template <class F>
static bool isNotCartesian()
{
  return IsNotCartesian<F>::result;
}
template <class CAV>
struct ViscTii : public Deltas<3> {
  ViscTii(const CAV& av) : c_av(av) {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 4> &i) const
  {
    i.extent(GuardLayers<3>(Loc<3>(0), Loc<3>(1)));
    i.write(0, true);
    i.write(1, false);
    i.write(2, false);
    i.write(3, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
    i.useGuards(2, false);
    i.useGuards(3, false);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2, class F3, class F4>
  inline void operator()(const F1 &T, const F2 &v, const F4 &rh, const F3 &eta,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = T.mesh();
    double divu = ((m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX) - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I)
     + (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY) - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I)
     + (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ) - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I));
    T(I)(0) = 2.0 * eta.read(I) * rh.read(I)
      * ((v.fieldEngine().engine(0, 0).read(I+dX) - v.fieldEngine().engine(0, 0).read(I))/m.vertexSpacing(I+dX)(0)
  - 1.0/3.0 * divu)
      - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
    T(I)(1) = 2.0 * eta.read(I) * rh.read(I)
      * ((v.fieldEngine().engine(0, 1).read(I+dY) - v.fieldEngine().engine(0, 1).read(I))/m.vertexSpacing(I+dY)(1)
  + (isSpherical<F1>() ? (v.fieldEngine().engine(0, 0).read(I) + v.fieldEngine().engine(0, 0).read(I+dX))/(2.0*m.cellPosition(I)(0)) : 0.0)
  - 1.0/3.0 * divu)
      - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
    T(I)(2) = 2.0 * eta.read(I) * rh.read(I)
      * ((v.fieldEngine().engine(0, 2).read(I+dZ) - v.fieldEngine().engine(0, 2).read(I))/m.vertexSpacing(I+dZ)(2)
  + (isNotCartesian<F1>() ? 0.5 * (v.fieldEngine().engine(0, 0).read(I) + v.fieldEngine().engine(0, 0).read(I+dX))/m.cellPosition(I)(0) : 0.0)
  - (isSpherical<F1>() ? 0.5 * (v.fieldEngine().engine(0, 1).read(I) + v.fieldEngine().engine(0, 1).read(I+dY))/tan(m.cellPosition(I)(1)) : 0.0)
  - 1.0/3.0 * divu)
      - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
  }
  CAV c_av;
};
struct Txy : public Deltas<3> {
  Txy() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
  {
    i.extent().lower(0) = 1;
    i.extent().lower(1) = 1;
    i.write(0, true);
    i.write(1, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2>
  inline void operator()(const F1 &T, const F2 &v,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = T.mesh();
    T(I) = (v.fieldEngine().engine(0, 1).read(I) - v.fieldEngine().engine(0, 1).read(I-dX)) * m.GEOXGA(I) / m.cellSpacing(I)(0)
      + (v.fieldEngine().engine(0, 0).read(I) - v.fieldEngine().engine(0, 0).read(I-dY)) / (m.GEOXGA(I) * m.cellSpacing(I)(1));
  }
};
struct Txz : public Deltas<3> {
  Txz() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
  {
    i.extent().lower(0) = 1;
    i.extent().lower(2) = 1;
    i.write(0, true);
    i.write(1, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2>
  inline void operator()(const F1 &T, const F2 &v,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = T.mesh();
    T(I) = (v.fieldEngine().engine(0, 2).read(I) - v.fieldEngine().engine(0, 2).read(I-dX)) * m.GEOXH(I) * m.GEOYH(I) / m.cellSpacing(I)(0)
      + (v.fieldEngine().engine(0, 0).read(I) - v.fieldEngine().engine(0, 0).read(I-dZ)) / (m.GEOXH(I) * m.GEOYH(I) * m.cellSpacing(I)(2));
  }
};
struct Tyz : public Deltas<3> {
  Tyz() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
  {
    i.extent().lower(1) = 1;
    i.extent().lower(2) = 1;
    i.write(0, true);
    i.write(1, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2>
  inline void operator()(const F1 &T, const F2 &v,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = T.mesh();
    T(I) = (v.fieldEngine().engine(0, 2).read(I) - v.fieldEngine().engine(0, 2).read(I-dY)) * m.GEOYHA(I) / m.cellSpacing(I)(1)
      + (v.fieldEngine().engine(0, 1).read(I) - v.fieldEngine().engine(0, 1).read(I-dZ)) / (m.GEOYHA(I) * m.cellSpacing(I)(2));
  }
};
struct ViscForceX : public Deltas<3> {
  ViscForceX() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
  {
    i.extent().lower(0) = 1;
    i.extent().upper(1) = 1;
    i.extent().upper(2) = 1;
    i.write(0, true);
    i.write(1, false);
    i.write(2, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
    i.useGuards(2, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2, class F3>
  inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = f.mesh();
    f(I) = (Tii(I)(0) * m.SURXB(I) - Tii(I-dX)(0) * m.SURXB(I-dX)) / m.VOLXA(I-dX)
      + (Tij.fieldEngine().engine(0, 0).read(I+dY) * m.SURYA(I+dY) - Tij.fieldEngine().engine(0, 0).read(I) * m.SURYA(I)) / (m.VOLYB(I)*m.GEOXHA(I))
      + (Tij.fieldEngine().engine(0, 1).read(I+dZ) * m.SURZA(I+dZ) - Tij.fieldEngine().engine(0, 1).read(I) * m.SURZA(I)) / (m.VOLZB(I)*m.GEOXHA(I)*m.GEOYH(I))
      - (isNotCartesian<F1>() ? ((isSpherical<F1>() ? Tii(I-dX)(1) + Tii(I)(1) : 0.0)
     + Tii(I-dX)(2) + Tii(I)(2)) / (2.0*m.vertexPosition(I)(0))
  : 0.0);
  }
};
struct ViscForceY : public Deltas<3> {
  ViscForceY() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
  {
    i.extent().lower(1) = 1;
    i.extent().upper(0) = 1;
    i.extent().upper(2) = 1;
    i.write(0, true);
    i.write(1, false);
    i.write(2, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
    i.useGuards(2, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2, class F3>
  inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = f.mesh();
    f(I) = (Tij.fieldEngine().engine(0, 0).read(I+dX) * m.SURXA(I+dX) - Tij.fieldEngine().engine(0, 0).read(I) * m.SURXA(I)) / m.VOLXB(I)
      + (Tii(I)(1) * m.SURYB(I) - Tii(I-dY)(1) * m.SURYB(I-dY)) / (m.VOLYA(I-dY)*m.GEOXG(I))
      + (Tij.fieldEngine().engine(0, 2).read(I+dZ) * m.SURZA(I+dZ) - Tij.fieldEngine().engine(0, 2).read(I) * m.SURZA(I)) / (m.VOLZB(I)*m.GEOXH(I)*m.GEOYHA(I))
      + (isSpherical<F1>() ? (Tij.fieldEngine().engine(0, 0).read(I) + Tij.fieldEngine().engine(0, 0).read(I+dX)
         + (Tii(I-dY)(2) + Tii(I)(2)) / tan(m.cellPosition(I)(1))) / (2.0*m.cellPosition(I)(0))
  : 0.0);
  }
};
struct ViscForceZ : public Deltas<3> {
  ViscForceZ() {}
  inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
  {
    i.extent().lower(2) = 1;
    i.extent().upper(0) = 1;
    i.extent().upper(1) = 1;
    i.write(0, true);
    i.write(1, false);
    i.write(2, false);
    i.useGuards(0, false);
    i.useGuards(1, true);
    i.useGuards(2, true);
  }
  using Deltas<3>::dX;
  using Deltas<3>::dY;
  using Deltas<3>::dZ;
  template <class F1, class F2, class F3>
  inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
    const Loc<3>& I) const
  {
    const typename F1::Mesh_t &m = f.mesh();
    f(I) = (Tij.fieldEngine().engine(0, 1).read(I+dX) * m.SURXA(I+dX) - Tij.fieldEngine().engine(0, 1).read(I) * m.SURXA(I)) / m.VOLXB(I)
      + (Tij.fieldEngine().engine(0, 2).read(I+dY) * m.SURYA(I+dY) - Tij.fieldEngine().engine(0, 2).read(I) * m.SURYA(I)) / (m.VOLYB(I)*m.GEOXG(I))
      + (Tii(I)(2) * m.SURZB(I) - Tii(I-dZ)(2) * m.SURZB(I-dZ)) / (m.VOLZA(I)*m.GEOXH(I)*m.GEOYH(I))
      + (isNotCartesian<F1>() ? ((Tij.fieldEngine().engine(0, 1).read(I) + Tij.fieldEngine().engine(0, 1).read(I+dX)
      - (isSpherical<F1>() ? (Tij.fieldEngine().engine(0, 2).read(I) + Tij.fieldEngine().engine(0, 2).read(I+dY))
         / tan(m.cellPosition(I)(1))
         : 0.0))
     / (2.0*m.cellPosition(I)(0)))
  : 0.0);
  }
};
  template <int Dim>
  struct TGuess : public Deltas<Dim> {
    TGuess(double dt_) : dt(dt_) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 7> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.write(4, false);
      i.write(5, false);
      i.write(6, false);
      i.useGuards(0, false);
      i.useGuards(1, false);
      i.useGuards(2, false);
      i.useGuards(3, true);
      i.useGuards(4, false);
      i.useGuards(5, false);
      i.useGuards(6, false);
    }
    double dt;
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4, class F5, class F6, class F7>
    inline void operator()(const F1 &pg, const F2 &T, const F3 &rh, const F4 &v,
      const F5 &cv, const F6 &dlmdlt, const F7 &xmue, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = pg.mesh();
      double g = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
    - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I)) / m.VOLXB(I);
      if (Dim > 1)
 g += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
       - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I)) / m.VOLYB(I);
      if (Dim > 2)
 g += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
       - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I)) / m.VOLZB(I);
      double tguess = T(I)
 - (dt
    * pg(I) / rh(I) / cv.read(I)
    * (1.0 - dlmdlt.read(I))
    * g);
      pg(I) = tguess * rh(I) / xmue.read(I);
    }
  };
  template <int Dim>
  struct CentX : public Deltas<Dim> {
    CentX(double omrot) : omrot_m(omrot) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
    {
      i.extent().lower(0) = 1;
      i.extent().upper(1) = 1;
      if (Dim > 2)
 i.extent().upper(2) = 1;
      i.write(0, true, false);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.useGuards(0, false);
      i.useGuards(1, false);
      i.useGuards(2, true);
      if (Dim > 2)
 i.useGuards(3, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >,
                  T, EngineTag> &centx,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      const typename MeshTraits<Dim, T, MeshTag, CartesianTag>::Mesh_t &m = centx.mesh();
      centx(I) = omrot_m*omrot_m*m.vertexPosition(I)(0);
    }
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CylindricalTag> >,
                  T, EngineTag> &centx,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      const typename MeshTraits<Dim, T, MeshTag, CylindricalTag>::Mesh_t &m = centx.mesh();
      double hq = 0.5*(m.DDX0(I)*(vz(I-dX) + vz(I-dX+dZ))
         + m.DDX1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
      centx(I) = m.vertexPosition(I)(0) * std::pow(hq, 2);
    }
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >,
                  T, EngineTag> &centx,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      const typename MeshTraits<Dim, T, MeshTag, SphericalTag>::Mesh_t &m = centx.mesh();
      double hq = 0.5*(m.DDX0(I)*(vz(I-dX) + vz(I-dX+dZ))
         + m.DDX1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
      double gq = 0.5*(m.DDX0(I)*(vy(I-dX+dY) + vy(I-dX))
         + m.DDX1(I)*(vy(I+dY) + vy(I)));
      centx(I) = m.vertexPosition(I)(0)
 * (std::pow(gq, 2) + std::pow(hq*sin(m.cellPosition(I)(1)), 2));
    }
    const double omrot_m;
  };
  template <int Dim>
  struct CentY : public Deltas<Dim> {
    CentY(double omrot) : omrot_m(omrot) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
    {
      i.extent().upper(0) = 1;
      i.extent().lower(1) = 1;
      if (Dim > 2)
 i.extent().upper(2) = 1;
      i.write(0, true, false);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
      i.useGuards(2, false);
      if (Dim > 2)
 i.useGuards(3, true);
    }
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >,
                  T, EngineTag> &centy,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      const typename MeshTraits<Dim, T, MeshTag, CartesianTag>::Mesh_t &m = centy.mesh();
      centy(I) = - omrot_m*omrot_m*m.vertexPosition(I)(1);
    }
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CylindricalTag> >,
                  T, EngineTag> &centy,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      centy(I) = 0.0;
    }
    template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
       class F2, class F3, class F4>
    inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >,
                  T, EngineTag> &centy,
      const F4 &vx, const F2 &vy, const F3 &vz,
      const Loc<Dim>& I) const
    {
      const typename MeshTraits<Dim, T, MeshTag, SphericalTag>::Mesh_t &m = centy.mesh();
      double hq = 0.5*(m.DDY0(I)*(vz(I-dY) + vz(I-dY+dZ))
         + m.DDY1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
      centy(I) = -cos(m.vertexPosition(I)(1)) * sin(m.vertexPosition(I)(1)) * std::pow(hq, 2)
 * m.cellPosition(I)(0);
    }
    const double omrot_m;
  };
  template <int Dim>
  struct VXUpd : public Deltas<Dim> {
    VXUpd(double dt_) : dt(dt_) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
    {
      i.extent().lower(0) = 1;
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.write(4, false);
      i.write(5, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
      i.useGuards(2, true);
      i.useGuards(3, true);
      i.useGuards(4, false);
      i.useGuards(5, false);
    }
    double dt;
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4, class F5, class F6>
    inline void operator()(const F1 &vx, const F2 &rh, const F3 &pg, const F4 &ph,
      const F5 &centx, const F6 &fvisx, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vx(I) = vx(I)
 + dt * ((-(pg.read(I)-pg.read(I-dX)) / m.cellSpacing(I)(0)
   + fvisx(I))
  / (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
  - (ph(I)-ph(I-dX)) / m.cellSpacing(I)(0)
  + centx(I));
    }
  };
  template <int Dim>
  struct VYUpd : public Deltas<Dim> {
    VYUpd(double dt_) : dt(dt_) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
    {
      i.extent().lower(1) = 1;
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.write(4, false);
      i.write(5, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
      i.useGuards(2, true);
      i.useGuards(3, true);
      i.useGuards(4, false);
      i.useGuards(5, false);
    }
    double dt;
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4, class F5, class F6>
    inline void operator()(const F1 &vy, const F2 &rh, const F3 &pg, const F4 &ph,
      const F5 &centy, const F6 &fvisy, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vy(I) = vy(I)
 + (dt * ((-(pg.read(I)-pg.read(I-dY)) / (m.cellSpacing(I)(1) * m.GEOXG(I))
    + fvisy(I))
   / (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
   -((ph(I)-ph(I-dY))
     / (m.cellSpacing(I)(1) * m.GEOXG(I)))
   - centy(I))
    / m.GEOXG(I));
    }
  };
  template <int Dim>
  struct VZUpd : public Deltas<Dim> {
    VZUpd(double dt_) : dt(dt_) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 5> &i) const
    {
      i.extent().lower(2) = 1;
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.write(4, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
      i.useGuards(2, true);
      i.useGuards(3, true);
      i.useGuards(4, true);
    }
    double dt;
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4, class F5>
    inline void operator()(const F1 &vz, const F2 &rh, const F3 &pg, const F4 &ph,
      const F5 &fvisz, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = rh.mesh();
      vz(I) = vz(I)
 + (dt * ((-(pg.read(I)-pg.read(I-dZ)) / (m.cellSpacing(I)(2)*m.GEOXH(I)*m.GEOYH(I))
    + fvisz(I))
   / (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
   -((ph(I)-ph(I-dZ))
     / (m.cellSpacing(I)(2)*m.GEOXH(I)*m.GEOYH(I)))
                          )
    / (m.GEOXH(I)*m.GEOYH(I)));
    }
  };
  template <int Dim>
  struct TUpd : public Deltas<Dim> {
    TUpd(double dt_) : dt(dt_) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.write(4, false);
      i.write(5, false);
      i.useGuards(0, false);
      i.useGuards(1, false);
      i.useGuards(2, true);
      i.useGuards(3, false);
      i.useGuards(4, false);
      i.useGuards(5, false);
    }
    double dt;
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4, class F5, class F6>
    inline void operator()(const F1 &T, const F2 &rh, const F3 &v, const F4 &pg,
      const F5 &cv, const F6 &dlmdlt, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = T.mesh();
      double g = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
    - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I)) / m.VOLXB(I);
      if (Dim > 1)
 g += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
       - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I)) / m.VOLYB(I);
      if (Dim > 2)
 g += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
       - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I)) / m.VOLZB(I);
      T(I) = T(I)
 - (dt
    * pg.read(I) / rh(I) / cv.read(I)
    * (1.0 - dlmdlt.read(I))
    * g);
    }
  };
  template <int Dim>
  struct GradV : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true, false);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &grad_v, const F2 &v, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = grad_v.mesh();
      grad_v(I)(0) = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
        - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I);
      if (Dim > 1)
 grad_v(I)(1) = (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
   - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I);
      if (Dim > 2)
 grad_v(I)(2) = (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
   - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I);
    }
  };
  template <int Dim>
  struct GradVdX : public Deltas<Dim> {
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true, false);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2>
    inline void operator()(const F1 &grad_v, const F2 &v, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = grad_v.mesh();
      grad_v(I)(0) = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
        - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I));
      if (Dim > 1)
 grad_v(I)(1) = (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
   - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I));
      if (Dim > 2)
 grad_v(I)(2) = (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
   - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I));
    }
  };
  template <int Dim>
  struct APressure : public Deltas<Dim> {
    APressure(double cnr, double cav) : c_nr(cnr), c_av(cav) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
    {
      i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
      i.write(0, true);
      i.write(1, false);
      i.write(2, false);
      i.write(3, false);
      i.useGuards(0, false);
      i.useGuards(1, false);
      i.useGuards(2, true);
      i.useGuards(3, false);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    using Deltas<Dim>::dZ;
    template <class F1, class F2, class F3, class F4>
    inline void operator()(const F1 &pg, const F2 &rh, const F3 &v, const F4 &cs,
      const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = pg.mesh();
      double q = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
    - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I);
      if (Dim > 1)
 q += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
       - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I);
      if (Dim > 2)
 q += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
       - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I);
      if (q >= 0.0)
 return;
      q *= m.vertexSpacing(I)(0);
      pg(I) += c_nr * q * q * rh(I);
      pg(I) -= c_av * rh(I) * cs(I) * q;
    }
  private:
    const double c_nr, c_av;
  };
  template <class CoordinateSystemTag>
  struct ApplyCoriolis
  {
    template <class F1, class F2>
    static void applyCoriolis(const F1&, const F2&, double) {}
  };
  template <int Dim>
  struct CoriolisX : public Deltas<Dim> {
    CoriolisX(double dphi) : sin2o_m(sin(2*dphi)), cos2o_m(cos(2*dphi)) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent().lower(0) = 1;
      i.extent().upper(1) = 1;
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    template <class F1, class F2>
    inline void operator()(const F1 &vx, const F2 &v, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = v.mesh();
      double vyx = 0.5*(m.DDX0(I)*(v.fieldEngine().engine(0, 1).read(I-dX)
       + v.fieldEngine().engine(0, 1).read(I-dX+dY))
   + m.DDX1(I)*(v.fieldEngine().engine(0, 1).read(I)
         + v.fieldEngine().engine(0, 1).read(I+dY)));
      vx(I) = v.fieldEngine().engine(0, 0).read(I)*cos2o_m + vyx*sin2o_m;
    }
  private:
    const double sin2o_m, cos2o_m;
  };
  template <int Dim>
  struct CoriolisY : public Deltas<Dim> {
    CoriolisY(double dphi) : sin2o_m(sin(2*dphi)), cos2o_m(cos(2*dphi)) {}
    inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
    {
      i.extent().lower(1) = 1;
      i.extent().upper(0) = 1;
      i.write(0, true);
      i.write(1, false);
      i.useGuards(0, false);
      i.useGuards(1, true);
    }
    using Deltas<Dim>::dX;
    using Deltas<Dim>::dY;
    template <class F1, class F2>
    inline void operator()(const F1 &vy, const F2 &v, const Loc<Dim>& I) const
    {
      const typename F1::Mesh_t &m = v.mesh();
      double vxy = 0.5*(m.DDY1(I)*(v.fieldEngine().engine(0, 0).read(I)
       + v.fieldEngine().engine(0, 0).read(I+dX))
   + m.DDY0(I)*(v.fieldEngine().engine(0, 0).read(I-dY)
         + v.fieldEngine().engine(0, 0).read(I-dY+dX)));
      vy(I) = -vxy*sin2o_m + v.fieldEngine().engine(0, 1).read(I)*cos2o_m;
    }
  private:
    const double sin2o_m, cos2o_m;
  };
  template <>
  struct ApplyCoriolis<CartesianTag>
  {
    template <class F1, class F2>
    static void applyCoriolis(const F1& v, const F2& scratchv, double dphi)
    {
      (ScalarCode<CoriolisX<Dim> >(dphi))(scratchv.center(0), v);
      (ScalarCode<CoriolisY<Dim> >(dphi))(scratchv.center(1), v);
      v.center(0) = scratchv.center(0);
      v.center(1) = scratchv.center(1);
    }
  };
  template <class F1, class F2>
  void applyCoriolis(const F1& v, const F2& scratchv, double omrot, double dt)
  {
    ApplyCoriolis<typename F1::Mesh_t::MeshTraits_t::CoordinateSystemTag_t>
      ::applyCoriolis(v, scratchv, omrot*dt);
  }
template <class Tag, class T>
struct FnSave
{
  inline T
  operator()(const T &a) const
  {
    val = a;
    return a;
  }
  static T val;
};
template <class Tag, class T>
T FnSave<Tag, T>::val;
template<class Tag, int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnSave<Tag, T1>,
  typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
save(const Array<D1,T1,E1> & l)
{
  typedef UnaryNode<FnSave<Tag, T1>,
    typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Array<D1,T1,E1> >::make(l)));
}
template<class Tag, class M1,class T1,class E1>
inline typename MakeReturn<UnaryNode<FnSave<Tag, T1>,
  typename CreateLeaf<Field<M1,T1,E1> >::Leaf_t> >::Expression_t
save(const Field<M1,T1,E1> & l)
{
  typedef UnaryNode<FnSave<Tag, T1>,
    typename CreateLeaf<Field<M1,T1,E1> >::Leaf_t> Tree_t;
  return MakeReturn<Tree_t>::make(Tree_t(
    CreateLeaf<Field<M1,T1,E1> >::make(l)));
}
template <class Tag, class T>
struct SaveRef
{
  SaveRef() {}
  inline
  operator T() const
  {
    return FnSave<Tag, T>::val;
  }
};
template<class Tag, class T>
inline Expression<Scalar<SaveRef<Tag, T> > >
ref()
{
  return Expression<Scalar<SaveRef<Tag, T> > >(SaveRef<Tag, T>());
}
struct DivV {};
  template <class F1, class F2, class F3, class F4, class F5,
     class F6, class F7, class F8, class F9, class F10,
     class F11, class F12, class F13,
     class F14, class F15, class F16, class F17>
  void force(double dt, const F1 &rh, F2 &T, F3 &v, double omrot, F4 &pg, const F5 &ph,
      const F11& cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
      const F9 &vint, F10 &cent, const F12 &a_pg, const F13 &gradv,
      const F14 &Tii, const F15 &Tij, const F16 &fvis, const F17 &eta, bool vis,
      double c_nr, bool cartvis_f, bool eeq)
  {
    enum { Dim = F1::dimensions };
    if (Dim == 3) {
      (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
           v.center(0), v.center(1), v.center(2));
      (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
           v.center(0), v.center(1), v.center(2));
    } else if (Dim == 2) {
      (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
           v.center(0), v.center(1), v.center(0));
      (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
           v.center(0), v.center(1), v.center(0));
    }
    if ((cartvis_f && !vis) || eeq) {
      Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
      ScalarCode<GradV<Dim> >()(gradv, I, v);
    }
    if (cartvis_f && !vis) {
      Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
      a_pg(I) = where(save<DivV>(dot(gradv, Vector<Dim>(1))(I)) < 0.0,
        (c_nr * rh * pow2(Pooma::spacings(rh).comp(0)) * ref<DivV, double>())(I),
        0.0);
    }
    if (eeq) {
      Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
      pg(I) = (T(I) - (0.5*dt * pg(I)
         / rh(I) / cv.read(I)
         * (1.0 - dlmdlt.read(I)) * dot(gradv(I), Vector<Dim>(1)))) * rh(I) / xmue.read(I);
      pg.clearDirty();
    }
    if (eeq) {
      vint.all() = v.all();
    }
      fvis.all() = 0.0;
    if (cartvis_f && !vis) {
      (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
        rh,
        pg + a_pg * min(gradv.comp(0), 0.0),
        ph, cent.center(0), fvis.center(0));
      if (Dim > 1)
 (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
          rh,
          pg + a_pg * min(gradv.comp(1), 0.0),
          ph, cent.center(1), fvis.center(1));
      if (Dim > 2)
 (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
          rh,
          pg + a_pg * min(gradv.comp(2), 0.0),
          ph, fvis.center(2));
    } else {
      (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
        rh, pg, ph, cent.center(0), fvis.center(0));
      if (Dim > 1)
 (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
          rh, pg, ph, cent.center(1), fvis.center(1));
      if (Dim > 2)
 (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
          rh, pg, ph, fvis.center(2));
    }
    if (omrot != 0.0)
      applyCoriolis(v, cent, omrot, dt);
    if (eeq) {
      for (int i=0; i<Dim; ++i)
 vint.center(i).all() = 0.5*(vint.center(i).all() + v.center(i).all());
      if (cartvis_f && !vis)
 (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint,
         pg + a_pg * dot(gradv, Vector<Dim>(1)), cv, dlmdlt);
      else
 (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint, pg, cv, dlmdlt);
    }
  }
  template <class F1, class F2, class F3, class F4, class F5,
     class F6, class F7, class F8, class F9, class F10, class F11,
     class F12, class F13, class F14, class F15>
  void force(double dt, const F1 &rh, const F2 &T, const F3 &v, double omrot, F4 &pg, const F5 &ph,
      const F11 &cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
      const F9 &vint, const F10 &cent,
      const F12 &Tii, const F13 &Tij, const F14 &fvis, const F15 &eta, bool vis,
      double c_nr, double c_av, bool cartvis_f, bool eeq)
  {
    enum { Dim = F1::dimensions };
    if (Dim == 3) {
      (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
           v.center(0), v.center(1), v.center(2));
      (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
           v.center(0), v.center(1), v.center(2));
    } else if (Dim == 2) {
      (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
           v.center(0), v.center(1), v.center(0));
      (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
           v.center(0), v.center(1), v.center(0));
    }
    if (eeq) {
      (ScalarCode<TGuess<Dim> >(0.5*dt))(pg, pg.physicalDomain(),
      T, rh, v, cv, dlmdlt, xmue);
      pg.clearDirty();
      vint.all() = v.all();
    }
    if (cartvis_f && !vis) {
      (ScalarCode<APressure<Dim> >(APressure<Dim>(c_nr, c_av)))(pg, pg.physicalDomain(), rh, v, cs);
      pg.clearDirty();
    }
      fvis.all() = 0.0;
    (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
      rh, pg, ph, cent.center(0), fvis.center(0));
    if (Dim > 1)
      (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
        rh, pg, ph, cent.center(1), fvis.center(1));
    if (Dim > 2)
      (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
        rh, pg, ph, fvis.center(2));
    if (omrot != 0.0)
      applyCoriolis(v, cent, omrot, dt);
    if (eeq) {
      for (int i=0; i<Dim; ++i)
 vint.center(i).all() = 0.5*(vint.center(i).all() + v.center(i).all());
      (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint, pg, cv, dlmdlt);
    }
  }
};
Loc<Dim> vdom(64, 64, 64);
void usage(int ret)
{
  std::cerr
    << "Usage: tramp3d-v4\n"
    << "  --help|-h|-?        show this command line help\n"
    << "  --num-iter|-n       number of iterations to perform [Inf]\n"
    << "  --end-t|-t          time to stop simulation [Inf]\n"
    << "  --cfl               cfl number [0.6]\n"
    << "  --dt                constant timestep, used with cfl number [off]\n"
    << "  --min-dt            minimum timestep allowed\n"
    << "  --max-dt            maximum timestep allowed\n"
    << "  --blocks nx ny nz   processor setup [automatic]\n"
    << "  --cartvis nr av     artificial viscosity NR AV [off]\n"
    << "  --eos n             choose eos\n"
    << "  --rhomin rho        density floor [off]\n"
    << "  --blocking-expressions  set blocking expressions [off]\n"
    << "  --domain x y z      computational vertex domain [64x64x64]\n\n"
    << "A particularly benchmarky and checky command-line includes\n"
    << "both artificial viscosity and density minimum via f.i.\n"
    << "  ./tramp3d-v4 --cartvis 1.0 0.0 --rhomin 1e-8\n"
    << std::flush;
  Pooma::finalize();
  exit(ret);
}
void handle_cmd_args(int argc, char** argv)
{
  int i = 1;
  while (i < argc) {
    if (strcmp(argv[i], "--help") == 0
 || strcmp(argv[i], "-h") == 0
 || strcmp(argv[i], "-?") == 0) {
      usage(0);
    } else if (argc > i+1
        && (strcmp(argv[i], "--num-iter") == 0
     || strcmp(argv[i], "-n") == 0)) {
      a_nr_f = true;
      a_nr = atoi(argv[i+1]);
      i += 1;
    } else if (argc > i+1
        && (strcmp(argv[i], "--end-t") == 0
     || strcmp(argv[i], "-t") == 0)) {
      a_end_t_f = true;
      a_end_t = atof(argv[i+1]);
      i += 1;
    } else if (argc > i+Dim
      && strcmp(argv[i], "--blocks") == 0) {
      a_blocks_f = true;
      a_blocks[0] = Loc<1>(atoi(argv[i+1]));
      if (Dim > 1)
 a_blocks[1] = Loc<1>(atoi(argv[i+2]));
      if (Dim > 2)
 a_blocks[2] = Loc<1>(atoi(argv[i+3]));
      i += 3;
    } else if (argc > i+Dim
      && strcmp(argv[i], "--domain") == 0) {
      vdom[0] = Loc<1>(atoi(argv[i+1]));
      if (Dim > 1)
 vdom[1] = Loc<1>(atoi(argv[i+2]));
      if (Dim > 2)
 vdom[2] = Loc<1>(atoi(argv[i+3]));
      i += 3;
    } else if (argc > i+1
        && strcmp(argv[i], "--cfl") == 0) {
      a_cfl_f = true;
      a_cfl = atof(argv[i+1]);
      i += 1;
    } else if (argc > i+1
        && strcmp(argv[i], "--dt") == 0) {
      a_constant_timestep_f = true;
      dt = atof(argv[i+1]);
      i += 1;
    } else if (argc > i+1
        && strcmp(argv[i], "--min-dt") == 0) {
      a_min_dt_f = true;
      a_min_dt = atof(argv[i+1]);
      i += 1;
    } else if (argc > i+1
        && strcmp(argv[i], "--max-dt") == 0) {
      a_max_dt_f = true;
      a_max_dt = atof(argv[i+1]);
      i += 1;
    } else if (argc > i+2
        && strcmp(argv[i], "--cartvis") == 0) {
      a_cartvis_f = true;
      cartvis_nr = atof(argv[i+1]);
      cartvis_av = atof(argv[i+2]);
      i += 2;
    } else if (argc > i+1
        && strcmp(argv[i], "--rhomin") == 0) {
      a_rhomin_f = true;
      a_rhomin = atof(argv[i+1]);
      i += 1;
    } else if (strcmp(argv[i], "--blocking-expressions") == 0) {
      Pooma::blockingExpressions(true);
    } else {
      std::cerr << "Unknown option " << argv[i] << ".\n\n";
      usage(1);
    }
    ++i;
  }
  commandline.append(argv[0]);
  for (int i=1; i<argc; ++i) {
    commandline.append(" ");
    commandline.append(argv[i]);
  }
}
static void initSpacings(Array<1, double, Brick> s[Dim], const Interval<Dim>& dom)
{
  for (int i=0; i<Dim; ++i)
    s[i].engine() = Engine<1, double, Brick>(grow(dom[i], 2));
}
static void initSpacings(Vector<Dim>& s, const Interval<Dim>&)
{
}
int main(int argc, char** argv)
{
    Pooma::initialize(argc,argv);
    Pooma::blockingExpressions(false);
  Inform out;
  if (argc == 1)
    usage(1);
  handle_cmd_args(argc, argv);
  origin = Vector<Dim>(-1.0);
  for (int i=0; i<Dim; ++i) {
    vertexDomain[i] = Interval<1>(vdom[i].min());
    spacings(i) = 2.0/(vertexDomain[i].size()-1);
  }
  periodicity = Vector<Dim, int>(1);
  if (a_blocks[0].min() == 0)
    a_blocks = makeRBlocks(vertexDomain, Pooma::contexts());
  Grid<Dim> grid = makeRGrid(vertexDomain, a_blocks);
  for (int i=0; i<Dim; ++i) {
    corr_v[i] = GuardLayers<Dim>(0);
    corr_v[i].lower(i) = 1;
    corr_v[i].upper(i) = 1;
  }
  Traits_t::Layout_t layout;
  Traits_t::createLayout(layout, grid, vertexDomain,
    GuardLayers<Dim>(2),
    GuardLayers<Dim>(2));
  Traits_t::Mesh_t mesh(layout, origin, spacings);
  Traits_t::Layout_t layout1;
  Traits_t::createLayout(layout1, grid, vertexDomain,
    GuardLayers<Dim>(1),
    GuardLayers<Dim>(1));
  Traits_t::Mesh_t mesh1(layout1, origin, spacings);
  Traits_t::Layout_t layout0;
  Traits_t::createLayout(layout0, grid, vertexDomain,
    GuardLayers<Dim>(0),
    GuardLayers<Dim>(0));
  Traits_t::Mesh_t mesh0(layout0, origin, spacings);
  Traits_t::Centering_t cell = canonicalCentering<Traits_t::Dim>(CellType, Continuous);
  Traits_t::Centering_t face = canonicalCentering<Traits_t::Dim>(FaceType, Continuous);
  Traits_t::Centering_t edge = canonicalCentering<Traits_t::Dim>(EdgeType, Continuous);
  Traits_t::Centering_t vertex = canonicalCentering<Traits_t::Dim>(VertexType, Continuous);
  Traits_t::Scalar_t rh(cell, layout, mesh);
  Traits_t::Scalar_t v(face, layout, mesh);
  Traits_t::Scalar_t T;
  Traits_t::Scalar_t pg(cell, layout, mesh);
  Traits_t::Scalar_t ph(cell, layout, mesh);
  Traits_t::Scalar_t cs(cell, layout, mesh);
  rh.all() = std::numeric_limits<double>::signaling_NaN();
  for (int i=0; i<Dim; ++i)
    v.center(i).all() = std::numeric_limits<double>::signaling_NaN();
  pg.all() = std::numeric_limits<double>::signaling_NaN();
  ph.all() = std::numeric_limits<double>::signaling_NaN();
  cs.all() = std::numeric_limits<double>::signaling_NaN();
  double t;
  Traits_t::Scalar_t scratchv(vertex, layout, mesh);
  Traits_t::Scalar_t scratchc(cell, layout, mesh);
  Traits_t::Vector_t scratchc_v(cell, layout, mesh);
  Traits_t::Vector_t scratchc_v2;
  Traits_t::Scalar_t flm(face, layout1, mesh1);
  Traits_t::Scalar_t fle;
  Traits_t::Vector_t flvv(vertex, layout0, mesh0);
  Traits_t::Scalar_t flvc(cell, layout0, mesh0);
  Traits_t::Scalar_t Tij;
  scratchv.all() = std::numeric_limits<double>::signaling_NaN();
  scratchc.all() = std::numeric_limits<double>::signaling_NaN();
  scratchc_v.all() = Vector<Dim>(std::numeric_limits<double>::signaling_NaN());
  for (int i=0; i<Dim; ++i)
    flm.center(i).all() = std::numeric_limits<double>::signaling_NaN();
  flvc.all() = std::numeric_limits<double>::signaling_NaN();
  flvv.all() = Vector<Dim>(std::numeric_limits<double>::signaling_NaN());
  Field<Traits_t::Mesh_t, double, ConstantFunction> cv(cell, layout, mesh);
  Field<Traits_t::Mesh_t, Zero<double>, ConstantFunction> dlmdlt(cell, layout, mesh);
  Field<Traits_t::Mesh_t, double, ConstantFunction> xmue(cell, layout, mesh);
  Field<Traits_t::Mesh_t, double, ConstantFunction> nue(cell, layout, mesh);
  int it;
    it = 0;
  it++;
    t = 0.0;
    T.initialize(cell, layout, mesh);
  bool eeq = true;
  if (eeq) {
    fle.initialize(face, layout0, mesh0);
    for (int i=0; i<Dim; ++i)
      fle.center(i).all() = std::numeric_limits<double>::signaling_NaN();
  }
  bool ietot = true;
    gamma_ = 1.33;
    K = 4.0*3.14159265358979323846/(1.0/(gamma_-1.0)+1.0);
    if (! a_cartvis_f) {
    cartvis_nr = 0.0;
    cartvis_av = 0.0;
    }
  xmue.engine().setConstant(2.3);
  cv.engine().setConstant(1.0/(xmue.engine().constant()*(gamma_-1.0)));
  nue.engine().setConstant(0.0);
  {
    Interval<Dim> I(rh.physicalDomain());
    rh(I) = 0.1;
    v.all() = 0.0;
    T(I) = 99.0/exp(100.0*pow(norm(positions(T)(I)-Vector<Dim>(0.25)), 2.0))+1.0;
    Pooma::addAllPeriodicFaceBC(rh);
    Pooma::addAllPeriodicFaceBC(T);
    Pooma::addAllPeriodicFaceBC(v);
  }
  Traits_t::Scalar_t vint(v);
  vint.makeOwnCopy();
  vint.all() = std::numeric_limits<double>::signaling_NaN();
  Traits_t::Scalar_t cent(face, layout0, mesh0);
  cent.all() = 0.0;
    ph.initialize(rh);
    ph.makeOwnCopy();
    ph.all() = 0.0;
  eos = EOS::IdealAdiabatic;
  double rh0 = sum(rh);
  double T0 = sum(rh*T);
  out << "Using\n"
      << "  using " << a_blocks << " block setup for computation on domain " << vertexDomain << "\n"
      << "  " << (eeq ? "" : "not ") << "solving eeq\n";
  if (a_constant_timestep_f)
    out << "  time increments fixed at " << dt << ", cfl " << a_cfl << "\n";
  else
    out << "  time increments from [" << a_min_dt << ", " << a_max_dt << "], cfl " << a_cfl << "\n";
  out << "  starting at t = " << t << ", i = " << it << "\n"
      << "  cell physical/total domain " << rh.physicalDomain() << ", " << rh.totalDomain() << "\n"
      << "  face  physical/total domain " << v.physicalDomain() << ", " << v.totalDomain() << "\n";
  if (periodicity(0)
      || (Dim > 1 && periodicity(1))
      || (Dim > 2 && periodicity(2))) {
    out << "  periodic boundaries in";
    if (periodicity(0))
      out << " X";
    if (Dim > 1 && periodicity(1))
      out << " Y";
    if (Dim > 2 && periodicity(2))
      out << " Z";
    out << "\n";
  }
  out << std::flush;
  struct timeval end_time, start_time;
  gettimeofday(&start_time, NULL);
  
  // LLVM: disable timing.
  end_time = start_time;
  
  if (a_rhomin_f)
    Pooma::newRelation(Hacks::limit_rh(a_rhomin), rh);
  switch (eos) {
  case EOS::IdealAdiabatic:
    Pooma::newRelation(EOS::pg_ig(), pg, T, rh, xmue);
    Pooma::newRelation(EOS::cs_adiabatic(gamma_), cs, pg, rh);
    break;
  }
  double iteration_time = 0.0;
  for (; it<=a_nr && t<=a_end_t; it++) {
    if (!a_constant_timestep_f) {
      double dt_ = CFL::schritt<Dim>(v, cs, nue,
                       scratchc,
                       0.0, false);
      if (dt_ <= 0.0 || std::isnan(dt_) || std::isinf(dt_)) {
 out << "dt is " << dt_ << std::endl;
 Pooma::pAbort("Blowup.");
      }
      dt = std::min(a_max_dt, std::max(a_min_dt, a_cfl*dt_));
    }
    t += dt;

    // LLVM: disable timing.
    //gettimeofday(&end_time, NULL);
    out << "i = " << it << "\t t = " << t << "\t dt = " << dt;
 //<< " (" << end_time.tv_sec + end_time.tv_usec/1000000.0 - start_time.tv_sec - start_time.tv_usec/1000000.0 << "s/it)" << std::endl;
    iteration_time += end_time.tv_sec + end_time.tv_usec/1000000.0 - start_time.tv_sec - start_time.tv_usec/1000000.0;
    start_time = end_time;
    Adv5::advect(dt, rh, v, 0.0, T, flm, fle, flvv, flvc, cv, scratchc, eeq, ietot);
    Forgas::force(dt,
    rh, T, v, 0.0, pg, ph,
    cs, cv, dlmdlt, xmue, vint, cent,
    scratchc_v , Tij, flm , nue*rh, false,
    cartvis_nr, cartvis_av, a_cartvis_f,
    eeq);
      Hacks::checkRegularity(rh);
      Hacks::checkRegularity(v.center(0));
      if (Dim > 1)
 Hacks::checkRegularity(v.center(1));
      if (Dim > 2)
 Hacks::checkRegularity(v.center(2));
  }
  // LLVM: disable timing.
  //out << "Time spent in iteration: " << iteration_time << std::endl;
  out << "Correctness:"
      << "\n\tsum(rh) difference = " << sum(rh)-rh0
      << "\n\tsum(vx) = " << sum(v.center(0))
      << "\n\tsum(vy) = " << sum(v.center(1))
      << "\n\tsum(vz) = " << sum(v.center(2))
      << "\n\tsum(rh*T) difference = " << sum(rh*T)-T0 << std::endl;
  Pooma::finalize();
  return 0;
}
