[PATCH] Fix Tiny/Zero.h, add Tiny/One.h, new testcase

Richard Guenther rguenth at tat.physik.uni-tuebingen.de
Wed Jul 24 09:07:44 UTC 2002


The attached patch introduces Tiny/One.h and a new testcase to
check ConstantFunction engine and Tiny/Zero.h, Tiny/One.h. Tiny/Zero.h
is also fixed (as in the previously sent patch + additional fixes).

Richard.

--
Richard Guenther <richard.guenther at uni-tuebingen.de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/
The GLAME Project: http://www.glame.de/
-------------- next part --------------
2002Jul24  Richard Guenther <richard.guenther at uni-tuebingen.de>

        * Tiny/Zero.h: fixed class protection
        const'ified operator T()
        deleted ambigous return type specializations
        * Tiny/One.h: new
        * Pooma/Tiny.h: include Zero.h and One.h
        * Engine/tests/makefile: new constant_test testcase
        * Engine/tests/constant_test.cpp: new

-------------- next part --------------
# This is a BitKeeper generated patch for the following project:
# Project Name: pooma/cheetah repository tracking CVS/tarball
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.40    -> 1.41   
#	 r2/src/Pooma/Tiny.h	1.2     -> 1.3    
#	r2/src/Engine/tests/makefile	1.1     -> 1.2    
#	  r2/src/Tiny/Zero.h	1.1     -> 1.2    
#	               (new)	        -> 1.1     r2/src/Tiny/One.h
#	               (new)	        -> 1.1     r2/src/Engine/tests/constant_test.cpp
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/07/24	rguenth at bellatrix.tat.physik.uni-tuebingen.de	1.41
# Fixed Zero<>, added One<> and MinusOne<> tiny classes, added testcase
# --------------------------------------------
#
diff --minimal -Nru a/r2/src/Engine/tests/constant_test.cpp b/r2/src/Engine/tests/constant_test.cpp
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/r2/src/Engine/tests/constant_test.cpp	Wed Jul 24 10:55:50 2002
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+// ACL:license
+// ----------------------------------------------------------------------
+// This software and ancillary information (herein called "SOFTWARE")
+// called POOMA (Parallel Object-Oriented Methods and Applications) is
+// made available under the terms described here.  The SOFTWARE has been
+// approved for release with associated LA-CC Number LA-CC-98-65.
+// 
+// Unless otherwise indicated, this SOFTWARE has been authored by an
+// employee or employees of the University of California, operator of the
+// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
+// the U.S. Department of Energy.  The U.S. Government has rights to use,
+// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
+// prepare derivative works and publicly display this SOFTWARE without 
+// charge, provided that this Notice and any statement of authorship are 
+// reproduced on all copies.  Neither the Government nor the University 
+// makes any warranty, express or implied, or assumes any liability or 
+// responsibility for the use of this SOFTWARE.
+// 
+// If SOFTWARE is modified to produce derivative works, such modified
+// SOFTWARE should be clearly marked, so as not to confuse it with the
+// version available from LANL.
+// 
+// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
+// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
+// ----------------------------------------------------------------------
+// ACL:license
+
+// Tests that check the ConstantFunction engine and the One<T> and
+// Zero<T> tiny classes for successful optimization.
+
+#include "Pooma/Pooma.h"
+#include "Pooma/Arrays.h"
+#include "Pooma/Tiny.h"
+
+
+// "number" classes we can use to detect successful optimization.
+// Optimization failures will cause compilation errors.
+class Number {
+public:
+  Number() : neg_m(false) {}
+  explicit Number(bool n) : neg_m(n) {}
+  bool operator==(const Number& n) const { return neg_m == n.neg_m; }
+  Number operator-() const { return Number(false); }
+private:
+  bool neg_m;
+};
+
+
+// Check successful optimization of ConstantFunction One<T>s and Zero<T>s
+void check_array_optimize(Pooma::Tester& tester)
+{
+  Interval<1> I(0, 15);
+  Array<1, Zero<Number>, ConstantFunction> zero(I);
+  Array<1, One<Number>, ConstantFunction> one(I);
+  Array<1, Number, Brick> n(I);
+
+  // simple checks involving n
+  tester.check("n + Zero == n", all(n+zero == n));
+  tester.check("Zero + n == n", all(zero+n == n));
+  tester.check("n - Zero == n", all(n-zero == n));
+  tester.check("n * One == n", all(n*one == n));
+  tester.check("One * n == n", all(one*n == n));
+  tester.check("n / One == n", all(n/one == n));
+  tester.check("Zero / n == Zero", all(zero/n == zero));
+
+  // some more complex checks [-n needed]
+  tester.check("n * (Zero - One) / -One == n", all(n*(zero-one)/(-one) == n));
+}
+
+
+// Check One<T> and Zero<T> is working correctly wrt arithmentics
+void check_arithmetic(Pooma::Tester& tester)
+{
+  Interval<1> I(0, 15);
+
+  Array<1, Zero<int>, ConstantFunction> zero(I);
+  Array<1, One<int>, ConstantFunction> one(I);
+
+  tester.check("one*zero == 0", all(one*zero == 0));
+  tester.check("zero*one == 0", all(zero*one == 0));
+  tester.check("one*one == 1", all(one*one == 1));
+
+  tester.check("one/one == 1", all(one/one == 1));
+  tester.check("zero/one == 0", all(zero/one == 0));
+
+  tester.check("one+zero == 1", all(one+zero == 1));
+  tester.check("zero+one == 1", all(zero+one == 1));
+
+  tester.check("one-zero == 1", all(one-zero == 1));
+  tester.check("zero-one == -1", all(zero-one == -1));
+  tester.check("zero-one == -one", all(zero-one == -one));
+
+  tester.check("one+one == 2", all(one+one == 2));
+  tester.check("2+one == 3", all(2+one == 3));
+}
+
+
+int main(int argc, char *argv[])
+{
+  Pooma::initialize(argc, argv);
+  Pooma::Tester tester(argc, argv);
+
+  check_array_optimize(tester);
+  check_arithmetic(tester);
+
+  int ret = tester.results("constant_test");
+  Pooma::finalize();
+  return ret;
+}
+
+
diff --minimal -Nru a/r2/src/Engine/tests/makefile b/r2/src/Engine/tests/makefile
--- a/r2/src/Engine/tests/makefile	Wed Jul 24 10:55:50 2002
+++ b/r2/src/Engine/tests/makefile	Wed Jul 24 10:55:50 2002
@@ -36,7 +36,8 @@
 default:: tests
 
 tests:: dynamic_tests brick_tests brickview_tests compbrick_tests \
