OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
SRefAttr.h
Go to the documentation of this file.
1#ifndef OPAL_SRefAttr_HH
2#define OPAL_SRefAttr_HH
3
4// ------------------------------------------------------------------------
5// $RCSfile: SRefAttr.h,v $
6// ------------------------------------------------------------------------
7// $Revision: 1.2 $
8// ------------------------------------------------------------------------
9// Copyright: see Copyright.readme
10// ------------------------------------------------------------------------
11//
12// Template class SRefAttr<T>
13//
14// ------------------------------------------------------------------------
15//
16// $Date: 2000/04/07 12:02:54 $
17// $Author: opal $
18//
19// ------------------------------------------------------------------------
20
25#include "Expressions/SValue.h"
27//#include "Utilities/Options.h"
28#include "Utilities/Options.h"
29#include <vector>
30
31
32namespace Expressions {
33
34 // Class SRefAttr
35 // ----------------------------------------------------------------------
36
38 // The referred attribute may have values of type real, logical or string.
39 // When a reference is seen, the pointers to the relevant object and
40 // attribute are left zero. When the expression value is required,
41 // the object and the attribute are searched, and the pointers cached.
42 // The reference is registered with the object. If the object referred
43 // to is deleted, it calls the invalidate() method of all reference
44 // expressions referring to it. This resets the pointers to zero, so
45 // that the next evaluation forces to search for a replacement object.
46
47 template <class T>
48 class SRefAttr: public AttributeBase {
49
50 public:
51
53 // Use object name [b]oName[/b] to identify the object containing
54 // the scalar, and [b]aName[/b] to identify the scalar itself.
55 SRefAttr(const std::string &oName, const std::string &aName, int index);
56
57 SRefAttr(const SRefAttr &);
58 virtual ~SRefAttr();
59
61 virtual SRefAttr<T> *clone() const;
62
64 // Evaluate the reference and return the value.
65 virtual T evaluate() const;
66
68 // This function has been added for speed of access.
69 virtual double getReal();
70
72 // Force re-evaluation of the reference.
73 virtual void invalidate();
74
76 virtual void print(std::ostream &) const;
77
79 // Evaluate the reference and assign to the scalar referred to.
80 virtual void set(const T &) const;
81
82 private:
83
84 // Not implemented.
86 void operator=(const SRefAttr &);
87
88 // Fill in the reference.
89 void fill() const;
90
91 // The name of the type referred to.
92 static const std::string typeName;
93
94 // The referred object, attribute and index.
95 const std::string obj_name;
96 const std::string att_name;
97 const int itsIndex;
98
99 // The object and attribute referred to.
102 };
103
104
105 template <class T>
106 inline std::ostream &operator<<(std::ostream &os, const SRefAttr<T> &a) {
107 a.print(os);
108 return os;
109 }
110
111
112 // Implementation of class SRefAttr<T>.
113 // ------------------------------------------------------------------------
114
115 template <class T>
117 (const std::string &oName, const std::string &aName, int index):
118 obj_name(oName), att_name(aName), itsIndex(index),
119 itsObject(0), itsAttr(0)
120 {}
121
122 template <class T>
125 obj_name(rhs.obj_name), att_name(rhs.att_name), itsIndex(rhs.itsIndex),
126 itsObject(rhs.itsObject), itsAttr(rhs.itsAttr)
127 {}
128
129
130 template <class T>
132 if(itsObject) itsObject->unregisterReference(this);
133 }
134
135
136
137 template <class T>
139 return new SRefAttr<T>(*this);
140 }
141
142
143 template <class T>
145 fill();
146
147 if(AttributeBase *base = &itsAttr->getBase()) {
148 if(itsIndex) {
149 if(ADeferred<T> *value = dynamic_cast<ADeferred<T>*>(base)) {
150 std::vector<T> array = value->evaluate();
151 if(itsIndex > int(array.size())) {
152 throw ParseError("SRefAttr::evaluate()", "Reference \"" +
153 getImage() + "\" has index out of range.");
154 } else {
155 return array[itsIndex - 1];
156 }
157 } else {
158 throw ParseError("SRefAttr::evaluate()", "Reference \"" +
159 getImage() + "\" is not an array.");
160 }
161 } else {
162 if(SValue<T> *value = dynamic_cast<SValue<T> *>(base)) {
163 return value->evaluate();
164 } else {
165 throw ParseError("SRefAttr::evaluate()", getImage() +
166 "\" is of the wrong type.");
167 }
168 }
169 }
170
171 return T(0);
172 }
173
174
175 template <class T>
177 throw ParseError("SRefAttr<T>::getReal()",
178 "Attribute is not of real type.");
179 }
180
181
182 template <> inline
184 return evaluate();
185 }
186
187
188 template <class T>
189 void SRefAttr<T>::print(std::ostream &os) const {
190 os << obj_name;
191 if(! att_name.empty()) os << "->" << att_name;
192 if(itsIndex != 0) os << '[' << itsIndex << ']';
193 return;
194 }
195
196
197 template <class T>
199 itsObject = 0;
200 itsAttr = 0;
201 }
202
203
204 template <class T>
205 void SRefAttr<T>::set(const T &value) const {
206 fill();
207
208 if(AttributeBase *base = &itsAttr->getBase()) {
209 if(dynamic_cast<SValue<T> *>(base)) {
210 return itsAttr->set(new SValue<T>(value));
211 } else {
212 throw ParseError("Real::get()", "Attribute \"" +
213 itsAttr->getName() + "\" is of the wrong type.");
214 }
215 }
216 }
217
218
219 template <class T>
220 void SRefAttr<T>::fill() const {
221 if(itsObject == 0) {
222 itsObject = OpalData::getInstance()->find(obj_name);
223 if(itsObject == 0) {
224 if(att_name.empty() && itsIndex <= 0) {
225 throw ParseError("SRefAttr::fill()",
226 "\nThe <variable> \"" + obj_name + "\" is unknown.\n");
227 } else {
228 throw ParseError("SRefAttr::fill()",
229 "Object \"" + obj_name + "\" is unknown.");
230 }
231 }
232
233 // Register the reference with the object, to allow invalidation
234 // when the object is deleted.
235 itsObject->registerReference(const_cast<SRefAttr<T>*>(this));
236
237 if(att_name.empty()) {
238 itsAttr = itsObject->findAttribute("VALUE");
239 if(itsAttr == 0) {
240 throw ParseError("SRefAttr::fill()", "Object \"" + obj_name +
241 "\" is not a variable, constant or vector.");
242 }
243 } else {
244 itsAttr = itsObject->findAttribute(att_name);
245 if(itsAttr == 0) {
246 throw ParseError("SRefAttr::fill()", "Attribute \"" + obj_name +
247 "->" + att_name + "\" is unknown.");
248 }
249 }
250 }
251 }
252
253}
254
255#endif // OPAL_SRefAttr_HH
std::complex< double > a
Representation objects and parsers for attribute expressions.
Definition: Expressions.h:64
std::ostream & operator<<(std::ostream &os, const SRefAttr< T > &a)
Definition: SRefAttr.h:106
A representation of an Object attribute.
Definition: Attribute.h:52
Abstract base class for attribute values of different types.
Definition: AttributeBase.h:32
An attribute defined as a reference to a scalar.
Definition: SRefAttr.h:48
static const std::string typeName
Definition: SRefAttr.h:92
void operator=(const SRefAttr &)
virtual ~SRefAttr()
Definition: SRefAttr.h:131
Attribute * itsAttr
Definition: SRefAttr.h:101
const std::string att_name
Definition: SRefAttr.h:96
virtual SRefAttr< T > * clone() const
Make clone.
Definition: SRefAttr.h:138
const std::string obj_name
Definition: SRefAttr.h:95
virtual void set(const T &) const
Store new value.
Definition: SRefAttr.h:205
virtual void print(std::ostream &) const
Print the reference.
Definition: SRefAttr.h:189
virtual void invalidate()
Invalidate.
Definition: SRefAttr.h:198
void fill() const
Definition: SRefAttr.h:220
virtual double getReal()
Return real value.
Definition: SRefAttr.h:176
const int itsIndex
Definition: SRefAttr.h:97
virtual T evaluate() const
Evaluate.
Definition: SRefAttr.h:144
The base class for all OPAL objects.
Definition: Object.h:48
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:566
static OpalData * getInstance()
Definition: OpalData.cpp:196
Parse exception.
Definition: ParseError.h:32
Object attribute with a `‘deferred’' array value.
Definition: ADeferred.h:40
Object attribute with a constant scalar value.
Definition: SValue.h:34