OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
23 #include "AbstractObjects/Object.h"
24 #include "Expressions/ADeferred.h"
25 #include "Expressions/SValue.h"
26 #include "Utilities/ParseError.h"
27 //#include "Utilities/Options.h"
28 #include "Utilities/Options.h"
29 #include <vector>
30 
31 
32 namespace 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.
100  mutable Object *itsObject;
101  mutable Attribute *itsAttr;
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>
124  AttributeBase(),
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:565
static OpalData * getInstance()
Definition: OpalData.cpp:195
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