// CS 509 - Advanced Programming II
// Spring 2004
//
// Expression template definitions.

#ifndef _et_h_defined_
#define _et_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;
  };


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:

    Operand 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:

    LeftOperand left;
    RightOperand right;
    BinaryOp oprtr;
  };


#endif

// $Log: et.h,v $
// Revision 1.1  2004/05/06 19:43:14  rclayton
// Initial revision
//


syntax highlighted by Code2HTML, v. 0.9