OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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
A pointer to an array expression.
Definition: Expressions.h:179
virtual std::vector< T > evaluate()
Evaluate.
Definition: ADeferred.h:166
Object attribute with a constant array value.
Definition: AValue.h:35
virtual const std::string & what() const
Return the message string for the exception.
The abstract base class for all exceptions in CLASSIC.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.
The base class for all OPAL exceptions.
Definition: OpalException.h:28
An array of pointers to scalar expressions.
Definition: Expressions.h:127
ArrayOfPtrs< T > itsOverrides
Overrides for single components.
Definition: ADeferred.h:91
virtual bool isExpression() const
Get expression flag.
Definition: ADeferred.h:213
virtual void print(std::ostream &) const
Print the attribute value.
Definition: ADeferred.h:219
void operator=(const ADeferred< T > &)
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special exception
Definition: LICENSE:157
PtrToArray< T > itsLaw
The generating law for the array expression.
Definition: ADeferred.h:85
void setComponent(int i, const PtrToScalar< T > expr)
Set a component of the value.
Definition: ADeferred.h:243
Object attribute with a ``deferred&#39;&#39; array value.
Definition: ADeferred.h:40
A pointer to a scalar expression.
Definition: Expressions.h:108
Logical error exception.
Definition: LogicalError.h:33
ADeferred()
Default constructor.
Definition: ADeferred.h:107
virtual ADeferred< T > * clone() const
Make clone.
Definition: ADeferred.h:160