OPAL (Object Oriented Parallel Accelerator Library) 2022.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"
27#include <iosfwd>
28#include <vector>
29#include <exception>
30
31namespace 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.