-          ump_tests gmp_tests indirect_tests brickbase_tests remote_tests
+          ump_tests gmp_tests indirect_tests brickbase_tests remote_tests \
+	  constant_test
 
 brick_tests:: brick_test1 brick_test2 brick_test3 brick_test4
 
@@ -63,7 +64,8 @@
 
 run_tests: tests \
 	   run_brickbase run_dynamic run_compbrick run_indirect \
-	   run_brick run_brickview run_ump run_gmp run_remote
+	   run_brick run_brickview run_ump run_gmp run_remote \
+	   run_constant
 
 run_compbrick:
 	$(MPIRUN) $(ODIR)/compbrick_test1 $(TSTOPTS) 1>compbrick_test1.out 2>&1
@@ -125,6 +127,10 @@
 	$(MPIRUN) $(ODIR)/makeOwnCopy $(TSTOPTS) \
 					1>makeOwnCopy.out 2>&1
 
+run_constant:
+	$(MPIRUN) $(ODIR)/constant_test $(TSTOPTS) \
+					1>constant_test.out 2>&1
+
 .PHONY: dynamic_test1
 .PHONY: dynamic_test2
 
@@ -211,6 +217,9 @@
 remoteDynamicTest1: $(ODIR)/remoteDynamicTest1
 makeOwnCopy: $(ODIR)/makeOwnCopy
 
+.PHONY: constant_test
+
+constant_test: $(ODIR)/constant_test
 
 
 $(ODIR)/dynamic_test1: $(ODIR)/dynamic_test1.o
@@ -310,6 +319,9 @@
 	$(LinkToSuite)
 
 $(ODIR)/makeOwnCopy: $(ODIR)/makeOwnCopy.o
+	$(LinkToSuite)
+
+$(ODIR)/constant_test: $(ODIR)/constant_test.o
 	$(LinkToSuite)
 
 include $(SHARED_ROOT)/tail.mk
diff --minimal -Nru a/r2/src/Pooma/Tiny.h b/r2/src/Pooma/Tiny.h
--- a/r2/src/Pooma/Tiny.h	Wed Jul 24 10:55:50 2002
+++ b/r2/src/Pooma/Tiny.h	Wed Jul 24 10:55:50 2002
@@ -46,6 +46,9 @@
 
 #include "Tiny/Reductions.h"
 
