SST  15.1.0
StructuralSimulationToolkit
objectMap.h
1 // Copyright 2009-2025 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-2025, 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 <cassert>
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstdio>
22 #include <iostream>
23 #include <map>
24 #include <ostream>
25 #include <string>
26 #include <type_traits>
27 #include <typeinfo>
28 #include <utility>
29 #include <vector>
30 
31 // #define _OBJMAP_DEBUG_
32 
33 namespace SST::Core::Serialization {
34 
35 class ObjectMap;
36 class TraceBuffer;
37 class ObjectBuffer;
38 
39 
40 // class ObjectMapComparison_impl<T>;
41 /**
42  Metadata object that each ObjectMap has a pointer to in order to
43  track the hierarchy information while traversing the data
44  structures. This is used because a given object can be pointed to
45  by multiple other objects, so we need to track the "path" through
46  which we got to the object so we can traverse back up the object
47  hierarchy.
48 */
50 {
51  /**
52  Parent object that contained this object and through which it
53  was selected.
54  */
56 
57  /**
58  Name of this object in the context of the currently set parent
59  */
60  std::string name;
61 
62  /**
63  Constructor for intializing data memebers
64  */
65  ObjectMapMetaData(ObjectMap* parent, const std::string& name) :
66  parent(parent),
67  name(name)
68  {}
69 
70  ObjectMapMetaData(const ObjectMapMetaData&) = delete;
71  ObjectMapMetaData& operator=(const ObjectMapMetaData&) = delete;
72 };
73 
74 
75 /**
76  Base class for interacting with data from ObjectMap. This includes
77  the ability to keep a history of values and compare the value
78  against specified criteria (i.e., value >= 15, value == 6,
79  etc). Because this class is type agnostic, interactions will be
80  through strings, just as with the ObjectMapClass.
81 
82  The implementations of the virtual functions needs to be done in
83  templated child clases so that the type of the data is known.
84  */
86 {
87 public:
88  enum class Op : std::uint8_t { LT, LTE, GT, GTE, EQ, NEQ, CHANGED, INVALID };
89 
90  static Op getOperationFromString(const std::string& op)
91  {
92  if ( op == "<" ) return Op::LT;
93  if ( op == "<=" ) return Op::LTE;
94  if ( op == ">" ) return Op::GT;
95  if ( op == ">=" ) return Op::GTE;
96  if ( op == "==" ) return Op::EQ;
97  if ( op == "!=" ) return Op::NEQ;
98  if ( op == "changed" ) return Op::CHANGED; // Could also use <>
99  return Op::INVALID;
100  }
101 
102  static std::string getStringFromOp(Op op)
103  {
104  switch ( op ) {
105  case Op::LT:
106  return "<";
107  case Op::LTE:
108  return "<+";
109  case Op::GT:
110  return ">";
111  case Op::GTE:
112  return ">=";
113  case Op::EQ:
114  return "==";
115  case Op::NEQ:
116  return "!=";
117  case Op::CHANGED:
118  return "CHANGED";
119  case Op::INVALID:
120  return "INVALID";
121  default:
122  return "Invalid Op";
123  }
124  }
125 
126  ObjectMapComparison() = default;
127 
128  ObjectMapComparison(const std::string& name) :
129  name_(name)
130  {}
131 
132  ObjectMapComparison(const std::string& name, ObjectMap* obj) :
133  name_(name),
134  obj_(obj)
135  {}
136 
137  virtual ~ObjectMapComparison() = default;
138 
139  virtual bool compare() = 0;
140  virtual std::string getCurrentValue() = 0;
141  virtual void print(std::ostream& stream) = 0;
142  std::string getName() { return name_; }
143 
144  virtual void* getVar() = 0;
145 
146 protected:
147  std::string name_ = "";
148  ObjectMap* obj_ = nullptr;
149 };
150 
151 /**
152  Base class for objects created by the serializer mapping mode used
153  to map the variables for objects. This allows access to read and
154  write the mapped variables. ObjectMaps for fundamental types are
155  templated because they need the type information embedded in the
156  code so they can read and print the values.
157  */
159 {
160 protected:
161  /**
162  Static empty variable map for use by versions that don't have
163  variables (i.e. are fundamentals or classes treated as
164  fundamentals. This is needed because getVariables() returns a
165  reference to the map.
166  */
167  static const std::multimap<std::string, ObjectMap*> emptyVars;
168 
169  /**
170  Metadata object for walking the object hierarchy. When this
171  object is selected by a parent object, a metadata object will
172  be added. The metadata contains a pointer to the parent and
173  the name of this object in the context of the parent. When the
174  object selects its parent, then this field is set to nullptr.
175  If this object is selected and the metadata is not a nullptr,
176  then we have hit a loop in the data structure.
177 
178  Under normal circumstances, the metadata allows you to get the
179  full path of the object according to how you walked the
180  hierarchy, and allows you to return to the parent object. If a
181  loop is detected on select, then the full path of the object
182  will return to the highest level path and the metadata from
183  that path to the current path will be erased.
184  */
186 
187 
188  /**
189  Indicates whether or not the variable is read-only
190  */
191  bool read_only_ = false;
192 
193 
194  /**
195  Function implemented by derived classes to implement set(). No
196  need to check for read-only, that is done in set().
197 
198  @param value Value to set the object to expressed as a string
199  */
200  virtual void set_impl(const std::string& UNUSED(value)) {}
201 
202  /**
203  Function that will get called when this object is selected
204  */
205  virtual void activate_callback() {}
206 
207  /**
208  Function that will get called when this object is deactivated
209  (i.e selectParent() is called)
210  */
211  virtual void deactivate_callback() {}
212 
213 private:
214  /**
215  Reference counter so the object knows when to delete itself.
216  ObjectMaps should not be deleted directly, rather the
217  decRefCount() function should be called when the object is no
218  longer needed and the object will delete itself if refCount_
219  reaches 0.
220  */
221  int32_t refCount_ = 1;
222 
223 public:
224  /**
225  Default constructor primarily used for the "top" object in the hierarchy
226  */
227  ObjectMap() = default;
228 
229 
230  /**
231  Check to see if this object is read-only
232 
233  @return true if ObjectMap is read-only, false otherwise
234  */
235  bool isReadOnly() { return read_only_; }
236 
237  /**
238  Set the read-only state of the object. NOTE: If the ObjectMap
239  is created as read-only, setting the state back to false could
240  lead to unexpected results. Setting the state to false should
241  only be done by the same object that set it to true.
242 
243  @param state Read-only state to set this ObjectMap to. Defaults to true.
244  */
245  void setReadOnly(bool state = true) { read_only_ = state; }
246 
247  /**
248  Check if value string is valid for this type
249 
250  @param value Value to set the object to expressed as a string
251  */
252  virtual bool checkValue(const std::string& UNUSED(value)) { return false; }
253 
254 
255  /**
256  Get the name of the variable represented by this ObjectMap. If
257  this ObjectMap has no metadata registered (i.e. it was not
258  selected by another ObjectMap), then an empty string will be
259  returned, since it has no name.
260 
261  @return Name of variable
262  */
263  std::string getName();
264 
265 
266  /**
267  Get the full hierarchical name of the variable represented by
268  this ObjectMap, based on the path taken to get to this
269  object. If this ObjectMap has no metadata registered (i.e. it
270  was not selected by another ObjectMap), then an empty string
271  will be returned, since it has no name.
272 
273  @return Full hierarchical name of variable
274  */
275  std::string getFullName();
276 
277 
278  /**
279  Get the type of the variable represented by the ObjectMap
280 
281  @return Type of variable
282  */
283  virtual std::string getType() = 0;
284 
285  /**
286  Get the address of the variable represented by the ObjectMap
287 
288  @return Address of variable
289  */
290  virtual void* getAddr() = 0;
291 
292 
293  /**
294  Get the list of child variables contained in this ObjectMap
295 
296  @return Reference to map containing ObjectMaps for this
297  ObjectMap's child variables. Fundamental types will return the
298  same empty map.
299  */
300  virtual const std::multimap<std::string, ObjectMap*>& getVariables() { return emptyVars; }
301 
302  /**
303  Increment the reference counter for this ObjectMap. When
304  keeping a pointer to the ObjectMap, incRefCount() should be
305  called to indicate usage. When done, call decRefCount() to
306  indicate it is no longer needed.
307  */
308  void incRefCount() { ++refCount_; }
309 
310  /**
311  Decrement the reference counter for this ObjectMap. If this
312  reference count reaches zero, the object will delete itself.
313  NOTE: delete should not be called directly on this object and
314  should only be done automatically using decRefCount().
315  */
316  void decRefCount()
317  {
318  if ( !--refCount_ ) delete this;
319  }
320 
321  /**
322  Get the current reference count
323 
324  @return current value of reference counter for the object
325  */
326  int32_t getRefCount() { return refCount_; }
327 
328 
329  /**
330  Get a watch point for this object. If it is not a valid object
331  for a watch point, nullptr will be returned.
332  */
334  const std::string& UNUSED(name), ObjectMapComparison::Op UNUSED(op), const std::string& UNUSED(value))
335  {
336  return nullptr;
337  }
338 
339  virtual ObjectMapComparison* getComparisonVar(const std::string& UNUSED(name), ObjectMapComparison::Op UNUSED(op),
340  const std::string& UNUSED(name2), ObjectMap* UNUSED(var2))
341  {
342  printf("In virtual ObjectMapComparison\n");
343  return nullptr;
344  }
345 
346  virtual ObjectBuffer* getObjectBuffer(const std::string& UNUSED(name), size_t UNUSED(sz)) { return nullptr; }
347 
348  /************ Functions for walking the Object Hierarchy ************/
349 
350 
351  /**
352  Get the parent for this ObjectMap
353 
354  @return Parent for this ObjectMap. If this is the top of the
355  hierarchy, it will return nullptr
356  */
358 
359  /**
360  Get the ObjectMap for the specified variable.
361  Important!!! This function return 'this' pointer and not a nullptr!!!
362  TODO: prefer this return nullptr as bugs have occurred with incorrect use
363 
364  @param name Name of variable to select
365 
366  @return ObjectMap for specified variable, if it exists, this
367  otherwise
368  */
369  ObjectMap* selectVariable(std::string name, bool& loop_detected);
370 
371 
372  /**
373  Adds a variable to this ObjectMap. NOTE: calls to this
374  function will be ignore if isFundamental() returns true.
375 
376  @param name Name of the object in the context of the parent class
377 
378  @param obj ObjectMap to add as a variable
379 
380  */
381  virtual void addVariable(const std::string& UNUSED(name), ObjectMap* UNUSED(obj)) {}
382 
383 
384  /************ Functions for getting/setting Object's Value *************/
385 
386  /**
387  Get the value of the variable as a string. NOTE: this function
388  is only valid for ObjectMaps that represent fundamental types
389  or classes treated as fundamental types (i.e. isFundamental()
390  returns true).
391 
392  @return Value of the represented variable as a string
393  */
394  virtual std::string get() { return ""; }
395 
396  /**
397  Sets the value of the variable represented by the ObjectMap to
398  the specified value, which is represented as a string. The
399  templated child classes for fundamentals will know how to
400  convert the string to a value of the approproprite type. NOTE:
401  this function is only valid for ObjectMaps that represent
402  fundamental types or classes treated as fundamentatl types
403  (i.e. isFundamental() returns true).
404 
405  @param value Value to set the object to, represented as a string
406 
407  */
408  void set(const std::string& value)
409  {
410  if ( !read_only_ ) set_impl(value);
411  }
412 
413  /**
414  Gets the value of the specified variable as a string. NOTE:
415  this function is only valid for ObjectMaps that represent
416  non-fundamental types or classes not treated as fundamental
417  types.
418 
419  @param var Name of variable
420 
421  @return Value of the specified variable, represented as a
422  string
423  */
424  virtual std::string get(const std::string& var);
425 
426  /**
427  Sets the value of the specified variable to the specified
428  value, which is represented as a string. The templated child
429  classes for fundamentals will know how to convert the string to
430  a value of the approproprite type. NOTE: this function is only
431  valid for ObjectMaps that represent non-fundamental types or
432  classes not treated as fundamentatl types (i.e. they must have
433  children).
434 
435  @param var Name of variable
436 
437  @param value Value to set var to represented as a string
438 
439  @param[out] found Set to true if var is found, set to false otherwise
440 
441  @param[out] read_only Set to true if var is read-only, set to false otherwise
442 
443  */
444  virtual void set(const std::string& var, const std::string& value, bool& found, bool& read_only);
445 
446  /**
447  Check to see if this ObjectMap represents a fundamental or a
448  class treated as a fundamental.
449 
450  @return true if this ObjectMap represents a fundamental or
451  class treated as a fundamental, false otherwise
452  */
453  virtual bool isFundamental() { return false; }
454 
455  /**
456  Check to see if this ObjectMap represents a container
457 
458  @return true if this ObjectMap represents a container, false
459  otherwise
460  */
461  virtual bool isContainer() { return false; }
462 
463  /**
464  Destructor. NOTE: delete should not be called directly on
465  ObjectMaps, rather decRefCount() should be called when the
466  object is no longer needed.
467  */
468  virtual ~ObjectMap() = default;
469 
470  /**
471  Disallow copying and assignment
472  */
473 
474  ObjectMap(const ObjectMap&) = delete;
475  ObjectMap& operator=(const ObjectMap&) = delete;
476 
477  /**
478  Static function to demangle type names returned from typeid(T).name()
479 
480  @param name typename returned from typeid(T).name()
481 
482  @return demangled name
483  */
484  static std::string demangle_name(const char* name);
485 
486  /**
487  Create a string that lists information for the specified
488  variable. This will list all child variables, including the
489  values for any children that are fundamentals, up to the
490  specified recursion depth.
491 
492  @param name Name of variable to list
493 
494  @param[out] found Set to true if variable is found, set to false otherwise
495 
496  @param recurse Number of levels to recurse (default is 0)
497 
498  @return String representing this object and any children
499  included based on the value of recurse
500  */
501  virtual std::string listVariable(std::string name, bool& found, int recurse = 0);
502 
503  /**
504  Create a string that lists information for the current object.
505  This will list all child variables, including the values for
506  any children that are fundamentals, up to the specified
507  recursion depth.
508 
509  @param recurse Number of levels to recurse (default is 0)
510 
511  @return String representing this object and any children
512  included based on the value of recurse
513  */
514  virtual std::string list(int recurse = 0);
515 
516  /**
517  Find a variable in this object map
518 
519  @param name Name of variable to find
520 
521  @return ObjectMap representing the requested variable if it is
522  found, nullptr otherwise
523  */
524  virtual ObjectMap* findVariable(const std::string& name)
525  {
526  auto& variables = getVariables();
527  for ( auto [it, end] = variables.equal_range(name); it != end; ++it )
528  return it->second; // For now, we return only the first match if multiple matches
529  return nullptr;
530  }
531 
532 private:
533  /**
534  Called to activate this ObjectMap. This will create the
535  metadata object and call activate_callback().
536 
537  @param parent ObjectMap parent of this ObjectMap
538 
539  @param name Name of this ObjectMap in the context of the parent
540  */
541  void activate(ObjectMap* parent, const std::string& name)
542  {
543  mdata_ = new ObjectMapMetaData(parent, name);
545  }
546 
547  /**
548  Deactivate this object. This will remove and delete the
549  metadata and call deactivate_callback().
550  */
551  void deactivate()
552  {
553  delete mdata_;
554  mdata_ = nullptr;
556  }
557 
558  /**
559  Function called by list to recurse the object hierarchy
560 
561  @param name Name of current ObjectMap
562 
563  @param level Current level of recursion
564 
565  @param recurse Number of levels deep to recurse
566  */
567  std::string listRecursive(const std::string& name, int level, int recurse);
568 };
569 
570 /**
571  ObjectMap object for non-fundamental, non-container types. This
572  class allows for child variables.
573  */
575 {
576 protected:
577  /**
578  Map that child ObjectMaps are stored in
579  */
580  std::multimap<std::string, ObjectMap*> variables_;
581 
582  /**
583  Default constructor
584  */
585  ObjectMapWithChildren() = default;
586 
587 public:
588  /**
589  Destructor. Should not be called directly (i.e. do not call
590  delete on the object). Call decRefCount() when object is no
591  longer needed. This will also call decRefCount() on all its
592  children.
593  */
595  {
596  for ( auto& obj : variables_ ) {
597  if ( obj.second != nullptr ) {
598  obj.second->decRefCount();
599  }
600  }
601  }
602 
603  /**
604  Disallow copying and assignment
605  */
606 
608  ObjectMapWithChildren& operator=(const ObjectMapWithChildren&) = delete;
609 
610  /**
611  Adds a variable to this ObjectMap
612 
613  @param name Name of the object in the context of this ObjectMap
614 
615  @param obj ObjectMap to add as a variable
616  */
617  void addVariable(const std::string& name, ObjectMap* obj) override { variables_.emplace(name, obj); }
618 
619  /**
620  Get the list of child variables contained in this ObjectMap
621 
622  @return Reference to map containing ObjectMaps for this ObjectMap's
623  child variables. pair.first is the name of the variable in the
624  context of this object. pair.second is a pointer to the ObjectMap.
625  */
626  const std::multimap<std::string, ObjectMap*>& getVariables() override { return variables_; }
627 };
628 
629 
630 /**
631  ObjectMap object to create a level of hierarchy that doesn't
632  represent a specific object. This can be used to create views of
633  data that don't align specifically with the underlying data
634  structures.
635  */
637 {
638 public:
639  /**
640  Default constructor
641  */
642  ObjectMapHierarchyOnly() = default;
643 
644 
645  /**
646  Destructor. Should not be called directly (i.e. do not call
647  delete on the object). Call decRefCount() when object is no
648  longer needed. This will also call decRefCount() on all its
649  children.
650  */
651  ~ObjectMapHierarchyOnly() override = default;
652 
653  /**
654  Returns empty string since there is no underlying object being
655  represented
656 
657  @return empty string
658  */
659  std::string getType() override { return ""; }
660 
661  /**
662  Returns nullptr since there is no underlying object being
663  represented
664 
665  @return nullptr
666  */
667  void* getAddr() override { return nullptr; }
668 };
669 
670 
671 /**
672  ObjectMap object for non-fundamental, non-container types. This
673  class allows for child variables.
674  */
676 {
677 protected:
678  /**
679  Type of the variable as given by the demangled version of
680  typeid(T).name() for the type.
681  */
682  std::string type_;
683 
684  /**
685  Address of the variable for reading and writing
686  */
687  void* addr_ = nullptr;
688 
689 public:
690  /**
691  Default constructor
692  */
693  ObjectMapClass() = default;
694 
695  /**
696  Disallow copying and assignment
697  */
698 
699  ObjectMapClass(const ObjectMapClass&) = delete;
700  ObjectMapClass& operator=(const ObjectMapClass&) = delete;
701 
702  /**
703  Constructor
704 
705  @param addr Address of the object represented by this ObjectMap
706 
707  @param type Type of this object as return by typeid(T).name()
708  */
709  ObjectMapClass(void* addr, const std::string& type) :
711  type_(demangle_name(type.c_str())),
712  addr_(addr)
713  {}
714 
715  /**
716  Destructor. Should not be called directly (i.e. do not call
717  delete on the object). Call decRefCount() when object is no
718  longer needed. This will also call decRefCount() on all its
719  children.
720  */
721  ~ObjectMapClass() override = default;
722 
723  /**
724  Get the type of the represented object
725 
726  @return type of represented object
727  */
728  std::string getType() override { return type_; }
729 
730  /**
731  Get the address of the represented object
732 
733  @return address of represented object
734  */
735  void* getAddr() override { return addr_; }
736 };
737 
738 
739 /**
740  Template implementation of ObjectMapComparison for <var> <op> <value>
741  */
742 template <typename T>
744 {
745 public:
746  ObjectMapComparison_impl(const std::string& name, T* var, Op op, const std::string& value) :
747  ObjectMapComparison(name),
748  var_(var),
749  op_(op)
750  {
751  // If we are looking for changes, get the current value as the
752  // comp_value_
753  if ( op_ == Op::CHANGED ) {
754  comp_value_ = *var_;
755  }
756  // Otherwise, we have to have a valid value. If the value is
757  // not valid, it will throw an exception.
758  else {
759  comp_value_ = SST::Core::from_string<T>(value);
760  }
761  }
762 
763 
764  bool compare() override
765  {
766  switch ( op_ ) {
767  case Op::LT:
768  return *var_ < comp_value_;
769  break;
770  case Op::LTE:
771  return *var_ <= comp_value_;
772  break;
773  case Op::GT:
774  return *var_ > comp_value_;
775  break;
776  case Op::GTE:
777  return *var_ >= comp_value_;
778  break;
779  case Op::EQ:
780  return *var_ == comp_value_;
781  break;
782  case Op::NEQ:
783  return *var_ != comp_value_;
784  break;
785  case Op::CHANGED:
786  {
787  // See if we've changed
788  bool ret = *var_ != comp_value_;
789  // Store the current value for the next test
790  comp_value_ = *var_;
791  return ret;
792  } break;
793  default:
794  return false;
795  break;
796  }
797  }
798 
799  std::string getCurrentValue() override { return SST::Core::to_string(*var_); }
800 
801  void* getVar() override { return var_; }
802 
803  void print(std::ostream& stream) override
804  {
805  stream << name_ << " " << getStringFromOp(op_);
806  if ( op_ == Op::CHANGED )
807  stream << " ";
808  else
809  stream << " " << SST::Core::to_string(comp_value_) << " ";
810  }
811 
812 private:
813  T* var_ = nullptr;
814  T comp_value_ = T();
815  Op op_ = Op::INVALID;
816 }; // class ObjectMapComparison_impl
817 
818 /**
819  Templated compareType implementations
820  Variables are currently cast to matching types before being passed to this function
821 */
822 template <typename V1>
823 bool
824 cmp(V1 v, ObjectMapComparison::Op op, V1 w)
825 {
826  switch ( op ) {
827  case ObjectMapComparison::Op::LT:
828  return v < w;
829  break;
830  case ObjectMapComparison::Op::LTE:
831  return v <= w;
832  break;
833  case ObjectMapComparison::Op::GT:
834  return v > w;
835  break;
836  case ObjectMapComparison::Op::GTE:
837  return v >= w;
838  break;
839  case ObjectMapComparison::Op::EQ:
840  return v == w;
841  break;
842  case ObjectMapComparison::Op::NEQ:
843  return v != w;
844  break;
845  default:
846  std::cout << "Invalid comparison operator\n";
847  return false;
848  break;
849  }
850 }
851 
852 // Comparison of two variables of the same type
853 template <typename U1, typename U2, std::enable_if_t<std::is_same_v<U1, U2>, int> = true>
854 bool
855 compareType(U1 v, ObjectMapComparison::Op op, U2 w)
856 {
857  // Handle same type - just compare
858  // printf(" CMP: Same type\n");
859  return cmp(v, op, w);
860 }
861 
862 // Comparison of two variables with different arithmetic types
863 template <typename U1, typename U2,
864  std::enable_if_t<!std::is_same_v<U1, U2> && std::is_arithmetic_v<U1> && std::is_arithmetic_v<U2>, int> = true>
865 bool
866 compareType(U1 v, ObjectMapComparison::Op op, U2 w)
867 {
868  // printf(" CMP: Different types\n");
869  // Handle integrals (bool, char, flavors of int)
870  if ( std::is_integral_v<U1> && std::is_integral_v<U2> ) {
871  // both unsigned integrals - cast to unsigned long long
872  if ( std::is_unsigned_v<U1> && std::is_unsigned_v<U2> ) {
873  // printf(" CMP: Both unsigned integrals\n");
874  unsigned long long v1 = static_cast<unsigned long long>(v);
875  unsigned long long w1 = static_cast<unsigned long long>(w);
876  return cmp(v1, op, w1);
877  }
878  // both integers but at least one signed - cast to signed long long
879  else {
880  // printf(" CMP: Not both unsigned integrals\n");
881  long long v1 = static_cast<long long>(v);
882  long long w1 = static_cast<long long>(w);
883  return cmp(v1, op, w1);
884  }
885  }
886  // Handle float/double combinations - cast to long double
887  else if ( std::is_floating_point_v<U1> && std::is_floating_point_v<U2> ) {
888  // printf(" CMP: Both fp\n");
889  long double v1 = static_cast<long double>(v);
890  long double w1 = static_cast<long double>(w);
891  return cmp(v1, op, w1);
892  }
893  else { // Integral and FP comparison - cast integral to fp
894  // printf(" CMP: integral and fp\n");
895  if ( std::is_integral_v<U1> ) {
896  if ( std::is_same_v<U2, float> ) {
897  float v1 = static_cast<float>(v);
898  float w1 = static_cast<float>(w); // unnecessary but compiler needs to know they are the same
899  return cmp(v1, op, w1);
900  }
901  else if ( std::is_same_v<U2, double> ) {
902  double v1 = static_cast<double>(v);
903  double w1 = static_cast<double>(w); // unnecessary ...
904  return cmp(v1, op, w1);
905  }
906  else {
907  long double v1 = static_cast<long double>(v);
908  long double w1 = static_cast<long double>(w); // unnecessary ...
909  return cmp(v1, op, w1);
910  }
911  }
912  else {
913  if ( std::is_same_v<U1, float> ) {
914  float v1 = static_cast<float>(v); // unnecessary ...
915  float w1 = static_cast<float>(w);
916  return cmp(v1, op, w1);
917  }
918  else if ( std::is_same_v<U1, double> ) {
919  double v1 = static_cast<double>(v); // unnecessary ...
920  double w1 = static_cast<double>(w);
921  return cmp(v1, op, w1);
922  }
923  else {
924  long double v1 = static_cast<long double>(v); // unnecessary ...
925  long double w1 = static_cast<long double>(w);
926  return cmp(v1, op, w1);
927  }
928  }
929  }
930 }
931 
932 // Comparison of two variables with at least one non-arithmetic type
933 template <typename U1, typename U2,
934  std::enable_if_t<(!std::is_same_v<U1, U2> && (!std::is_arithmetic_v<U1> || !std::is_arithmetic_v<U2>)), int> = true>
935 bool
936 compareType(U1 UNUSED(v), ObjectMapComparison::Op UNUSED(op), U2 UNUSED(w))
937 {
938  // We shouldn't get here.... Can I throw an error somehow?
939  printf(" ERROR: CMP: Does not support non-arithmetic types\n");
940  return false;
941 }
942 
943 
944 /**
945 Template implementation of ObjectMapComparison for <var> <op> <var>
946 */
947 template <typename T1, typename T2>
949 {
950 public:
951  ObjectMapComparison_var(const std::string& name1, T1* var1, Op op, const std::string& name2, T2* var2) :
952  ObjectMapComparison(name1),
953  name2_(name2),
954  var1_(var1),
955  op_(op),
956  var2_(var2)
957  {}
958 
959  bool compare() override
960  {
961  T1 v1 = *var1_;
962  T2 v2 = *var2_;
963  return compareType(v1, op_, v2);
964  }
965 
966  std::string getCurrentValue() override { return SST::Core::to_string(*var1_) + " " + SST::Core::to_string(*var2_); }
967 
968  void* getVar() override { return var1_; }
969 
970  void print(std::ostream& stream) override
971  {
972  stream << name_ << " " << getStringFromOp(op_);
973  if ( op_ == Op::CHANGED )
974  stream << " ";
975  else
976  stream << " " << name2_ << " ";
977  }
978 
979 private:
980  std::string name2_ = "";
981  T1* var1_ = nullptr;
982  Op op_ = Op::INVALID;
983  T2* var2_ = nullptr;
984 }; // class ObjectMapComparison_impl
985 
986 
988 {
989 public:
990  ObjectBuffer(const std::string& name, size_t sz) :
991  name_(name),
992  bufSize_(sz)
993  {}
994 
995  virtual ~ObjectBuffer() = default;
996 
997  virtual void sample(size_t index, bool trigger) = 0;
998  virtual std::string get(size_t index) = 0;
999  virtual std::string getTriggerVal() = 0;
1000 
1001  std::string getName() { return name_; }
1002  size_t getBufSize() { return bufSize_; }
1003 
1004 private:
1005  std::string name_;
1006  size_t bufSize_;
1007 
1008 }; // class ObjectBuffer
1009 
1010 template <typename T>
1012 {
1013 public:
1014  ObjectBuffer_impl(const std::string& name, T* varPtr, size_t sz) :
1015  ObjectBuffer(name, sz),
1016  varPtr_(varPtr)
1017  {
1018  objectBuffer_.resize(sz);
1019  }
1020 
1021  void sample(size_t index, bool trigger) override
1022  {
1023  objectBuffer_[index] = *varPtr_;
1024  if ( trigger ) triggerVal = *varPtr_;
1025  }
1026 
1027  std::string get(size_t index) override { return SST::Core::to_string(objectBuffer_.at(index)); }
1028 
1029  std::string getTriggerVal() override { return SST::Core::to_string(triggerVal); }
1030 
1031 
1032 private:
1033  T* varPtr_ = nullptr;
1034  std::vector<T> objectBuffer_;
1035  T triggerVal;
1036 
1037 }; // class ObjectBuffer_impl
1038 
1039 
1041 {
1042 
1043 public:
1044  TraceBuffer(Core::Serialization::ObjectMap* var, size_t sz, size_t pdelay) :
1045  varObj_(var),
1046  bufSize_(sz),
1047  postDelay_(pdelay)
1048  {
1049  tagBuffer_.resize(bufSize_);
1050  cycleBuffer_.resize(bufSize_);
1051  handlerBuffer_.resize(bufSize_);
1052  }
1053 
1054  virtual ~TraceBuffer() = default;
1055 
1056  void setBufferReset() { reset_ = true; }
1057 
1058  void resetTraceBuffer()
1059  {
1060  printf(" Reset Trace Buffer\n");
1061  postCount_ = 0;
1062  cur_ = 0;
1063  first_ = 0;
1064  numRecs_ = 0;
1065  samplesLost_ = 0;
1066  isOverrun_ = false;
1067  reset_ = false;
1068  state_ = CLEAR;
1069  }
1070 
1071  size_t getBufferSize() { return bufSize_; }
1072 
1073  void addObjectBuffer(ObjectBuffer* vb)
1074  {
1075  objBuffers_.push_back(vb);
1076  numObjects++;
1077  }
1078 
1079  enum BufferState : int {
1080  CLEAR, // 0 Pre Trigger
1081  TRIGGER, // 1 Trigger
1082  POSTTRIGGER, // 2 Post Trigger
1083  OVERRUN // 3 Overrun
1084  };
1085 
1086  const std::map<BufferState, char> state2char { { CLEAR, '-' }, { TRIGGER, '!' }, { POSTTRIGGER, '+' },
1087  { OVERRUN, 'o' } };
1088 
1089 
1090  bool sampleT(bool trigger, uint64_t cycle, const std::string& handler)
1091  {
1092  size_t start_state = state_;
1093  bool invokeAction = false;
1094 
1095  // if Trigger == TRUE
1096  if ( trigger ) {
1097  if ( start_state == CLEAR ) { // Not previously triggered
1098  state_ = TRIGGER; // State becomes trigger record
1099  }
1100  // printf(" Sample: trigger\n");
1101 
1102  } // if trigger
1103 
1104  if ( start_state == TRIGGER || start_state == POSTTRIGGER ) { // trigger record or post trigger
1105  state_ = POSTTRIGGER; // State becomes post trigger
1106  // printf(" Sample: post trigger\n");
1107  }
1108 
1109 // Circular buffer
1110 #ifdef _OBJMAP_DEBUG_
1111  std::cout << " Sample:" << handler << ": numRecs:" << numRecs_ << " first:" << first_ << " cur:" << cur_
1112  << " state:" << state2char.at(state_) << " isOverrun:" << isOverrun_
1113  << " samplesLost:" << samplesLost_ << std::endl;
1114 #endif
1115  cycleBuffer_[cur_] = cycle;
1116  handlerBuffer_[cur_] = handler;
1117  if ( trigger ) {
1118  triggerCycle = cycle;
1119  }
1120 
1121  // Sample all the trace object buffers
1122  ObjectBuffer* varBuffer_;
1123  for ( size_t obj = 0; obj < numObjects; obj++ ) {
1124  varBuffer_ = objBuffers_[obj];
1125  varBuffer_->sample(cur_, trigger);
1126  }
1127 
1128  if ( numRecs_ < bufSize_ ) {
1129  tagBuffer_[cur_] = state_;
1130  numRecs_++;
1131  cur_ = (cur_ + 1) % bufSize_;
1132  if ( cur_ == 0 ) first_ = 0; // 1;
1133  }
1134  else { // Buffer full
1135  // Check to see if we are overwriting trigger
1136  if ( tagBuffer_[cur_] == TRIGGER ) {
1137  // printf(" Sample Overrun\n");
1138  isOverrun_ = true;
1139  }
1140  tagBuffer_[cur_] = state_;
1141  numRecs_++;
1142  cur_ = (cur_ + 1) % bufSize_;
1143  first_ = cur_;
1144  }
1145 
1146  if ( isOverrun_ ) {
1147  samplesLost_++;
1148  }
1149 
1150  if ( (state_ == TRIGGER) && (postDelay_ == 0) ) {
1151  invokeAction = true;
1152  std::cout << " Invoke Action\n";
1153  }
1154 
1155  if ( state_ == POSTTRIGGER ) {
1156  postCount_++;
1157  if ( postCount_ >= postDelay_ ) {
1158  invokeAction = true;
1159  std::cout << " Invoke Action\n";
1160  }
1161  }
1162 
1163  return invokeAction;
1164  }
1165 
1166  void dumpTraceBufferT()
1167  {
1168  if ( numRecs_ == 0 ) return;
1169 
1170  size_t start;
1171  size_t end;
1172 
1173  start = first_;
1174  if ( cur_ == 0 ) {
1175  end = bufSize_ - 1;
1176  }
1177  else {
1178  end = cur_ - 1;
1179  }
1180  // std::cout << "start=" << start << " end=" << end << std::endl;
1181 
1182  for ( int j = start;; j++ ) {
1183  size_t i = j % bufSize_;
1184 
1185  std::cout << "buf[" << i << "] " << handlerBuffer_.at(i) << " @" << cycleBuffer_.at(i) << " ("
1186  << state2char.at(tagBuffer_.at(i)) << ") ";
1187 
1188  for ( size_t obj = 0; obj < numObjects; obj++ ) {
1189  ObjectBuffer* varBuffer_ = objBuffers_[obj];
1190  std::cout << SST::Core::to_string(varBuffer_->getName()) << "=" << varBuffer_->get(i) << " ";
1191  }
1192  std::cout << std::endl;
1193 
1194  if ( i == end ) {
1195  break;
1196  }
1197  }
1198  }
1199 
1200  void dumpTriggerRecord()
1201  {
1202  if ( numRecs_ == 0 ) {
1203  std::cout << "No trace samples in current buffer" << std::endl;
1204  return;
1205  }
1206  if ( state_ != CLEAR ) {
1207  std::cout << "TriggerRecord:@cycle" << triggerCycle << ": samples lost = " << samplesLost_ << ": ";
1208  for ( size_t obj = 0; obj < numObjects; obj++ ) {
1209  ObjectBuffer* varBuffer_ = objBuffers_[obj];
1210  std::cout << SST::Core::to_string(varBuffer_->getName()) << "=" << varBuffer_->getTriggerVal() << " ";
1211  }
1212  std::cout << std::endl;
1213  }
1214  }
1215 
1216  void printVars()
1217  {
1218  for ( size_t obj = 0; obj < numObjects; obj++ ) {
1219  ObjectBuffer* varBuffer_ = objBuffers_[obj];
1220  std::cout << SST::Core::to_string(varBuffer_->getName()) << " ";
1221  }
1222  }
1223 
1224  void printConfig()
1225  {
1226  std::cout << "bufsize = " << bufSize_ << " postDelay = " << postDelay_ << " : ";
1227  printVars();
1228  }
1229 
1230  // private:
1231  Core::Serialization::ObjectMap* varObj_ = nullptr;
1232  size_t bufSize_ = 64;
1233  size_t postDelay_ = 8;
1234  size_t postCount_ = 0;
1235  size_t cur_ = 0;
1236  size_t first_ = 0;
1237  size_t numRecs_ = 0;
1238  bool isOverrun_ = false;
1239  size_t samplesLost_ = 0;
1240  bool reset_ = false;
1241  BufferState state_ = CLEAR;
1242 
1243  size_t numObjects = 0;
1244  std::vector<BufferState> tagBuffer_;
1245  std::vector<std::string> handlerBuffer_;
1246  std::vector<ObjectBuffer*> objBuffers_;
1247  std::vector<uint64_t> cycleBuffer_;
1248  uint64_t triggerCycle;
1249 
1250 }; // class TraceBuffer
1251 
1252 
1253 /**
1254  ObjectMap representing fundamental types, and classes treated as
1255  fundamental types. In order for an object to be treated as a
1256  fundamental, it must be printable using SST::Core::to_string() and
1257  assignable using SST::Core::from_string(). If this is not true, it
1258  is possible to create a template specialization for the type
1259  desired to be treated as a fundamental. The specialization will
1260  need to provide the functions for getting and setting the values as
1261  a string.
1262 */
1263 template <typename T>
1265 {
1266 protected:
1267  /**
1268  Address of the variable for reading and writing
1269  */
1270  T* addr_ = nullptr;
1271 
1272 public:
1273  /**
1274  Set the value of the object represented as a string
1275 
1276  @param value Value to set the underlying object to, represented
1277  as a string
1278  */
1279  virtual void set_impl(const std::string& value) override { *addr_ = SST::Core::from_string<T>(value); }
1280 
1281  virtual bool checkValue(const std::string& value) override
1282  {
1283  bool ret = false;
1284  try {
1285  T v = SST::Core::from_string<T>(value);
1286  ret = static_cast<bool>(v);
1287  }
1288  catch ( const std::invalid_argument& e ) {
1289  std::cerr << "Error: Invalid value: " << value << std::endl;
1290  return false;
1291  }
1292  catch ( const std::out_of_range& e ) {
1293  std::cerr << "Error: Value is out of range: " << value << std::endl;
1294  return false;
1295  }
1296  ret = true;
1297  return ret;
1298  }
1299 
1300  /**
1301  Get the value of the object as a string
1302  */
1303  virtual std::string get() override { return SST::Core::to_string(*addr_); }
1304 
1305  /**
1306  Returns true as object is a fundamental
1307 
1308  @return true
1309  */
1310  bool isFundamental() override { return true; }
1311 
1312  /**
1313  Get the address of the variable represented by the ObjectMap
1314 
1315  @return Address of variable
1316  */
1317  void* getAddr() override { return (void*)addr_; }
1318 
1319  explicit ObjectMapFundamental(T* addr) :
1320  addr_(addr)
1321  {}
1322 
1323  /**
1324  Destructor. Should not be called directly (i.e. do not call
1325  delete on the object). Call decRefCount() when object is no
1326  longer needed. This will also call decRefCount() on all its
1327  children.
1328  */
1329  ~ObjectMapFundamental() override = default;
1330 
1331  /**
1332  Disallow copying and assignment
1333  */
1334 
1335  ObjectMapFundamental(const ObjectMapFundamental&) = delete;
1336  ObjectMapFundamental& operator=(const ObjectMapFundamental&) = delete;
1337 
1338  /**
1339  Return the type represented by this ObjectMap as given by the
1340  demangled version of typeid(T).name()
1341 
1342  @return type of underlying object
1343  */
1344  std::string getType() override { return demangle_name(typeid(T).name()); }
1345 
1346  ObjectMapComparison* getComparison(
1347  const std::string& name, ObjectMapComparison::Op UNUSED(op), const std::string& value) override
1348  {
1349  return new ObjectMapComparison_impl<T>(name, addr_, op, value);
1350  }
1351 
1352  ObjectMapComparison* getComparisonVar(
1353  const std::string& name, ObjectMapComparison::Op op, const std::string& name2, ObjectMap* var2) override
1354  {
1355  // Ensure var2 is fundamental type
1356  if ( !var2->isFundamental() ) {
1357  printf("Triggers can only use fundamental types; %s is not "
1358  "fundamental\n",
1359  name2.c_str());
1360  return nullptr;
1361  }
1362 
1363  std::string type = var2->getType();
1364 #if 0
1365  std::cout << "In ObjectMapComparison_var: " << name << " " << name2 << std::endl;
1366  // std::cout << "typeid(T): " << demangle_name(typeid(T).name()) << std::endl;
1367  std::string type1 = getType();
1368  std::cout << "getType(v1): " << type1 << std::endl;
1369  std::cout << "getType(v2): " << type << std::endl;
1370 #endif
1371 
1372  // Create ObjectMapComparison_var which compares two variables
1373  // Only support arithmetic types for now
1374  if ( std::is_arithmetic_v<T> ) {
1375  if ( type == "int" ) {
1376  int* addr2 = static_cast<int*>(var2->getAddr());
1377  return new ObjectMapComparison_var<T, int>(name, addr_, op, name2, addr2);
1378  }
1379  else if ( type == "unsigned int" ) {
1380  unsigned int* addr2 = static_cast<unsigned int*>(var2->getAddr());
1381  return new ObjectMapComparison_var<T, unsigned int>(name, addr_, op, name2, addr2);
1382  }
1383  else if ( type == "long" ) {
1384  long* addr2 = static_cast<long*>(var2->getAddr());
1385  return new ObjectMapComparison_var<T, long>(name, addr_, op, name2, addr2);
1386  }
1387  else if ( type == "unsigned long" ) {
1388  unsigned long* addr2 = static_cast<unsigned long*>(var2->getAddr());
1389  return new ObjectMapComparison_var<T, unsigned long>(name, addr_, op, name2, addr2);
1390  }
1391  else if ( type == "char" ) {
1392  char* addr2 = static_cast<char*>(var2->getAddr());
1393  return new ObjectMapComparison_var<T, char>(name, addr_, op, name2, addr2);
1394  }
1395  else if ( type == "signed char" ) {
1396  signed char* addr2 = static_cast<signed char*>(var2->getAddr());
1397  return new ObjectMapComparison_var<T, signed char>(name, addr_, op, name2, addr2);
1398  }
1399  else if ( type == "unsigned char" ) {
1400  unsigned char* addr2 = static_cast<unsigned char*>(var2->getAddr());
1401  return new ObjectMapComparison_var<T, unsigned char>(name, addr_, op, name2, addr2);
1402  }
1403  else if ( type == "short" ) {
1404  short* addr2 = static_cast<short*>(var2->getAddr());
1405  return new ObjectMapComparison_var<T, short>(name, addr_, op, name2, addr2);
1406  }
1407  else if ( type == "unsigned short" ) {
1408  unsigned short* addr2 = static_cast<unsigned short*>(var2->getAddr());
1409  return new ObjectMapComparison_var<T, unsigned short>(name, addr_, op, name2, addr2);
1410  }
1411  else if ( type == "long long" ) {
1412  long long* addr2 = static_cast<long long*>(var2->getAddr());
1413  return new ObjectMapComparison_var<T, long long>(name, addr_, op, name2, addr2);
1414  }
1415  else if ( type == "unsigned long long" ) {
1416  unsigned long long* addr2 = static_cast<unsigned long long*>(var2->getAddr());
1417  return new ObjectMapComparison_var<T, unsigned long long>(name, addr_, op, name2, addr2);
1418  }
1419  else if ( type == "bool" ) {
1420  bool* addr2 = static_cast<bool*>(var2->getAddr());
1421  return new ObjectMapComparison_var<T, bool>(name, addr_, op, name2, addr2);
1422  }
1423  else if ( type == "float" ) {
1424  float* addr2 = static_cast<float*>(var2->getAddr());
1425  return new ObjectMapComparison_var<T, float>(name, addr_, op, name2, addr2);
1426  }
1427  else if ( type == "double" ) {
1428  double* addr2 = static_cast<double*>(var2->getAddr());
1429  return new ObjectMapComparison_var<T, double>(name, addr_, op, name2, addr2);
1430  }
1431  else if ( type == "long double" ) {
1432  long double* addr2 = static_cast<long double*>(var2->getAddr());
1433  return new ObjectMapComparison_var<T, long double>(name, addr_, op, name2, addr2);
1434  }
1435 
1436  else {
1437  std::cout << "Invalid type for comparison: " << name2 << "(" << type << ")\n";
1438  return nullptr;
1439  }
1440  } // end if first var is arithmetic
1441  else {
1442  std::cout << "Invalid type for comparison: " << name2 << "(" << type << ")\n";
1443  return nullptr;
1444  }
1445  }
1446 
1447  ObjectBuffer* getObjectBuffer(const std::string& name, size_t sz) override
1448  {
1449  return new ObjectBuffer_impl<T>(name, addr_, sz);
1450  }
1451 };
1452 
1453 /**
1454  Class used to map containers
1455  */
1456 template <class T>
1458 {
1459 protected:
1460  T* addr_;
1461 
1462 public:
1463  bool isContainer() override final { return true; }
1464 
1465  std::string getType() override { return demangle_name(typeid(T).name()); }
1466 
1467  void* getAddr() override { return addr_; }
1468 
1469  explicit ObjectMapContainer(T* addr) :
1470  addr_(addr)
1471  {}
1472 
1473  ~ObjectMapContainer() override = default;
1474 };
1475 
1476 /**
1477  Class used to map arrays
1478  */
1479 template <class T>
1481 {
1482 protected:
1483  size_t size;
1484 
1485 public:
1486  virtual size_t getSize() { return size; }
1487  ObjectMapArray(T* addr, size_t size) :
1488  ObjectMapContainer<T>(addr),
1489  size(size)
1490  {}
1491  ~ObjectMapArray() override = default;
1492 };
1493 
1494 
1495 } // namespace SST::Core::Serialization
1496 
1497 #endif // SST_CORE_SERIALIZATION_OBJECTMAP_H
Template implementation of ObjectMapComparison for <op>
Definition: objectMap.h:948
bool isFundamental() override
Returns true as object is a fundamental.
Definition: objectMap.h:1310
Base class for interacting with data from ObjectMap.
Definition: objectMap.h:85
const std::multimap< std::string, ObjectMap * > & getVariables() override
Get the list of child variables contained in this ObjectMap.
Definition: objectMap.h:626
bool isContainer() override final
Check to see if this ObjectMap represents a container.
Definition: objectMap.h:1463
void * addr_
Address of the variable for reading and writing.
Definition: objectMap.h:687
virtual void deactivate_callback()
Function that will get called when this object is deactivated (i.e selectParent() is called) ...
Definition: objectMap.h:211
virtual bool isFundamental()
Check to see if this ObjectMap represents a fundamental or a class treated as a fundamental.
Definition: objectMap.h:453
ObjectMap object to create a level of hierarchy that doesn&#39;t represent a specific object...
Definition: objectMap.h:636
~ObjectMapFundamental() override=default
Destructor.
virtual ObjectMapComparison * getComparison(const std::string &UNUSED(name), ObjectMapComparison::Op UNUSED(op), const std::string &UNUSED(value))
Get a watch point for this object.
Definition: objectMap.h:333
~ObjectMapClass() override=default
Destructor.
bool read_only_
Indicates whether or not the variable is read-only.
Definition: objectMap.h:191
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:177
Class used to map containers.
Definition: objectMap.h:1457
ObjectMap representing fundamental types, and classes treated as fundamental types.
Definition: objectMap.h:1264
virtual ~ObjectMap()=default
Destructor.
Template implementation of ObjectMapComparison for <op>
Definition: objectMap.h:743
T * addr_
Address of the variable for reading and writing.
Definition: objectMap.h:1270
virtual void set_impl(const std::string &UNUSED(value))
Function implemented by derived classes to implement set().
Definition: objectMap.h:200
virtual ObjectMap * findVariable(const std::string &name)
Find a variable in this object map.
Definition: objectMap.h:524
~ObjectMapHierarchyOnly() override=default
Destructor.
virtual void set_impl(const std::string &value) override
Set the value of the object represented as a string.
Definition: objectMap.h:1279
ObjectMapClass(void *addr, const std::string &type)
Constructor.
Definition: objectMap.h:709
void * getAddr() override
Get the address of the represented object.
Definition: objectMap.h:735
ObjectMapClass()=default
Default constructor.
Metadata object that each ObjectMap has a pointer to in order to track the hierarchy information whil...
Definition: objectMap.h:49
void addVariable(const std::string &name, ObjectMap *obj) override
Adds a variable to this ObjectMap.
Definition: objectMap.h:617
Base class for objects created by the serializer mapping mode used to map the variables for objects...
Definition: objectMap.h:158
virtual bool isContainer()
Check to see if this ObjectMap represents a container.
Definition: objectMap.h:461
ObjectMapMetaData * mdata_
Metadata object for walking the object hierarchy.
Definition: objectMap.h:185
virtual void activate_callback()
Function that will get called when this object is selected.
Definition: objectMap.h:205
ObjectMap object for non-fundamental, non-container types.
Definition: objectMap.h:675
ObjectMap * selectParent()
Get the parent for this ObjectMap.
Definition: objectMap.cc:47
ObjectMap * parent
Parent object that contained this object and through which it was selected.
Definition: objectMap.h:55
int32_t getRefCount()
Get the current reference count.
Definition: objectMap.h:326
bool isReadOnly()
Check to see if this object is read-only.
Definition: objectMap.h:235
virtual void * getAddr()=0
Get the address of the variable represented by the ObjectMap.
std::string getType() override
Get the type of the variable represented by the ObjectMap.
Definition: objectMap.h:1465
std::string name
Name of this object in the context of the currently set parent.
Definition: objectMap.h:60
void * getAddr() override
Get the address of the variable represented by the ObjectMap.
Definition: objectMap.h:1317
std::string type_
Type of the variable as given by the demangled version of typeid(T).name() for the type...
Definition: objectMap.h:682
ObjectMap object for non-fundamental, non-container types.
Definition: objectMap.h:574
std::string getType() override
Returns empty string since there is no underlying object being represented.
Definition: objectMap.h:659
std::string getName()
Get the name of the variable represented by this ObjectMap.
Definition: objectMap.cc:26
static const std::multimap< std::string, ObjectMap * > emptyVars
Static empty variable map for use by versions that don&#39;t have variables (i.e.
Definition: objectMap.h:167
std::string getType() override
Get the type of the represented object.
Definition: objectMap.h:728
virtual const std::multimap< std::string, ObjectMap * > & getVariables()
Get the list of child variables contained in this ObjectMap.
Definition: objectMap.h:300
virtual std::string list(int recurse=0)
Create a string that lists information for the current object.
Definition: objectMap.cc:201
static std::string demangle_name(const char *name)
Static function to demangle type names returned from typeid(T).name()
Definition: objectMap.cc:161
void * getAddr() override
Returns nullptr since there is no underlying object being represented.
Definition: objectMap.h:667
ObjectMapMetaData(ObjectMap *parent, const std::string &name)
Constructor for intializing data memebers.
Definition: objectMap.h:65
std::string getFullName()
Get the full hierarchical name of the variable represented by this ObjectMap, based on the path taken...
Definition: objectMap.cc:32
virtual void addVariable(const std::string &UNUSED(name), ObjectMap *UNUSED(obj))
Adds a variable to this ObjectMap.
Definition: objectMap.h:381
~ObjectMapWithChildren() override
Destructor.
Definition: objectMap.h:594
Definition: objectMap.h:987
Class used to map arrays.
Definition: objectMap.h:1480
std::multimap< std::string, ObjectMap * > variables_
Map that child ObjectMaps are stored in.
Definition: objectMap.h:580
virtual bool checkValue(const std::string &UNUSED(value))
Check if value string is valid for this type
Definition: objectMap.h:252
ObjectMapWithChildren()=default
Default constructor.
void decRefCount()
Decrement the reference counter for this ObjectMap.
Definition: objectMap.h:316
void incRefCount()
Increment the reference counter for this ObjectMap.
Definition: objectMap.h:308
ObjectMap()=default
Default constructor primarily used for the "top" object in the hierarchy.
std::string getType() override
Return the type represented by this ObjectMap as given by the demangled version of typeid(T)...
Definition: objectMap.h:1344
ObjectMapHierarchyOnly()=default
Default constructor.
ObjectMap * selectVariable(std::string name, bool &loop_detected)
Get the ObjectMap for the specified variable.
Definition: objectMap.cc:59
virtual std::string getType()=0
Get the type of the variable represented by the ObjectMap.
void setReadOnly(bool state=true)
Set the read-only state of the object.
Definition: objectMap.h:245
void * getAddr() override
Get the address of the variable represented by the ObjectMap.
Definition: objectMap.h:1467
Definition: objectMap.h:1040