OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
ADeferred.h
Go to the documentation of this file.
1 #ifndef OPAL_ADeferred_HH
2 #define OPAL_ADeferred_HH
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: ADeferred.h,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.3.4.1 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: ADeferred<T>
13 //
14 // ------------------------------------------------------------------------
15 //
16 // $Date: 2004/11/18 22:52:40 $
17 // $Author: jsberg $
18 //
19 // ------------------------------------------------------------------------
20 
23 #include "Expressions/AList.h"
24 #include "Expressions/AValue.h"
25 #include "Utilities/LogicalError.h"
27 #include <iosfwd>
28 #include <vector>
29 #include <exception>
30 
31 namespace Expressions {
32 
33  // Template class ADeferred
34  // ----------------------------------------------------------------------
36  // A deferred expression is always re-evaluated when its value is
37  // required. This is notably needed to implement random generators.
38 
39  template <class T>
40  class ADeferred: public AValue<T> {
41 
42  public:
43 
45  // Construct empty array.
46  ADeferred();
47 
49  // From array expression.
50  explicit ADeferred(PtrToArray<T> expr);
51 
53  // From array constant.
54  explicit ADeferred(const std::vector<T> &val);
55 
57  // From array of scalar expressions.
58  explicit ADeferred(ArrayOfPtrs<T> expr);
59 
60  ADeferred(const ADeferred<T> &);
61  virtual ~ADeferred();
62 
64  virtual ADeferred<T> *clone() const;
65 
67  // The expression is always re-evaluated.
68  virtual std::vector<T> evaluate();
69 
71  virtual bool isExpression() const;
72 
74  virtual void print(std::ostream &) const;
75 
77  void setComponent(int i, const PtrToScalar<T> expr);
78 
79  protected:
80 
82  // This expression is used first to evaluate all components of
83  // the expression. Individual values may be overwritten using
84  // [b]itsOverrides[b].
86 
88  // After applying [b]itsLaw[/b] to evaluate all components, any
89  // scalar expression defined in this array is used to overwrite
90  // the corresponding component.
92 
93  private:
94 
95  // Not implemented.
96  void operator=(const ADeferred<T> &);
97 
98  // Guard against recursive definition.
99  mutable bool in_evaluation;
100  };
101 
102 
103  // Implementation
104  // ----------------------------------------------------------------------
105 
106  template <class T>
108  AValue<T>(),
109  itsLaw(),
110  itsOverrides(),
111  in_evaluation(false)
112  {}
113 
114 
115  template <class T>
117  AValue<T>(),
118  itsLaw(rhs.itsLaw->clone()),
119  itsOverrides(rhs.itsOverrides.size()),
120  in_evaluation(false) {
121  for(typename ArrayOfPtrs<T>::size_type i = 0; i < rhs.itsOverrides.size(); ++i) {
122  itsOverrides[i] = rhs.itsOverrides[i]->clone();
123  }
124  }
125 
126 
127  template <class T>
128  ADeferred<T>::ADeferred(const std::vector<T> &val):
129  AValue<T>(val),
130  itsLaw(0),
131  itsOverrides(0),
132  in_evaluation(false)
133  {}
134 
135 
136  template <class T>
138  AValue<T>(),
139  itsLaw(expr),
140  itsOverrides(),
141  in_evaluation(false)
142  {}
143 
144 
145  template <class T>
147  AValue<T>(),
148  itsLaw(),
149  itsOverrides(expr),
150  in_evaluation(false)
151  {}
152 
153 
154  template <class T>
156  {}
157 
158 
159  template <class T>
161  return new ADeferred<T>(*this);
162  }
163 
164 
165  template <class T>
166  std::vector<T> ADeferred<T>::evaluate() {
167  if(in_evaluation) {
168  throw LogicalError("ADeferred::evaluate()",
169  "Recursive expression definitions found.");
170  } else {
171  in_evaluation = true;
172 
173  try {
174  if(itsLaw.isValid()) this->value = itsLaw->evaluate();
175  in_evaluation = false;
176  if(this->value.size() < itsOverrides.size()) {
177  this->value.resize(itsOverrides.size());
178  }
179 
180  for(typename ArrayOfPtrs<T>::size_type i = 0; i < itsOverrides.size(); ++i) {
181  if(itsOverrides[i].isValid()) {
182  this->value[i] = itsOverrides[i]->evaluate();
183  }
184  }
185  } catch(OpalException &ex) {
186  in_evaluation = false;
187  throw LogicalError(ex.where(),
188  "Evaluating expression \"" +
189  this->getImage() + "\": " + ex.what());
190  } catch(ClassicException &ex) {
191  in_evaluation = false;
192  throw LogicalError(ex.where(),
193  "Evaluating expression \"" +
194  this->getImage() + "\": " + ex.what());
195  } catch(std::exception &ex) {
196  in_evaluation = false;
197  throw LogicalError("ADeferred::evaluate()",
198  "Standard C++ exception while evaluating \"" +
199  this->getImage() + "\": " + ex.what());
200  } catch(...) {
201  in_evaluation = false;
202  throw LogicalError("ADeferred::evaluate()",
203  "Unknown exception while evaluating \"" +
204  this->getImage() + "\": ");
205  }
206  }
207 
208  return this->value;
209  }
210 
211 
212  template <class T>
214  return itsLaw.isValid() || (! itsOverrides.empty());
215  }
216 
217 
218  template <class T>
219  void ADeferred<T>::print(std::ostream &os) const {
220  // Print the generating law, if any.
221  if(itsLaw.isValid()) itsLaw->print(os, 0);
222 
223  // Print the overrides.
224  if(! itsOverrides.empty()) {
225  os << "; overrides: {";
226  typename ArrayOfPtrs<T>::const_iterator i = itsOverrides.begin();
227 
228  while(i != itsOverrides.end()) {
229  if(i->isValid())(*i)->print(os);
230  if(++i == itsOverrides.end()) break;
231  os << ',';
232  }
233 
234  os << '}';
235  }
236 
237  return;
238  }
239 
240 
241  template <class T>
243  (int index, const PtrToScalar<T> expr) {
244  while(int(itsOverrides.size()) < index) {
245  itsOverrides.push_back(PtrToScalar<T>());
246  }
247 
248  itsOverrides[index-1] = expr;
249  }
250 
251 }
252 
253 #endif // OPAL_ADeferred_HH
Representation objects and parsers for attribute expressions.
Definition: Expressions.h:64
A pointer to a scalar expression.
Definition: Expressions.h:109
An array of pointers to scalar expressions.
Definition: Expressions.h:127
A pointer to an array expression.
Definition: Expressions.h:180
The abstract base class for all exceptions in CLASSIC.
Logical error exception.
Definition: LogicalError.h:33
Object attribute with a `‘deferred’' array value.
Definition: ADeferred.h:40
void operator=(const ADeferred< T > &)
ArrayOfPtrs< T > itsOverrides
Overrides for single components.
Definition: ADeferred.h:91
virtual void print(std::ostream &) const
Print the attribute value.
Definition: ADeferred.h:219
virtual std::vector< T > evaluate()
Evaluate.
Definition: ADeferred.h:166
virtual bool isExpression() const
Get expression flag.
Definition: ADeferred.h:213
ADeferred()
Default constructor.
Definition: ADeferred.h:107
PtrToArray< T > itsLaw
The generating law for the array expression.
Definition: ADeferred.h:85
virtual ADeferred< T > * clone() const
Make clone.
Definition: ADeferred.h:160
void setComponent(int i, const PtrToScalar< T > expr)
Set a component of the value.
Definition: ADeferred.h:243
Object attribute with a constant array value.
Definition: AValue.h:35
The base class for all OPAL exceptions.
Definition: OpalException.h:28
virtual const std::string & what() const
Return the message string for the exception.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.