+#include "Tiny/Zero.h"
+#include "Tiny/One.h"
+
 #endif // POOMA_POOMA_TINY_H
 
 // ACL:rcsinfo
diff --minimal -Nru a/r2/src/Tiny/One.h b/r2/src/Tiny/One.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/r2/src/Tiny/One.h	Wed Jul 24 10:55:50 2002
@@ -0,0 +1,425 @@
+// -*- C++ -*-
+// ACL:license
+// ----------------------------------------------------------------------
+// This software and ancillary information (herein called "SOFTWARE")
+// called POOMA (Parallel Object-Oriented Methods and Applications) is
+// made available under the terms described here.  The SOFTWARE has been
+// approved for release with associated LA-CC Number LA-CC-98-65.
+// 
+// Unless otherwise indicated, this SOFTWARE has been authored by an
+// employee or employees of the University of California, operator of the
+// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
+// the U.S. Department of Energy.  The U.S. Government has rights to use,
+// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
+// prepare derivative works and publicly display this SOFTWARE without 
+// charge, provided that this Notice and any statement of authorship are 
+// reproduced on all copies.  Neither the Government nor the University 
+// makes any warranty, express or implied, or assumes any liability or 
+// responsibility for the use of this SOFTWARE.
+// 
+// If SOFTWARE is modified to produce derivative works, such modified
+// SOFTWARE should be clearly marked, so as not to confuse it with the
+// version available from LANL.
+// 
+// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
+// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
+// ----------------------------------------------------------------------
+// ACL:license
+
+#ifndef POOMA_TINY_ONE_H
+#define POOMA_TINY_ONE_H
+
+//-----------------------------------------------------------------------------
+// Class: One
+//-----------------------------------------------------------------------------
+
+/** @file
+ * @ingroup Tiny
+ * @brief
+ * A numeric class for a number that is always one.
+ */
+
+//-----------------------------------------------------------------------------
+// Typedefs:
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Includes:
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Forward Declarations:
+//-----------------------------------------------------------------------------
+
+template<class T> struct Zero;
+template<class T, class Op> struct UnaryReturn;
+template<class T1, class T2, class Op> struct BinaryReturn;
+
+
+/// The point of this class is to be a number of type T which is known at
+/// compile time to be one.
+///
+/// This is reflected in the operations like
+/// multiplication and division that use it.  If you return a One object,
+/// the compiler should be able to make better optimizations than if you
+/// just return one.
+/// One is templated on type T, to represent a one object of type T.
+/// Type T is required to be constructable from an integer one.
+
+template<class T>
+struct One
+{
+  /// If you need to convert to an object of type T,
+  /// just build one from one.  This will be used in 
+  /// the cases where the operators below don't match.
+
+  operator T() const { return T(1); }
+
+  bool operator==(const One<T>&) const { return true; }
+
+  /// Give it empty ctors and assignment operators
+  /// to try and keep purify happy.
+
+  One() {}
+  One(const One<T>&) {}
+  One<T>& operator=(const One<T>&) { return *this; }
+};
+
+/// The point of this class is to be a number of type T which is known at
+/// compile time to be minus one.
+///
+/// This is reflected in the operations like
+/// multiplication and division that use it.  If you return a MinusOne object,
+/// the compiler should be able to make better optimizations than if you
+/// just return minus one.
+/// MinusOne is templated on type T, to represent a one object of type T.
+/// Type T is required to be constructable from an integer minus one.
+
+template<class T>
+struct MinusOne
+{
+  /// If you need to convert to an object of type T,
+  /// just build one from minus one.  This will be used in 
+  /// the cases where the operators below don't match.
+
+  operator T() const { return T(-1); }
+
+  bool operator==(const MinusOne<T>&) const { return true; }
+
+  /// Give it empty ctors and assignment operators
+  /// to try and keep purify happy.
+
+  MinusOne() {}
+  MinusOne(const One<T>&) {}
+  MinusOne<T>& operator=(const MinusOne<T>&) { return *this; }
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// Operators using One and/or MinusOne.
+//
+//-----------------------------------------------------------------------------
+
+//
+// Unary minus operators.
+//
+
+template<class T>
+  inline MinusOne<T>  operator-(One<T>) { return MinusOne<T>(); }
+
+template<class T>
+  inline One<T>  operator-(MinusOne<T>) { return One<T>(); }
+
+
+//
+// Binary multiply/divide operations involving One<T>/MinusOne<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>(); }
+
+//
+// Subtraction/addition of a One<T>/MinusOne<T> from a One<T>/MinusOne<T>
+// which yields Zero<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>(); }
+
+
+
+//
+// Trait classes so that expression templates will deal correctly
+// with Ones/MinusOnes in specific operations.
+//
+
+// Unary minus
+
+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;
+};
+
+// Multiply
+
+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;
+};
+
+// Divide
+
+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;
+};
+
+// Subtract
+
+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;
+};
+
+// Add
+
+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;
+};
+
+// Equality
+
+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;
+};
+
+
+//
+// Trait class definitios for the cases where the One<T>/MinusOne<T> gets
+// converted to a T. Traits with just one specialized operand are
+// ambigous to specialized operator versions.
+//
+
+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;
+};
+
+
+//
+// Let Zero, One and MinusOne play together for other operators.
+//
+
+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;
+};
+
+
+
+#endif
+
+// ACL:rcsinfo
+// ----------------------------------------------------------------------
+// $RCSfile: One.h,v $   $Author: swhaney $
+// $Revision: 1.6 $   $Date: 2000/03/07 13:18:17 $
+// ----------------------------------------------------------------------
+// ACL:rcsinfo
diff --minimal -Nru a/r2/src/Tiny/Zero.h b/r2/src/Tiny/Zero.h
--- a/r2/src/Tiny/Zero.h	Wed Jul 24 10:55:50 2002
+++ b/r2/src/Tiny/Zero.h	Wed Jul 24 10:55:50 2002
@@ -30,14 +30,14 @@
 #define POOMA_TINY_ZERO_H
 
 //-----------------------------------------------------------------------------
