// CS 509 - Advanced Programming II
// Spring 2004
//
// Definitions for expression templates using traits.
#ifndef _ett_h_defined_
#define _ett_h_defined_
// The type of the value returned by evaluate().
typedef double result_type;
class literal {
public:
// Create an expression that always evaluates to the given value.
literal(result_type v) : value(v) { }
// Evaluate this expression.
result_type evaluate() const {
return value;
}
private:
result_type value;
};
class variable {
public:
// Create an expression that evaluates to the value stored in the given
// reference.
variable(result_type & v) : var(v) { }
// Evaluate this expression.
result_type evaluate() const {
return var;
}
private:
result_type var;
};
// The default type-representation mapping.
template <class ValueType>
struct representation {
typedef ValueType type;
};
// Type-representation mapping specializations for pod types.
template <>
struct representation<int> {
typedef literal type;
};
template <>
struct representation<float> {
typedef literal type;
};
template <>
struct representation<double> {
typedef literal type;
};
template < class Operand, class UnaryOp >
class unary_expression {
public:
// Create an expression that evaluates to the result of applying the given
// unary operation to the result of evaluating the given expression.
unary_expression(
Operand e, UnaryOp op = UnaryOp())
: expr(e), oprtr(op) { }
// Return the result of evaluating this expression.
result_type evaluate() const {
return oprtr(expr.evaluate());
}
private:
typename representation<Operand>::type expr;
UnaryOp oprtr;
};
template < class LeftOperand, class RightOperand, class BinaryOp >
class binary_expression {
public:
// Create an expression that evaluates to the result of applying the given
// binary operation to the result of evaluating the given expressions.
binary_expression(
LeftOperand l, RightOperand r, BinaryOp op = BinaryOp())
: left(l), right(r), oprtr(op) { }
// Return the result of evaluating this expression.
result_type evaluate() const {
return oprtr(left.evaluate(), right.evaluate());
}
private:
typename representation<LeftOperand>::type left;
typename representation<RightOperand>::type right;
BinaryOp oprtr;
};
#define def_binexp(_op1, _op2) \
template <class LExpr, class RExpr> \
static binary_expression <LExpr, RExpr, std::_op2<result_type> > \
operator _op1 (LExpr l, RExpr r) { \
return binary_expression<LExpr, RExpr, std::_op2<result_type> >(l, r); }
#endif
// $Log: ett.h,v $
// Revision 1.1 2004/05/06 19:43:14 rclayton
// Initial revision
//
syntax highlighted by Code2HTML, v. 0.9