OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
SBinary.h
Go to the documentation of this file.
1 #ifndef OPAL_SBinary_HH
2 #define OPAL_SBinary_HH
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: SBinary.h,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.1.1.1 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: SBinary<T,U>
13 //
14 // ------------------------------------------------------------------------
15 //
16 // $Date: 2000/03/27 09:33:42 $
17 // $Author: Andreas Adelmann $
18 //
19 // ------------------------------------------------------------------------
20 
22 #include "Expressions/SConstant.h"
23 #include "Expressions/TFunction2.h"
24 #include "Utilities/DomainError.h"
26 #include <cerrno>
27 #include <iosfwd>
28 
29 
30 namespace Expressions {
31 
32  // Template class SBinary
33  // ----------------------------------------------------------------------
35  // The expression first evaluates the two scalar operands, and then
36  // it applies the given function to the operands and returns the result.
37 
38  template <class T, class U>
39  class SBinary: public Scalar<T> {
40 
41  public:
42 
44  // Use scalar function with two operands and two scalars.
45  SBinary(const TFunction2<T, U> &function,
46  PtrToScalar<U> left, PtrToScalar<U> right);
47 
48  SBinary(const SBinary<T, U> &);
49  virtual ~SBinary();
50 
52  virtual Scalar<T> *clone() const;
53 
55  virtual T evaluate() const;
56 
58  // If both operands are constants and the function is not a random
59  // generator, evaluate the expression and store the result as a
60  // constant.
61  static Scalar<T> *make(const TFunction2<T, U> &,
62  PtrToScalar<U> left, PtrToScalar<U> right);
63 
65  virtual void print(std::ostream &str, int precedence = 99) const;
66 
67  private:
68 
69  // Not implemented.
70  SBinary();
71  void operator=(const SBinary &);
72 
73  // The operation object.
75 
76  // The two operands.
79  };
80 
81 
82  // Implementation
83  // ------------------------------------------------------------------------
84 
85  template <class T, class U> inline
87  Scalar<T>(rhs),
88  fun(rhs.fun), lft(rhs.lft->clone()), rgt(rhs.rgt->clone())
89  {}
90 
91 
92  template <class T, class U> inline
94  PtrToScalar<U> left, PtrToScalar<U> right):
95  fun(function), lft(left), rgt(right)
96  {}
97 
98 
99  template <class T, class U> inline
101  {}
102 
103 
104  template <class T, class U> inline
106  return new SBinary<T, U>(*this);
107  }
108 
109 
110  template <class T, class U> inline
112  errno = 0;
113  U op1 = lft->evaluate();
114  U op2 = rgt->evaluate();
115  T result = (*fun.function)(op1, op2);
116 
117  // Test for run-time evaluation errors.
118  switch(errno) {
119 
120  case EDOM:
121  throw DomainError("SBinary::evaluate()");
122 
123  case ERANGE:
124  // Ignore underflow.
125  if(result == T(0)) return result;
126  throw OverflowError("SBinary::evaluate()");
127 
128  default:
129  return result;
130  }
131  }
132 
133 
134  template <class T, class U> inline
136  (const TFunction2<T, U> &function,
137  PtrToScalar<U> left, PtrToScalar<U> right) {
138  // We must pick up the constant flag before the ownerships of "left" and
139  // "right" are transferred to "result".
140  bool isConst = left->isConstant() && right->isConstant();
141  PtrToScalar<T> result = new SBinary<T, U>(function, left, right);
142 
143  if(function.precedence != -2) {
144  if(isConst) {
145  // Replace constant expression by its value.
146  result = new SConstant<T>(result->evaluate());
147  }
148  }
149 
150  // Other expression.
151  return result.release();
152  }
153 
154 
155  template <class T, class U> inline
156  void SBinary<T, U>::print(std::ostream &os, int precedence) const {
157  if(fun.precedence >= 0) {
158  // Binary operation.
159  if(fun.precedence <= precedence) os << "(";
160  lft->print(os, fun.precedence - 1);
161  os << fun.name;
162  rgt->print(os, fun.precedence);
163  if(fun.precedence <= precedence) os << ")";
164  } else {
165  // Function.
166  os << fun.name << '(';
167  lft->print(os, 0);
168  os << ',';
169  rgt->print(os, 0);
170  os << ')';
171  }
172 
173  return;
174  }
175 
176 }
177 
178 #endif // OPAL_SBinary_HH
A scalar expression.
Definition: Expressions.h:79
virtual Scalar< T > * clone() const
Make clone.
Definition: SBinary.h:105
A scalar constant expression.
Definition: SConstant.h:35
Definition: rbendmap.h:8
const TFunction2< T, U > & fun
Definition: SBinary.h:74
virtual ~SBinary()
Definition: SBinary.h:100
PtrToScalar< U > rgt
Definition: SBinary.h:78
A scalar expression with two scalar operands.
Definition: SBinary.h:39
A function of two U&#39;s returning a T.
Definition: TFunction2.h:31
Scalar< T > * release()
Release ownership.
void operator=(const SBinary &)
virtual T evaluate() const
Evaluate.
Definition: SBinary.h:111
Overflow exception.
Definition: OverflowError.h:32
Domain error exception.
Definition: DomainError.h:32
PtrToScalar< U > lft
Definition: SBinary.h:77
static Scalar< T > * make(const TFunction2< T, U > &, PtrToScalar< U > left, PtrToScalar< U > right)
Make a new expression.
Definition: SBinary.h:136
virtual void print(std::ostream &str, int precedence=99) const
Print expression.
Definition: SBinary.h:156