[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