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