SST  14.1.0
StructuralSimulationToolkit
objectMap.h
1 // Copyright 2009-2024 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2024, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_SERIALIZATION_OBJECTMAP_H
13 #define SST_CORE_SERIALIZATION_OBJECTMAP_H
14 
15 #include "sst/core/from_string.h"
16 #include "sst/core/warnmacros.h"
17 
18 #include <string>
19 #include <vector>
20 
21 namespace SST {
22 namespace Core {
23 namespace Serialization {
24 
25 class ObjectMap;
26 
27 // Metadata object that each ObjectMap has a pointer to in order to
28 // track the hierarchy information while traversing the data
29 // structures. This is used because a given object can be pointed to
30 // by multiple other objects, so we need to track the "path" through
31 // which we got to the object so we can traverse back up the object
32 // hierarchy.
34 {
35  /**
36  Parent object that contained this object and through which it
37  was selected.
38  */
40 
41  /**
42  Name of this object in the context of the currently set parent
43  */
44  std::string name;
45 
46  /**
47  Constructor for intializing data memebers
48  */
49  ObjectMapMetaData(ObjectMap* parent, const std::string& name) : parent(parent), name(name) {}
50 };
51 
52 /**
53  Class created by the serializer mapping mode used to map the
54  variables for objects. This allows access to read and write the
55  mapped variables. The base class is used for non-fundamental and
56  non-container types, but there is a templated child class used for
57  fundameentals and containers. The templating is needed so that the
58  type information can be embedded in the code for reading and
59  writing.
60  */
61 class ObjectMap
62 {
63 protected:
64  /**
65  Static empty variable vector for use by versions that don't
66  have variables (i.e. are fundamentals or classes treated as
67  fundamentals. This is needed because getVariables() returns a
68  reference to the vector.
69  */
70  static std::vector<std::pair<std::string, ObjectMap*>> emptyVars;
71 
72  /**
73  Metedata object for walking the object hierarchy. When this
74  object is selected by a parent object, a metadata object will
75  be added. The metadata contains a pointer to the parent and
76  the name of this object in the context of the parent. If this
77  object is selected and the metadata is non a nullptr, then we
78  have hit a loop in the data structure.
79 
80  Under normal circumstances, the metadata allows you to get the
81  full path of the object according to how you walked the
82  hierarchy, and allows you to return to the parent object. If a
83  loop is detected on select, then the full path of the object
84  will return to the highest level path and the metadata from
85  that path to the current path will be erased.
86  */
88 
89 
90  /**
91  Indicates wheter or not the variable is read-only
92  */
93  bool read_only_ = false;
94 
95 
96  /**
97  Function implemented by derived classes to implement set(). No
98  need to check for read_only, that is done in set().
99  */
100  virtual void set_impl(const std::string& UNUSED(value)) {}
101 
102  /**
103  Function that will get called when this object is selected
104  */
105  virtual void activate_callback() {}
106  virtual void deactivate_callback() {}
107 
108 private:
109  int32_t refCount_ = 1;
110 
111 public:
112  /**
113  Default constructor primarily used for the "top" object in the hierarchy
114  */
116 
117 
118  inline bool isReadOnly() { return read_only_; }
119  inline void setReadOnly() { read_only_ = true; }
120 
121 
122  /**
123  Get the name of the variable represented by this ObjectMap
124 
125  @return Name of variable
126  */
127  std::string getName();
128 
129 
130  /**
131  Get the full hierarchical name of the variable represented by
132  this ObjectMap, based on the path taken to get to this object.
133 
134  @return Full hierarchical name of variable
135  */
136  std::string getFullName();
137 
138 
139  /**
140  Get the type of the variable represented by the ObjectMap
141 
142  @return Type of variable
143  */
144  virtual std::string getType() = 0;
145 
146  /**
147  Get the address of the variable represented by the ObjectMap
148 
149  @return Address of varaible
150  */
151  virtual void* getAddr() = 0;
152 
153 
154  /**
155  Get the list of child variables contained in this ObjectMap
156 
157  @return Reference to vector containing ObjectMaps for this
158  ObjectMap's child variables. Fundamental types will return the
159  same empty vector.
160  */
161  virtual const std::vector<std::pair<std::string, ObjectMap*>>& getVariables() { return emptyVars; }
162 
163 
164  /**
165  Increament the reference counter for this object map
166  */
167  void incRefCount() { refCount_++; }
168 
169  /**
170  Decreament the reference counter for this object map. If this
171  reference count reaches zero, the object will delete itself.
172  NOTE: delete should not be called directly on this object and
173  should only be done automatically using decRefCount().
174  */
175  void decRefCount()
176  {
177  refCount_--;
178  if ( refCount_ == 0 ) { delete this; }
179  }
180 
181  /**
182  Get the current reference count
183 
184  @return current value of reference counter for the object
185  */
186  int32_t getRefCount() { return refCount_; }
187 
188 
189  /************ Functions for walking the Object Hierarchy ************/
190 
191 
192  /**
193  Get the parent for this ObjectMap
194 
195  @return Parent for this ObjectMap. If this is the top of the
196  hierarchy, it will return nullptr
197  */
199 
200  /**
201  Get the ObjectMap for the specified variable
202 
203  @param name Name of variable to select
204 
205  @return ObjectMap for specified variable, if it exists, this
206  otherwise
207  */
208  ObjectMap* selectVariable(std::string name, bool& loop_detected);
209 
210 
211  /**
212  Adds a varaible to this ObjectMap. NOTE: calls to this
213  function will be ignore if isFundamental() returns true.
214 
215  @param name Name of the object in the context of the parent class
216 
217  @param obj ObjectMap to add as a variable
218 
219  */
220  virtual void addVariable(const std::string& UNUSED(name), ObjectMap* UNUSED(obj)) {}
221 
222 
223  /************ Functions for getting/setting Object's Value *************/
224 
225  /**
226  Get the value of the variable as a string. NOTE: this function
227  is only valid for ObjectMaps that represent fundamental types
228  or classes treated as fundamental types.
229 
230  @return Value of the represented variable as a string
231  */
232  virtual std::string get() { return ""; }
233 
234  /**
235  Sets the value of the variable represented by the ObjectMap to
236  the specified value, which is represented as a string. The
237  templated child classes for fundamentals will know how to
238  convert the string to a value of the approproprite type. NOTE:
239  this fucntion is only value for ObjectMaps that represent
240  fundamental types or classes treated as fundamentatl types.
241 
242  @param value Value to set the object to represented as a string
243 
244  */
245  void set(const std::string& value)
246  {
247  if ( read_only_ )
248  return;
249  else
250  set_impl(value);
251  }
252 
253  /**
254  Gets the value of the specified variable as a string. NOTE:
255  this function is only valid for ObjectMaps that represent
256  non-fundamental types or classes not treated as fundamental
257  types.
258 
259  @param var Name of variable
260 
261  @return Value of the specified variable as a string
262  */
263  virtual std::string get(const std::string& var);
264 
265  /**
266  Sets the value of the specified variable to the specified
267  value, which is represented as a string. The templated child
268  classes for fundamentals will know how to convert the string to
269  a value of the approproprite type. NOTE: this fucntion is only
270  valuid for ObjectMaps that represent non-fundamental types or
271  classes not treated as fundamentatl types (i.e. they must have
272  childrent).
273 
274  @param var Name of variable
275 
276  @param value Value to set var to represented as a string
277 
278  @param[out] found Set to true if var is found, set to false otherwise
279 
280  @param[out] read_only Set to true if var is read-only, set to false otherwise
281 
282  */
283  virtual void set(const std::string& var, const std::string& value, bool& found, bool& read_only);
284 
285  /**
286  Check to see if this ObjectMap represents a fundamental or a
287  class treated as a fundamental.
288 
289  @return true if this ObjectMap represents a fundamental or
290  class treated as a fundamental, false otherwise
291  */
292  virtual bool isFundamental() { return false; }
293 
294  /**
295  Check to see if this ObjectMap represents a container
296 
297  @return true if this ObjectMap represents a container, false
298  otherwise
299  */
300  virtual bool isContainer() { return false; }
301 
302 
303  /**
304  Destructor
305  */
306  virtual ~ObjectMap() {}
307 
308  /**
309  Static function to demangle type names returned from typeid<T>.name()
310 
311  @param name typename returned from typid<T>.name()
312 
313  @return demangled name
314  */
315  static std::string demangle_name(const char* name);
316 
317  /**
318  Create a string that lists information for the specified
319  variable. This will list all child variables, including the
320  values for any children that are fundamentals.
321 
322  @param name name of variable to list
323 
324  @param[out] found Set to true if variable is found, set to false otherwise
325 
326  @param recurse number of levels to recurse (default is 0)
327 
328  @return String representing this object and any children
329  included based on the value of recurse
330  */
331  virtual std::string listVariable(std::string name, bool& found, int recurse = 0);
332 
333  /**
334  Create a string that lists information for the current object.
335  This will list all child variables, including the values for
336  any children that are fundamentals.
337 
338  @param recurse number of levels to recurse (default is 0)
339 
340  @return String representing this object and any children
341  included based on the value of recurse
342  */
343  virtual std::string list(int recurse = 0);
344 
345 
346 private:
347  inline void activate(ObjectMap* parent, const std::string& name)
348  {
349  mdata_ = new ObjectMapMetaData(parent, name);
351  }
352 
353  inline void deactivate()
354  {
355  delete mdata_;
356  mdata_ = nullptr;
357  deactivate_callback();
358  }
359 
360  inline ObjectMap* findVariable(const std::string& name)
361  {
362  const std::vector<std::pair<std::string, ObjectMap*>>& variables = getVariables();
363  for ( auto& x : variables ) {
364  if ( x.first == name ) { return x.second; }
365  }
366  return nullptr;
367  }
368 
369  std::string listRecursive(const std::string& name, int level, int recurse);
370 };
371 
372 
373 /**
374  ObjectMap object for non-fundamental, non-container types. This
375  class allows for child variables.
376  */
378 {
379 protected:
380  /**
381  Vector that child ObjectMaps are stored in
382  */
383  std::vector<std::pair<std::string, ObjectMap*>> variables_;
384 
386 
387 public:
389  {
390  for ( auto obj : variables_ ) {
391  if ( obj.second != nullptr ) obj.second->decRefCount();
392  }
393  variables_.clear();
394  }
395 
396  /**
397  Adds a variable to this ObjectMap
398 
399  @param obj ObjectMap to add as a variable
400  */
401  void addVariable(const std::string& name, ObjectMap* obj) override
402  {
403  variables_.push_back(std::make_pair(name, obj));
404  }
405 
406 
407  /**
408  Get the list of child variables contained in this ObjectMap
409 
410  @return Refernce to vector containing ObjectMaps for this
411  ObjectMap's child variables. pair.first is the name of the
412  variable in the context of this object.
413  */
414  const std::vector<std::pair<std::string, ObjectMap*>>& getVariables() override { return variables_; }
415 };
416 
417 
418 /**
419  ObjectMap object to create a level of hierarchy that doesn't
420  represent a specific object. This can be used to create views of
421  data that don't align specifically with the underlying data
422  structures.
423  */
425 {
426 public:
428 
430 
431  /**
432  Returns empty string since there is no underlying object being
433  represented
434 
435  @return empty string
436  */
437  std::string getType() override { return ""; }
438 
439  /**
440  Returns nullptr since there is no underlying object being
441  represented
442 
443  @return nullptr
444  */
445  void* getAddr() override { return nullptr; }
446 };
447 
448 
449 /**
450  ObjectMap object for non-fundamental, non-container types. This
451  class allows for child variables.
452  */
454 {
455 protected:
456  /**
457  Type of the variable as given by the demangled version of
458  typeif<T>.name() for the type.
459  */
460  std::string type_;
461 
462  /**
463  Address of the variable for reading and writing
464  */
465  void* addr_ = nullptr;
466 
467 public:
469 
470  ObjectMapClass(void* addr, const std::string& type) :
472  type_(demangle_name(type.c_str())),
473  addr_(addr)
474  {}
475 
476  ~ObjectMapClass() {}
477 
478  /**
479  Get the type of the represented object
480 
481  @return type of represented object
482  */
483  std::string getType() override { return type_; }
484 
485  /**
486  Get the address of the represented object
487 
488  @return address of represented object
489  */
490  void* getAddr() override { return addr_; }
491 };
492 
493 
494 /**
495  ObjectMap object fundamental types, and classes treated as
496  fundamental types. In order for an object to be treated as a
497  fundamental, it must be printable using std::to_string() and
498  assignable using SST::Core::from_string().
499 */
500 template <typename T>
502 {
503 protected:
504  /**
505  Address of the variable for reading and writing
506  */
507  T* addr_ = nullptr;
508 
509 public:
510  virtual std::string get() override { return std::to_string(*addr_); }
511  virtual void set_impl(const std::string& value) override { *addr_ = SST::Core::from_string<T>(value); }
512 
513  bool isFundamental() override { return true; }
514 
515  /**
516  Get the address of the variable represented by the ObjectMap
517 
518  @return Address of varaible
519  */
520  void* getAddr() override { return addr_; }
521 
522 
523  /**
524  Get the list of child variables contained in this ObjectMap,
525  which in this case will be empty.
526 
527  @return Refernce to vector containing ObjectMaps for this
528  ObjectMap's child variables. This vector will be empty because
529  fundamentals have no children
530  */
531  const std::vector<std::pair<std::string, ObjectMap*>>& getVariables() override { return emptyVars; }
532 
533  ObjectMapFundamental(T* addr) : ObjectMap(), addr_(addr) {}
534 
536 
537  std::string getType() override { return demangle_name(typeid(T).name()); }
538 };
539 
540 
541 } // namespace Serialization
542 } // namespace Core
543 } // namespace SST
544 
545 #endif // SST_CORE_SERIALIZATION_OBJECTMAP_H
bool isFundamental() override
Check to see if this ObjectMap represents a fundamental or a class treated as a fundamental.
Definition: objectMap.h:513
virtual ~ObjectMap()
Destructor.
Definition: objectMap.h:306
void * addr_
Address of the variable for reading and writing.
Definition: objectMap.h:465
virtual bool isFundamental()
Check to see if this ObjectMap represents a fundamental or a class treated as a fundamental.
Definition: objectMap.h:292
ObjectMap object to create a level of hierarchy that doesn&#39;t represent a specific object...
Definition: objectMap.h:424
const std::vector< std::pair< std::string, ObjectMap * > > & getVariables() override
Get the list of child variables contained in this ObjectMap.
Definition: objectMap.h:414
bool read_only_
Indicates wheter or not the variable is read-only.
Definition: objectMap.h:93
virtual std::string listVariable(std::string name, bool &found, int recurse=0)
Create a string that lists information for the specified variable.
Definition: objectMap.cc:155
static std::vector< std::pair< std::string, ObjectMap * > > emptyVars
Static empty variable vector for use by versions that don&#39;t have variables (i.e.
Definition: objectMap.h:70
ObjectMap object fundamental types, and classes treated as fundamental types.
Definition: objectMap.h:501
T * addr_
Address of the variable for reading and writing.
Definition: objectMap.h:507
virtual void set_impl(const std::string &UNUSED(value))
Function implemented by derived classes to implement set().
Definition: objectMap.h:100
virtual const std::vector< std::pair< std::string, ObjectMap * > > & getVariables()
Get the list of child variables contained in this ObjectMap.
Definition: objectMap.h:161
Definition: action.cc:18
ObjectMap()
Default constructor primarily used for the "top" object in the hierarchy.
Definition: objectMap.h:115
void * getAddr() override
Get the address of the represented object.
Definition: objectMap.h:490
void addVariable(const std::string &name, ObjectMap *obj) override
Adds a variable to this ObjectMap.
Definition: objectMap.h:401
Class created by the serializer mapping mode used to map the variables for objects.
Definition: objectMap.h:61
virtual bool isContainer()
Check to see if this ObjectMap represents a container.
Definition: objectMap.h:300
ObjectMapMetaData * mdata_
Metedata object for walking the object hierarchy.
Definition: objectMap.h:87
virtual void activate_callback()
Function that will get called when this object is selected.
Definition: objectMap.h:105
ObjectMap object for non-fundamental, non-container types.
Definition: objectMap.h:453
ObjectMap * selectParent()
Get the parent for this ObjectMap.
Definition: objectMap.cc:51
ObjectMap * parent
Parent object that contained this object and through which it was selected.
Definition: objectMap.h:39
int32_t getRefCount()
Get the current reference count.
Definition: objectMap.h:186
virtual void * getAddr()=0
Get the address of the variable represented by the ObjectMap.
std::string name
Name of this object in the context of the currently set parent.
Definition: objectMap.h:44
void * getAddr() override
Get the address of the variable represented by the ObjectMap.
Definition: objectMap.h:520
std::string type_
Type of the variable as given by the demangled version of typeif<T>.name() for the type...
Definition: objectMap.h:460
ObjectMap object for non-fundamental, non-container types.
Definition: objectMap.h:377
std::string getType() override
Returns empty string since there is no underlying object being represented.
Definition: objectMap.h:437
std::string getName()
Get the name of the variable represented by this ObjectMap.
Definition: objectMap.cc:29
std::string getType() override
Get the type of the represented object.
Definition: objectMap.h:483
virtual std::string list(int recurse=0)
Create a string that lists information for the current object.
Definition: objectMap.cc:179
static std::string demangle_name(const char *name)
Static function to demangle type names returned from typeid<T>.name()
Definition: objectMap.cc:139
void * getAddr() override
Returns nullptr since there is no underlying object being represented.
Definition: objectMap.h:445
const std::vector< std::pair< std::string, ObjectMap * > > & getVariables() override
Get the list of child variables contained in this ObjectMap, which in this case will be empty...
Definition: objectMap.h:531
ObjectMapMetaData(ObjectMap *parent, const std::string &name)
Constructor for intializing data memebers.
Definition: objectMap.h:49
std::string getFullName()
Get the full hierarchical name of the variable represented by this ObjectMap, based on the path taken...
Definition: objectMap.cc:36
virtual void addVariable(const std::string &UNUSED(name), ObjectMap *UNUSED(obj))
Adds a varaible to this ObjectMap.
Definition: objectMap.h:220
void decRefCount()
Decreament the reference counter for this object map.
Definition: objectMap.h:175
void incRefCount()
Increament the reference counter for this object map.
Definition: objectMap.h:167
std::string getType() override
Get the type of the variable represented by the ObjectMap.
Definition: objectMap.h:537
ObjectMap * selectVariable(std::string name, bool &loop_detected)
Get the ObjectMap for the specified variable.
Definition: objectMap.cc:61
std::vector< std::pair< std::string, ObjectMap * > > variables_
Vector that child ObjectMaps are stored in.
Definition: objectMap.h:383
virtual std::string getType()=0
Get the type of the variable represented by the ObjectMap.