-
 // Class: Zero
 //-----------------------------------------------------------------------------
 
-//-----------------------------------------------------------------------------
-// Overview:
-// A numeric class for a number that is always zero.
-//-----------------------------------------------------------------------------
+/** @file
+ * @ingroup Tiny
+ * @brief
+ * A numeric class for a number that is always zero.
+ */
 
 //-----------------------------------------------------------------------------
 // Typedefs:
@@ -53,7 +53,7 @@
 
 //-----------------------------------------------------------------------------
 //
-// Full Description:
+/**
 //
 // The point of this class is to be a number of type T which is known at
 // compile time to be zero.  This is reflected in the operations like
@@ -63,21 +63,22 @@
 //
 // Zero is templated on type T, to represent a zero object of type T.
 // Type T is required to be constructable from an integer zero.
-//
+*/
 //-----------------------------------------------------------------------------
 
 template<class T>
-class Zero
+struct Zero
 {
-  // If you need to convert to an object of type T,
-  // just build one from zero.  This will be used in 
-  // the cases where the operators below don't match.
+  /// If you need to convert to an object of type T,
+  /// just build one from zero.  This will be used in 
+  /// the cases where the operators below don't match.
 
-  operator T() { return T(0); }
+  operator T() const { return T(0); }
 
+  bool operator==(const Zero<T>&) const { return true; }
 
-  // Give it empty ctors and assignment operators
-  // to try and keep purify happy.
+  /// Give it empty ctors and assignment operators
+  /// to try and keep purify happy.
 
   Zero() {}
   Zero(const Zero<T>&) {}
@@ -236,31 +237,20 @@
 
 //
 // Trait class definitios for the cases where the Zero<T> gets
-// converted to a T.
+// converted to a T. Traits with just one Zero specialization
+// are ambigous if operator is not specified.
 //
 
-template<class T, class Op>
-struct UnaryReturn< Zero<T> , Op >
-{
-  typedef typename UnaryReturn<T,Op>::Type_t Type_t;
-};
-
-template<class T1, class T2, class Op>
-struct BinaryReturn< Zero<T1> , T2, Op >
-{
-  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
-};
-
 template<class T1, class T2, class Op>
-struct BinaryReturn< T1 , Zero<T2>, Op >
+struct BinaryReturn< Zero<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> , Zero<T2>, Op >
+template<class T>
+struct BinaryReturn< Zero<T>, Zero<T>, OpEQ >
 {
-  typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+  typedef bool Type_t;
 };
 
 


More information about the pooma-dev mailing list