The Sparta Modeling Framework
Loading...
Searching...
No Matches
TreeNode.hpp
Go to the documentation of this file.
1// <TreeNode> -*- C++ -*-
2
3
9#pragma once
10
11#include <cstddef>
12#include <cstdint>
13#include <iostream>
14#include <fstream>
15#include <string>
16#include <ostream>
17#include <vector>
18#include <sstream>
19#include <set>
20#include <map>
21#include <unordered_map>
22#include <regex>
23#include <functional>
24#include <memory>
25#include <type_traits>
26#include <typeinfo>
27#include <utility>
28
31#include "sparta/extensions/TreeNodeExtensionManager.hpp"
33#include "sparta/utils/Utils.hpp"
37#include "sparta/utils/StringManager.hpp"
39
40namespace sparta {
42} // namespace sparta
43
44#ifndef TREENODE_LIFETIME_TRACE
53//#define TREENODE_LIFETIME_TRACE 1
54#endif // #ifndef TREENODE_LIFETIME_TRACE
55
56
58#define ALPHANUM_CHARS \
59 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_"
60
62#define DIGIT_CHARS "0123456789"
63
69#define RESERVED_WORDS {"and", "del", "from", "not", \
70 "while", "as", "elif", "global", \
71 "or", "with", "assert", "else", \
72 "if", "pass", "yield", "break", \
73 "except", "import", "print", "class", \
74 "exec", "in", "raise", "continue", \
75 "finally", "is", "return", "def", \
76 "for", "lambda", "try", "__init__", \
77 "__del__", "__cinit__", "__dealloc__", \
78 /* End of Python reserved names */ \
79 "name", "author", "report", "content", \
80 "include", \
81 /* End of SPARTA Report definition reserved nodes */ \
82 "extension" \
83 /* End of SPARTA extensions reserved words */ \
84 }
85
149#define REGISTER_FOR_NOTIFICATION(func, datat, name) \
150 registerForNotification<datat, \
151 typename std::remove_reference<decltype(*this)>::type, \
152 &std::remove_reference<decltype(*this)>::type::func>(this, name);
153
159#define DEREGISTER_FOR_NOTIFICATION(func, datat, name) \
160 deregisterForNotification<datat, \
161 typename std::remove_reference<decltype(*this)>::type, \
162 &std::remove_reference<decltype(*this)>::type::func>(this, name);
163
164#define NOTIFY(func, datat, name) \
165
166
167namespace sparta
168{
169 namespace app {
170 class Simulation;
171 }
172
173 class Clock;
174 class VirtualGlobalTreeNode;
175 class ClockManager;
176 class TreeNodePrivateAttorney;
177 class ParameterBase;
178 class ParameterSet;
179 class Scheduler;
180
204 {
205 public:
212
216 friend class ClockManager;
217
223
229
233
237 typedef uint64_t node_uid_type;
238
242 typedef std::vector<TreeNode*> ChildrenVector;
243
247 typedef std::vector<std::string> AliasVector;
248
255 typedef std::multimap<std::string, TreeNode*> ChildNameMapping;
256
260 typedef uint32_t group_idx_type;
261
265 typedef std::weak_ptr<TreeNode> WeakPtr;
266
270 typedef std::weak_ptr<const TreeNode> ConstWeakPtr;
271
275 typedef std::shared_ptr<TreeNode> SharedPtr;
276
280 typedef std::map<const std::string*, std::vector<TreeNode*>> TagsMap;
281
289 struct ANY_TYPE {};
290
293
297
303
309
313 static constexpr char GROUP_NAME_NONE[] = "";
314
318 static constexpr char NODE_NAME_NONE[] = "";
319
323 static const std::string DEBUG_DUMP_SECTION_DIVIDER;
324
328 static constexpr char NODE_NAME_VIRTUAL_GLOBAL[] = "_SPARTA_virtual_global_";
329
336 static constexpr char LOCATION_NODE_SEPARATOR_ATTACHED = '.';
337
345 static constexpr char LOCATION_NODE_SEPARATOR_EXPECTING = ',';
346
354 static constexpr char LOCATION_NODE_SEPARATOR_UNATTACHED = '~';
355
361 static const uint32_t RENDER_SUBTREE_INDENT = 2;
362
369 static constexpr char GROUP_NAME_BUILTIN[] = "_SPARTA_builtin_group_";
370
391 static const uint64_t CHILD_FIND_THRESHOLD = 100000;
392
399 static const uint64_t CHILD_GET_THRESHOLD = 100000;
400
405 static const uint32_t TEARDOWN_ERROR_LIMIT = 5;
406
411 static const std::vector<std::pair<const char*, std::function<void (std::string&)>>> TREE_NODE_PATTERN_SUBS;
412
415
419
432 throw SpartaException("Device tree with root \"")
433 << getRoot()->getLocation() << "\" not currently in the TREE_BUILDING phase or "
434 << "TREE_CONFIGURING phase, so it cannot enter TREE_LOCKDOWN";
435 }
436 lockdownParametersUtil_();
437 }
438
439 static const std::map<const TreeNode*, WeakPtr>& getParentlessNodes();
440
445 static const std::map<const TreeNode*, WeakPtr>& getAllNodes();
446
451 static std::string formatAllNodes();
452
457 static bool isNodeConstructed(const TreeNode*);
458
461
465
467 TreeNode() = delete;
468
472 TreeNode(const TreeNode&) = delete;
473
484
486 TreeNode& operator=(const TreeNode&) = delete;
487
572 const std::string& name,
573 const std::string& group,
574 group_idx_type group_idx,
575 const std::string& desc,
576 bool is_indexable);
577
584 const std::string& name,
585 const std::string& group,
586 group_idx_type group_idx,
587 const std::string& desc);
588
593 TreeNode(const std::string& name,
594 const std::string& group,
595 group_idx_type group_idx,
596 const std::string& desc);
597
610 const std::string& name,
611 const std::string& desc);
612
626 const std::string& group,
627 group_idx_type group_idx,
628 const std::string& desc);
629
637 TreeNode(const std::string& name,
638 const std::string& desc);
639
645 virtual ~TreeNode();
646
649
653
668 void addAlias(const std::string& alias);
669
676 void addAliases(const AliasVector& v);
677
694 void addTag(const std::string& tag);
695
702 void addTags(const std::vector<std::string>& v);
703
706
710
722 virtual std::string stringize(bool pretty=false) const {
723 (void) pretty;
724 std::stringstream ss;
725 ss << "<" << getLocation();
726 if(is_expired_){
727 ss << " EXPIRED";
728 }
729 stringizeTags(ss);
730 ss << ">";
731 return ss.str();
732 }
733
742 void stringizeTags(std::stringstream& ss) const {
743 if(tags_.size() > 0){
744 ss << " tags:[";
745 uint32_t i = 0;
746 for(auto & tag : tags_){
747 if(i != 0){
748 ss << ", ";
749 }
750 ss << *tag;
751 ++i;
752 }
753 ss << "]";
754 }
755
756 }
757
760
764
769
774 const std::string& getName() const override;
775
781 const std::string* getNamePtr() const;
782
787 bool isAnonymous() const;
788
794 bool isExpired() const;
795
800 bool isIndexableByGroup() const;
801
807 const std::string& getGroup() const;
808
816 const std::string* getGroupNamePtr() const;
817
824
838 const std::vector<const std::string*>& getTags() const;
839
843 bool hasTag(const std::string& tag) const;
844
852 bool hasTag(const std::string* interned_tag_name) const;
853
858 const std::string& getDesc() const;
859
864 bool isBuiltin() const;
865
871 void markHidden(bool hidden=true);
872
880 bool isHidden() const;
881
884
888
901 void validateName(const std::string& nm);
902
928 void validateGroup(const std::string& name,
929 const std::string& group,
930 group_idx_type idx);
931
941 void validateDesc(const std::string& desc);
942
945
949
956 virtual bool isAttached() const {
957 return is_attached_;
958 }
959
964 virtual TreeNode* getParent() {
965 return parent_;
966 }
967
971 virtual const TreeNode* getParent() const {
972 return parent_;
973 }
974
988 template <class T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
989 const T getParentAs(bool must_exist=true) const {
990 const T result = dynamic_cast<const T>(getParent());
991 if(result == nullptr){
992 if(must_exist){
993 throw SpartaException("Could not get parent of ")
994 << getLocation() << " with type: const " << demangle(typeid(T*).name());
995 }
996 return nullptr;
997 }
998 return result;
999 }
1000
1001 // Overload of getParentAs for const access with a non-pointer T type
1002 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1003 const T* getParentAs(bool must_exist=true) const {
1004 return getParentAs<const T*>(must_exist);
1005 }
1006
1007 // Overload of getParentAs for non-const access with a pointer T type
1008 template <class T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
1009 T getParentAs(bool must_exist=true) {
1010 T result = dynamic_cast<T>(getParent());
1011 if(result == nullptr){
1012 if(must_exist){
1013 throw SpartaException("Could not get parent of ")
1014 << getLocation() << " with type: const " << demangle(typeid(T*).name());
1015 }
1016 return nullptr;
1017 }
1018 return result;
1019 }
1020
1021 // Overload of getParentAs for non-const access with a non-pointer T type
1022 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1023 T* getParentAs(bool must_exist=true) {
1024 return getParentAs<T*>(must_exist);
1025 }
1026
1033 virtual TreeNode* getRoot();
1034
1038 virtual const TreeNode* getRoot() const;
1039
1044
1048 const TreeNode *getScopeRoot() const;
1049
1057
1066
1076 uint32_t getNumChildren() const;
1077
1090 TreeNode* getChildAt(uint32_t idx) const;
1091
1107
1123 uint32_t getChildren(std::vector<TreeNode*>& results,
1124 bool ignore_builtin_group=true,
1125 bool ignore_anonymous_nodes=true);
1126
1134 template <class T>
1135 uint32_t getChildrenOfType(std::vector<T*>& results) const
1136 {
1137 uint32_t orig_size = results.size();
1138 for (auto child : getChildren())
1139 {
1140 if (dynamic_cast<T*>(child))
1141 {
1142 results.emplace_back(static_cast<T*>(child));
1143 }
1144 }
1145 return results.size() - orig_size;
1146 }
1147
1153 sparta::TreeNode *findAncestorByName(const std::string &name) {
1154 sparta::TreeNode *parent = getParent();
1155 while (parent != getRoot()) {
1156 if (parent->locationMatchesPattern(name, parent->getParent())) {
1157 return parent;
1158 }
1159 parent = parent->getParent();
1160 }
1161 return nullptr;
1162 }
1163
1179 template <typename T>
1181 sparta::TreeNode *parent = getParent();
1182 while (parent != getRoot()) {
1183 if (parent->getResourceTypeRaw() == typeid(T).name()) {
1184 return parent;
1185 }
1186 parent = parent->getParent();
1187 }
1188 return nullptr;
1189 }
1190
1202 sparta::TreeNode *findAncestorByTag(const std::string& tag)
1203 {
1204 sparta::TreeNode *parent = getParent();
1205 while (parent != getRoot()) {
1206 if (parent->hasTag(tag))
1207 {
1208 return parent;
1209 }
1210 parent = parent->getParent();
1211 }
1212 return nullptr;
1213 }
1214
1224 template<typename T>
1226 {
1227 static_assert(!std::is_pointer<T>::value && !std::is_reference<T>::value,
1228 "Expected a non-pointer/non-reference T template argument");
1230 if (node)
1231 {
1232 return node->getResourceAs<T*>();
1233 }
1234 return nullptr;
1235 }
1236
1243 const AliasVector& getAliases() const;
1244
1268 uint32_t getChildrenIdentifiers(std::vector<std::string>& idents,
1269 bool ignore_builtin_group=true) const;
1270
1280 std::vector<const std::string*> getIdentifiers() const;
1281
1293 uint32_t getGroupSize(const std::string& group);
1294
1304 group_idx_type getGroupIndexMax(const std::string& group);
1305
1316 uint32_t getGroup(const std::string& group,
1317 std::vector<TreeNode*>& results);
1318
1420 uint32_t findChildren(const std::string& pattern,
1421 std::vector<TreeNode*>& results,
1422 std::vector<std::vector<std::string>>& replacements)
1423 {
1424 return findChildren_(pattern, results, replacements, false /*allow_private*/);
1425 }
1426
1430 uint32_t findChildren(const std::string& pattern,
1431 std::vector<TreeNode*>& results)
1432 {
1433 return findChildren_(pattern, results, false /*allow_private*/);
1434 }
1435
1445 virtual uint32_t findImmediateChildren_(std::regex& expr,
1446 std::vector<TreeNode*>& found,
1447 std::vector<std::vector<std::string>>& replacements,
1448 bool allow_private=false);
1449
1453 uint32_t findImmediateChildren_(std::regex& expr,
1454 std::vector<TreeNode*>& found,
1455 bool allow_private=false);
1456
1460 virtual uint32_t findImmediateChildren_(std::regex& expr,
1461 std::vector<const TreeNode*>& found,
1462 std::vector<std::vector<std::string>>& replacements,
1463 bool allow_private=false) const;
1464
1469 uint32_t findImmediateChildren_(std::regex& expr,
1470 std::vector<const TreeNode*>& found,
1471 bool allow_private=false) const;
1472
1503 bool locationMatchesPattern(const std::string& pattern,
1504 const TreeNode* pat_loc) const;
1505
1530 TreeNode* getChild(const std::string& name,
1531 bool must_exist=true)
1532 {
1533 return getChild_(name, must_exist, false /*private_also*/);
1534 }
1535
1537 const TreeNode* getChild(const std::string& name,
1538 bool must_exist=true) const
1539 {
1540 return getChild_(name, must_exist, false /*private also */);
1541 }
1542
1543
1560 std::string getDeepestMatchingPath(const std::string& path) const;
1561
1570 bool hasChild(const std::string& name) const noexcept
1571 {
1572 return hasChild_(name, false /*private also */);
1573 }
1574
1580 bool hasImmediateChild(const TreeNode* n) const noexcept;
1581
1602 template <class T,
1603 typename = typename std::enable_if<std::is_pointer<T>::value>::type,
1604 class ConstT = typename ptr_to_const_obj_ptr<T>::type>
1605 const ConstT getChildAs(const std::string& name, bool must_exist=true) const {
1606 static_assert(std::is_base_of<TreeNode, typename std::remove_pointer<T>::type>::value == true,
1607 "Cannot use getChildAs with a type argument that is not a subclass of " \
1608 "TreeNode. If the caller is looking for a resource, use " \
1609 "getChild(name)->getResource instead.");
1610 const TreeNode* child = TreeNode::getChild(name, must_exist);
1611 const ConstT result = dynamic_cast<ConstT>(child);
1612 if(result == nullptr){
1613 if(must_exist){
1614 throw SpartaException("Could not find child of \"")
1615 << getLocation() << "\" with the relative path \""
1616 << name << "\" that was of type: const "
1617 << demangle(typeid(T*).name()) << ". Found node of type "
1618 << demangle(typeid(*child).name());
1619 }
1620 return nullptr;
1621 }
1622 return result;
1623 }
1624
1625 // Overload of getChildAs for const access with a non-pointer T typeid
1626 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1627 const T* getChildAs(const std::string& name, bool must_exist=true) const {
1628 return getChildAs<const T*>(name, must_exist);
1629 }
1630
1631 // Overload of getChildAs for non-const access with a non-pointer T type
1632 template <class T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
1633 T getChildAs(const std::string& name, bool must_exist=true) {
1634 static_assert(std::is_base_of<TreeNode, typename std::remove_pointer<T>::type>::value == true,
1635 "Cannot use getChildAs with a type argument that is not a subclass of " \
1636 "TreeNode. If the caller is looking for a resource, use " \
1637 "getChild(name)->getResource instead.");
1638 TreeNode* child = TreeNode::getChild(name, must_exist);
1639 T result = dynamic_cast<T>(child);
1640 if(result == nullptr){
1641 if(must_exist){
1642 throw SpartaException("Could not find child of \"")
1643 << getLocation() << "\" with the relative path \""
1644 << name << "\" that was of type: " << demangle(typeid(T).name())
1645 << ". Found node of type "<< demangle(typeid(*child).name());
1646 }
1647 return nullptr;
1648 }
1649 return result;
1650 }
1651
1652 // Overload of getChildAs for non-const access with a non-pointer T type
1653 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1654 T* getChildAs(const std::string& name, bool must_exist=true) {
1655 return getChildAs<T*>(name, must_exist);
1656 }
1657
1658
1670 template <class T,
1671 typename = typename std::enable_if<std::is_pointer<T>::value>::type,
1672 class ConstT = typename ptr_to_const_obj_ptr<T>::type>
1673 ConstT getAs() const {
1674 static_assert(std::is_base_of<TreeNode, typename std::remove_pointer<T>::type>::value == true,
1675 "Cannot use getAs with a type argument that is not a subclass of " \
1676 "TreeNode.");
1677 ConstT result = dynamic_cast<typename ptr_to_const_obj_ptr<T>::type>(this);
1678 if(result == nullptr){
1679 throw SpartaException("Could not get TreeNode \"")
1680 << getLocation() << "\" as type: const " << demangle(typeid(T).name());
1681 }
1682 return result;
1683 }
1684
1695 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1696 const T* getAs() const {
1697 return getAs<const T*>();
1698 }
1699
1710 template <class T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
1711 T getAs() {
1712 static_assert(std::is_base_of<TreeNode, typename std::remove_pointer<T>::type>::value == true,
1713 "Cannot use getAs with a type argument that is not a subclass of " \
1714 "TreeNode.");
1715 T result = dynamic_cast<T>(this);
1716 if(result == nullptr){
1717 throw SpartaException("Could not get TreeNode \"")
1718 << getLocation() << "\" as type: " << demangle(typeid(T).name());
1719 }
1720 return result;
1721 }
1722
1733 template <class T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>
1734 T* getAs() {
1735 return getAs<T*>();
1736 }
1737
1755 uint32_t findChildrenByTag(const std::string& tag,
1756 std::vector<TreeNode*>& results,
1757 int32_t max_depth=-1);
1758
1772 bool isDescendantOf(const TreeNode* ancestor,
1773 int32_t max_depth=-1) const;
1774
1778 std::string getLocation() const override final;
1779
1795 std::string getDisplayLocation() const;
1796
1803 std::string getExpectedLocation() const;
1804
1829 std::string renderSubtree(int32_t max_depth=-1,
1830 bool show_builtins=false,
1831 bool names_only=false,
1832 bool hide_hidden=false,
1833 bool(*leaf_filt_fxn)(const TreeNode*) = nullptr) const;
1834
1845 uint32_t getLevel() const;
1846
1852 template <typename T>
1853 uint32_t getRecursiveNodeCount() const {
1854 uint32_t count = dynamic_cast<const typename std::remove_const<typename std::remove_pointer<T>::type>::type*>(this) != nullptr;
1855 for(auto& child : children_){
1856 count += child->getRecursiveNodeCount<T>();
1857 }
1858 return count;
1859 }
1860
1874
1877
1881
1882 using ExtensionsBase = detail::ExtensionsBase;
1883
1893 void addExtensionFactory(const std::string & extension_name,
1894 std::function<ExtensionsBase*()> factory);
1895
1907 ExtensionsBase * getExtension(const std::string & extension_name, bool no_factory_ok=false)
1908 {
1909 auto ext_mgr = getExtensionManager_();
1910 return ext_mgr->getExtension(getLocation(), extension_name, no_factory_ok);
1911 }
1912
1921 const ExtensionsBase * getExtension(const std::string & extension_name) const
1922 {
1923 auto ext_mgr = getExtensionManager_();
1924 return ext_mgr->getExtension(getLocation(), extension_name);
1925 }
1926
1931 template <typename ExtensionT>
1932 ExtensionT* getExtensionAs(const std::string & extension_name) {
1933 auto ext_mgr = getExtensionManager_();
1934 return ext_mgr->getExtensionAs<ExtensionT>(getLocation(), extension_name);
1935 }
1936
1941 template <typename ExtensionT>
1942 const ExtensionT* getExtensionAs(const std::string & extension_name) const {
1943 auto ext_mgr = getExtensionManager_();
1944 return ext_mgr->getExtensionAs<ExtensionT>(getLocation(), extension_name);
1945 }
1946
1957 ExtensionsBase * getExtension();
1958
1972 const ExtensionsBase * getExtension() const;
1973
1987 ExtensionsBase * createExtension(const std::string & extension_name,
1988 bool replace=false)
1989 {
1990 auto ext_mgr = getExtensionManager_();
1991 return ext_mgr->createExtension(getLocation(), extension_name, replace);
1992 }
1993
2011 ExtensionsBase * createExtension(bool replace=false)
2012 {
2013 auto ext_mgr = getExtensionManager_();
2014 return ext_mgr->createExtension(getLocation(), replace);
2015 }
2016
2020 ExtensionsBase * createExtension(const char* extension_name, bool replace = false)
2021 {
2022 return createExtension(std::string(extension_name), replace);
2023 }
2024
2037 template <typename ExtensionT, typename... Args>
2038 ExtensionT * addExtension(Args&&... args) {
2039 auto ext_mgr = getExtensionManager_();
2040 return ext_mgr->addExtension<ExtensionT>(getLocation(), std::forward<Args>(args)...);
2041 }
2042
2054 template <typename Extension, typename... Args>
2055 Extension * replaceExtension(Args&&... args) {
2056 static_assert(std::is_base_of<ExtensionsBase, Extension>::value);
2057 removeExtension(Extension::NAME);
2058 return addExtension<Extension, Args...>(std::forward<Args>(args)...);
2059 }
2060
2065 bool removeExtension(const std::string & extension_name)
2066 {
2067 auto ext_mgr = getExtensionManager_();
2068 return ext_mgr->removeExtension(getLocation(), extension_name);
2069 }
2070
2074 bool hasExtension(const std::string & extension_name) const {
2075 auto ext_mgr = getExtensionManager_();
2076 return ext_mgr->hasExtension(getLocation(), extension_name);
2077 }
2078
2082 template <typename ExtensionT>
2083 bool hasExtensionOfType(const std::string & extension_name) const noexcept {
2084 auto ext_mgr = getExtensionManager_();
2085 return ext_mgr->hasExtensionOfType<ExtensionT>(getLocation(), extension_name);
2086 }
2087
2095 std::set<std::string> getAllInstantiatedExtensionNames() const
2096 {
2097 if (auto ext_mgr = getExtensionManager_(false)) {
2098 return ext_mgr->getAllInstantiatedExtensionNames(getLocation());
2099 }
2100 return {};
2101 }
2102
2110 std::set<std::string> getAllConfigExtensionNames() const
2111 {
2112 if (auto ext_mgr = getExtensionManager_(false)) {
2113 return ext_mgr->getAllConfigExtensionNames(getLocation());
2114 }
2115 return {};
2116 }
2117
2123 size_t getNumExtensions() const {
2124 if (auto ext_mgr = getExtensionManager_(false)) {
2125 return ext_mgr->getNumExtensions(getLocation());
2126 }
2127 return 0;
2128 }
2129
2133 std::map<std::string, const ExtensionsBase*> getAllExtensions() const {
2134 if (auto ext_mgr = getExtensionManager_(false)) {
2135 return ext_mgr->getAllExtensions(getLocation());
2136 }
2137 return {};
2138 }
2139
2143
2147
2183 void addChild(TreeNode* child, bool inherit_phase=true);
2184
2190 void addChild(TreeNode& child);
2191
2204 {
2205 incrementPrivacyLevel_(1);
2206 }
2207
2212 {
2213 is_scope_root_ = true;
2214 }
2215
2216
2220 bool isScopeRoot() const
2221 {
2222 return is_scope_root_;
2223 }
2224
2227
2236 const Clock* getClock() override{
2237 if(isFinalized()){
2238 return working_clock_;
2239 }else{
2240 // Search for clock
2241 TreeNode* n = this;
2242 while(n){
2243 const Clock* c = n->getLocalClock();
2244 if(c){
2245 return c;
2246 }
2247 n = n->getParent();
2248 }
2249 return nullptr;
2250 }
2251 }
2252
2256 const Clock* getClock() const {
2257 if(isFinalized()){
2258 return working_clock_;
2259 }else{
2260 // Search for clock
2261 const TreeNode* n = this;
2262 while(n){
2263 const Clock* c = n->getLocalClock();
2264 if(c){
2265 return c;
2266 }
2267 n = n->getParent();
2268 }
2269 return nullptr;
2270 }
2271 }
2272
2287 return clock_;
2288 }
2289
2293 const Clock* getLocalClock() const {
2294 return clock_;
2295 }
2296
2307 virtual void setClock(const Clock * clk);
2308
2312 Scheduler * getScheduler(const bool must_exist = false);
2313 const Scheduler * getScheduler(const bool must_exist = false) const;
2314
2337
2342
2358 virtual void addLink(TreeNode *node, const std::string &label);
2359
2373 virtual void activateLink(const std::string &label);
2374
2385 static std::string createSearchRegexPattern(const std::string& pat);
2386
2395 static bool hasWildcardCharacters(const std::string& name);
2396
2412 static std::string getNextName(const std::string& name, size_t& pos);
2413
2422 static bool matchesGlobLike(const std::string& pattern, const std::string& other);
2423
2424
2425 private:
2430 void lockdownParametersUtil_(){
2431 for(auto child : children_){
2432 child->lockdownParametersUtil_();
2433 }
2434 special_params_lockdown_ = true;
2435 }
2436
2442 static node_uid_type getNextNodeUID_();
2443
2451 static void trackParentlessNode_(TreeNode* node);
2452
2461 static void untrackParentlessNode_(TreeNode* node);
2462
2475 static void trackNode_(TreeNode* node);
2476
2498 static void untrackNode_(TreeNode* node) noexcept;
2499
2507 void informAddedChildSubtree_();
2508
2518 void informAddedChildAncestors_(TreeNode* des);
2519
2526 void incrementGetChildCount_(const std::string& name) const;
2527
2531
2559 virtual void setParent_(TreeNode* parent, bool inherit_phase);
2567 void addChild_(TreeNode* child, bool inherit_phase);
2581 void recursSetPhase_(TreePhase phase);
2582
2585
2589
2598 void getLocation_(std::stringstream& ss, bool anticipate_parent=false) const;
2599
2604 void getDisplayLocation_(std::stringstream& ss) const;
2605
2621 uint32_t renderSubtree_(std::stringstream& ss,
2622 uint32_t indent,
2623 int32_t max_depth,
2624 bool show_builtins,
2625 bool names_only,
2626 bool hide_hidden,
2627 bool(*leaf_filt_fxn)(const TreeNode*)) const;
2628
2638 virtual TreeNode*
2639 getImmediateChildByIdentity_(const std::string& name,
2640 bool must_exist=true)
2641 ;
2642
2643 // Overload of getImmediateChildByIdentity_
2645 virtual const TreeNode*
2646 getImmediateChildByIdentity_(const std::string& name,
2647 bool must_exist=true)
2648 const;
2656 void ensureNoParent_(const char* action);
2657
2662 OneWayBool<false> special_params_lockdown_;
2663
2666
2667 protected:
2668
2677 static bool identityMatchesPattern_(const std::string& ident,
2678 std::regex& expr,
2679 std::vector<std::string>& replacements);
2680
2681
2685 static bool identityMatchesPattern_(const std::string& ident,
2686 std::regex& expr);
2687
2707 static std::string getPreviousName_(const std::string& name,
2708 size_t& pos);
2709
2716 std::pair<uint32_t, std::string> recursGetDeepestMatchingPath_(const std::string& path,
2717 size_t name_pos) const;
2718
2749 void setExpectedParent_(const TreeNode* parent);
2750
2757
2772
2780
2788
2795 void enterConfig_() noexcept;
2796
2803
2810
2827
2849
2873 void dumpDebugContent_(std::ostream& out) const noexcept;
2874
2875
2884 void enterTeardown_() noexcept;
2885
2897 void verifyUniqueChildIdentifier_(const std::string& ident,
2898 bool ignore_group_collision=false);
2899
2920
2929
2935
2941
2950 return special_params_lockdown_;
2951 }
2952
2956
2965 {
2966 public:
2967
2968 typedef void (*stub_type)(void* obj,
2969 const TreeNode& origin,
2970 const TreeNode* obs_pt,
2971 const void* data); //, const std::type_info& tinfo);
2972
2973 delegate() :
2974 object_ptr(0),
2975 obs_point(0),
2976 name_ptr(0),
2977 stub_ptr(0),
2978 reveals_origin(true)
2979 { }
2980
2981 delegate(const delegate&& d) :
2982 object_ptr(d.object_ptr),
2983 obs_point(d.obs_point),
2984 name_ptr(d.name_ptr),
2985 stub_ptr(d.stub_ptr),
2986 reveals_origin(d.reveals_origin)
2987 { }
2988
2993 object_ptr = d.object_ptr;
2994 obs_point = d.obs_point;
2995 name_ptr = d.name_ptr;
2996 stub_ptr = d.stub_ptr;
2997 reveals_origin = d.reveals_origin;
2998
2999 return *this;
3000 }
3001
3002 delegate(const delegate& d) :
3003 object_ptr(d.object_ptr),
3004 obs_point(d.obs_point),
3005 name_ptr(d.name_ptr),
3006 stub_ptr(d.stub_ptr),
3007 reveals_origin(d.reveals_origin)
3008 { }
3009
3010
3019 template <class DataT, class T, void (T::*TMethod)(const TreeNode&,
3020 const TreeNode&,
3021 const DataT&)>
3022 constexpr bool equals(T* obj,
3023 const TreeNode& obs_pt,
3024 const std::string& name) const
3025 {
3026 return (stub_ptr == &method_stub<DataT, T, TMethod>)
3027 && (obj == object_ptr)
3028 && (&obs_pt == obs_point)
3029 && (name == *name_ptr);
3030 }
3031
3032 template <class DataT, class T, void (T::*TMethod)(const DataT&)>
3033 constexpr bool equals(T* obj,
3034 const TreeNode& obs_pt,
3035 const std::string& name) const
3036 {
3037 return (stub_ptr == &method_stub<DataT, T, TMethod>)
3038 && (obj == object_ptr)
3039 && (&obs_pt == obs_point)
3040 && (name == *name_ptr);
3041 }
3042
3043
3051 bool operator==(const delegate& d) const {
3052 return (stub_ptr == d.stub_ptr)
3053 && (object_ptr == d.object_ptr)
3054 && (obs_point == d.obs_point)
3055 && (name_ptr == d.name_ptr);
3056 }
3057
3076 bool observes(const TreeNode& obs_pt, const std::string* name) const
3077 {
3078 return (&obs_pt == obs_point)
3079 && TreeNode::notificationCategoryMatch(name_ptr, name);
3080 }
3081
3088 template <class DataT, class T, void (T::*TMethod)(const TreeNode&,
3089 const TreeNode&,
3090 const DataT&)>
3091 static delegate from_method(T* obj,
3092 const TreeNode& obs_pt,
3093 const std::string& name)
3094 {
3095 delegate d;
3096 d.object_ptr = obj;
3097 d.obs_point = &obs_pt;
3098 d.name_ptr = StringManager::getStringManager().internString(name);
3099 d.stub_ptr = &method_stub<DataT, T, TMethod>;
3100 return d;
3101 }
3102
3103 template <class DataT, class T, void (T::*TMethod)(const DataT&)>
3104 static delegate from_method(T* obj,
3105 const TreeNode& obs_pt,
3106 const std::string& name)
3107 {
3108 delegate d;
3109 d.object_ptr = obj;
3110 d.obs_point = &obs_pt;
3111 d.name_ptr = StringManager::getStringManager().internString(name);
3112 d.stub_ptr = &method_stub<DataT, T, TMethod>;
3113 d.reveals_origin = false;
3114 return d;
3115 }
3116
3120 template <typename DataT>
3121 void operator()(const TreeNode& origin,
3122 const DataT& data) const
3123 {
3124 (*stub_ptr)(object_ptr, origin, obs_point, &data); //, typeid(DataT));
3125 }
3126
3127 const std::string* getNameID() const {
3128 return name_ptr;
3129 }
3130
3131 const TreeNode* getObservationPoint() const {
3132 return obs_point;
3133 }
3134
3135 bool revealsOrigin() const { return reveals_origin; }
3136
3137 private:
3138
3145 template <class DataT, class T, void (T::*TMethod)(const TreeNode&,
3146 const TreeNode&,
3147 const DataT&)>
3148 static void method_stub(void* obj,
3149 const TreeNode& origin,
3150 const TreeNode* obs_pt,
3151 const void* data)
3152 {
3153 // Check type
3154 //sparta_assert(tinfo == typeid(DataT),
3155 // "Expected to invoke method delegate for data type \"" << typeid(DataT).name()
3156 // << "\" with incorrect data type \"" << typeid(tinfo).name() << "\"")
3157
3158 T* p = static_cast<T*>(obj);
3159 const DataT& d = *static_cast<const DataT*>(data);
3160 return (p->*TMethod)(origin, *obs_pt, d);
3161 }
3162
3163 template <class DataT, class T, void (T::*TMethod)(const DataT&)>
3164 static void method_stub(void* obj,
3165 const TreeNode& origin,
3166 const TreeNode* obs_pt,
3167 const void* data)
3168 {
3169 (void) origin;
3170 (void) obs_pt;
3171 T* p = static_cast<T*>(obj);
3172 const DataT& d = *static_cast<const DataT*>(data);
3173 return (p->*TMethod)(d);
3174 }
3175
3176 template <class DataT, void (*TMethod)(const TreeNode&,
3177 const TreeNode&,
3178 const DataT&)>
3179 static void method_stub(void* obj,
3180 const TreeNode& origin,
3181 const TreeNode* obs_pt,
3182 const void* data)
3183 {
3184 (void) obj;
3185 const DataT& d = *static_cast<const DataT*>(data);
3186 return (*TMethod)(origin, *obs_pt, d);
3187 }
3188
3189 template <class DataT, void (*TMethod)(const DataT&)>
3190 static void method_stub(void* obj,
3191 const TreeNode& origin,
3192 const TreeNode* obs_pt,
3193 const void* data)
3194 {
3195 (void) obj;
3196 (void) origin;
3197 (void) obs_pt;
3198 const DataT& d = *static_cast<const DataT*>(data);
3199 return (*TMethod)(d);
3200 }
3201
3206 void* object_ptr;
3207
3211 const TreeNode* obs_point;
3212
3217 const std::string* name_ptr;
3218
3222 stub_type stub_ptr;
3223
3229 bool reveals_origin = true;
3230 };
3231
3239
3240 const std::type_info* tinfo_;
3241 size_t hash_code_;
3242
3243 public:
3244
3245 type_info_container() = delete;
3246
3248 tinfo_(rhp.tinfo_),
3249 hash_code_(rhp.hash_code_)
3250 { }
3251
3252 type_info_container(const std::type_info& tinfo) :
3253 tinfo_(&tinfo),
3254 hash_code_(tinfo.hash_code())
3255 { }
3256
3257 bool operator==(const type_info_container& rhp) const {
3258 return hash_code_ == rhp.hash_code_;
3259 }
3260
3261 bool operator<(const type_info_container& rhp) const {
3262 return hash_code_ < rhp.hash_code_;
3263 }
3264
3265 const std::type_info& operator*() const {
3266 return *tinfo_;
3267 }
3268
3269 const std::type_info* get() const {
3270 return tinfo_;
3271 }
3272 };
3273
3277 typedef std::vector<delegate> DelegateVector;
3278
3282 typedef std::map<type_info_container, DelegateVector> NotificationObserverMap;
3283
3284
3293 template <typename DataT>
3295 const DataT& data,
3296 const std::string* name_id) {
3297 // Assure that this notification passes canGenerateNotification. It
3298 // is of no use to us if nodes are generating Notifications that no
3299 // observer can possible expect by examining the tree.
3300 // Skip this in production builds for performance
3301#ifndef NDEBUG
3302 sparta_assert(origin);
3303 sparta_assert(name_id);
3304 NotificationInfo info(origin, &typeid(DataT), name_id);
3305 if(!canGenerateNotification(info)){
3306 throw SpartaException("TreeNode ")
3307 << getLocation() << " posted a notification <"
3308 << origin->getLocation() << ", \"" << demangle(typeid(DataT).name())
3309 << "\", \"" << *name_id
3310 << "\"> which it did not properly announce through canGenerateNotification";
3311 }
3312#endif
3313 propagateNotification_(origin, data, name_id);
3314
3315 // Post to the global virtual node
3316 getVirtualGlobalNode()->propagateNotification_(origin, data, name_id);
3317 }
3318
3334 template <typename DataT, typename T, void (T::*TMethod)(const TreeNode&,
3335 const TreeNode&,
3336 const DataT&)>
3337 DelegateVector::iterator findDelegate_(DelegateVector& dvec,
3338 T* obj,
3339 const std::string& target_name) {
3340 const DelegateVector::const_iterator dend = dvec.end();
3341 DelegateVector::iterator d;
3342 for(d=dvec.begin(); d!=dend; ++d){
3343 if(d->equals<DataT, T, TMethod>(obj, *this, target_name)){
3344 break;
3345 }
3346 }
3347 return d;
3348 }
3349
3350 // Overload of findDelegate_ with one TMethod signature having a sole DataT parameter
3351 template <typename DataT, typename T, void (T::*TMethod)(const DataT&)>
3352 DelegateVector::iterator findDelegate_(DelegateVector& dvec,
3353 T* obj,
3354 const std::string& target_name) {
3355 const DelegateVector::const_iterator dend = dvec.end();
3356 DelegateVector::iterator d;
3357 for(d=dvec.begin(); d!=dend; ++d){
3358 if(d->equals<DataT, T, TMethod>(obj, *this, target_name)){
3359 break;
3360 }
3361 }
3362 return d;
3363 }
3364
3386 virtual void
3388 const std::vector<const std::string*>& name_ids,
3389 TreeNode* obs_node,
3390 const delegate* del,
3391 const bool allow_private);
3392
3405 virtual void
3407 const std::vector<const std::string*>& name_ids,
3408 TreeNode* obs_node,
3409 const delegate* del,
3410 const bool allow_private);
3411
3416 void
3418 const std::string& name,
3419 TreeNode* obs_node,
3420 const delegate* del,
3421 const bool private_only)
3422 {
3423 auto names = parseNotificationNameString(name);
3424 broadcastRegistrationForNotificationToChildren_(tinfo, names, obs_node, del,
3425 private_only);
3426 }
3427
3432 void
3434 const std::string& name,
3435 TreeNode* obs_node,
3436 const delegate* del,
3437 const bool private_only)
3438 {
3439 auto names = parseNotificationNameString(name);
3440 broadcastDeregistrationForNotificationToChildren_(tinfo, names, obs_node, del,
3441 private_only);
3442 }
3443
3452 template <typename DataT>
3454 const DataT& data,
3455 const std::string* name_id) {
3456 to_invoke->invokeDelegates_(this, data, name_id);
3457 }
3458
3459 private:
3460
3472 template <typename DataT>
3473 void invokeDelegates_(const TreeNode* origin,
3474 const DataT& data,
3475 const std::string* name_id) {
3476 auto itr = obs_local_.find(typeid(DataT));
3477 if(itr != obs_local_.end()){
3478 DelegateVector& observers = itr->second;
3479 for(delegate& d : observers) {
3480 // Invoke delegate if matched
3481 if(d.getNameID() == name_id
3482 || d.getNameID() == StringManager::getStringManager().EMPTY){
3483 d(*origin, data); // invoke
3484 }
3485 }
3486 }
3487 }
3488
3507 template <typename DataT>
3508 void propagateNotification_(const TreeNode* origin,
3509 const DataT& data,
3510 const std::string* name_id) {
3511
3512 invokeDelegates_<DataT>(origin, data, name_id);
3513
3514 if(getParent() != nullptr){
3515 getParent()->propagateNotification_(origin, data, name_id);
3516 }
3517 }
3518
3519 // Internal Notification System
3522
3523 public:
3524
3528
3536
3539 const std::type_info* _tinfo,
3540 const std::string* _name) :
3541 origin(_origin),
3542 tinfo(_tinfo),
3543 name(_name)
3544 {
3545 checkValid();
3546 }
3547
3550 origin(rhp.origin),
3551 tinfo(rhp.tinfo),
3552 name(rhp.name)
3553 {
3554 checkValid();
3555 }
3556
3559 origin(rhp.origin),
3560 tinfo(rhp.tinfo),
3561 name(rhp.name)
3562 {
3563 checkValid();
3564 }
3565
3568 rhp.checkValid();
3569 origin = rhp.origin;
3570 tinfo = rhp.tinfo;
3571 name = rhp.name;
3572 return *this;
3573 }
3574
3578 void checkValid() const {
3579 sparta_assert(origin);
3580 sparta_assert(tinfo);
3581 sparta_assert(name);
3582 }
3583
3588
3592 const std::type_info* tinfo;
3593
3597 const std::string* name;
3598 };
3599
3609 uint32_t getPossibleNotifications(std::vector<NotificationInfo>& infos) const;
3610
3616 void dumpPossibleNotifications(std::ostream& o) const noexcept;
3617
3646 template <typename DataT=ANY_TYPE>
3647 uint32_t locateNotificationSources(std::vector<TreeNode*>& nodes,
3648 const std::string& name="") {
3649 static_assert(std::is_same<
3650 typename std::remove_cv<
3651 typename std::remove_reference<
3652 typename std::remove_pointer<DataT>::type
3653 >::type
3654 >::type,
3655 DataT
3656 >::value,
3657 "DataT must NOT be a const, volatile, pointer, or reference"
3658 "type. It violates at least one of these restrictions");
3659
3660 auto& strmgr = StringManager::getStringManager();
3661 const std::string* name_id = strmgr.internString(name);
3662 return locateNotificationSources_<DataT>(nodes, name_id);
3663 }
3664
3672 template <typename DataT=ANY_TYPE>
3673 void dumpLocatedNotificationSources(std::ostream& o, const std::string& name=""){
3674 std::vector<TreeNode*> nodes;
3676 for(const TreeNode* n : nodes){
3677 o << n->stringize() << std::endl;
3678 }
3679 }
3680
3690 uint32_t getPossibleSubtreeNotifications(std::vector<NotificationInfo>& infos) const noexcept;
3696 void dumpPossibleSubtreeNotifications(std::ostream& o) const noexcept;
3697
3722 bool canGenerateNotification(const std::type_info& tinfo,
3723 const std::string* name) const;
3724
3734 bool canGenerateNotification(const std::type_info& tinfo,
3735 const std::string& name) const;
3736
3743
3769 bool canSubtreeGenerateNotification(const std::type_info& tinfo,
3770 const std::string* name) const;
3771
3781 bool canSubtreeGenerateNotification(const std::type_info& tinfo,
3782 const std::string& name) const;
3783
3788 bool canSubtreeGenerateNotifications(const std::type_info& tinfo,
3789 const std::vector<const std::string*>& names) const;
3790
3798 static std::vector<const std::string*> parseNotificationNameString(const std::string& csl);
3799
3873 template <typename DataT, typename T, void (T::*TMethod)(const TreeNode&, const TreeNode&, const DataT&)>
3874 void registerForNotification(T* obj, const std::string& name, bool ensure_possible=true)
3875 {
3876 registerForNotification_<DataT, T, TMethod>(obj, name, ensure_possible, false /*allow_private*/);
3877 }
3878
3879 // Overload which allows registration with a class member function accepting only a data argument
3880 template <typename DataT, typename T, void (T::*TMethod)(const DataT&)>
3881 void registerForNotification(T* obj, const std::string& name, bool ensure_possible=true)
3882 {
3883 registerForNotification_<DataT, T, TMethod>(obj, name, ensure_possible, false /*allow_private*/);
3884 }
3885
3895 template <typename DataT, typename T, void (T::*TMethod)(const TreeNode&, const TreeNode&, const DataT&)>
3896 void deregisterForNotification(T* obj, const std::string& name)
3897 {
3898 deregisterForNotification_<DataT, T, TMethod>(obj, name, false /* allow_private */);
3899 }
3900
3901 // Overload which allows deregistration with a class member function accepting only a data argument
3902 template <typename DataT, typename T, void (T::*TMethod)(const DataT&)>
3903 void deregisterForNotification(T* obj, const std::string& name)
3904 {
3905 deregisterForNotification_<DataT, T, TMethod>(obj, name, false /* allow_private */);
3906 }
3907
3915 bool hasObserversRegisteredForNotification(const std::type_info& tinfo,
3916 const std::string* name) const noexcept;
3917
3927 void getDelegatesRegisteredForNotification(const std::type_info& tinfo,
3928 const std::string* name,
3929 std::vector<delegate>& dels) noexcept;
3930
3937 static bool notificationCategoryMatch(const std::string* query_id,
3938 const std::string* node_id);
3939
3940 // Public Notification System
3943
3944 private:
3945
3949 void incrementPrivacyLevel_(uint32_t privacy_increment)
3950 {
3951 privacy_level_ += privacy_increment;
3952 for (auto n : children_)
3953 {
3954 n->incrementPrivacyLevel_(privacy_increment);
3955 }
3956 }
3957
3978 virtual void onAddingChild_(TreeNode* child) {
3979 (void) child;
3980 // No actions by default
3981 // Could throw to reject child
3982 }
3983
4006 virtual void onSettingParent_(const TreeNode* parent) const {
4007 (void) parent;
4008 // No actions by default
4009 // Could throw to reject parent
4010 }
4011
4028 virtual void onAddedAsChild_() noexcept {
4029 }
4030
4043 virtual void onDescendentSubtreeAdded_(TreeNode* des) noexcept {
4044 (void) des;
4045 }
4046
4053 virtual void onDestroyingParent_() noexcept {
4054 }
4055
4063 virtual void onDestroyingChild_(TreeNode* child) noexcept {
4064 (void) child;
4065 }
4066
4070 virtual void onConfiguring_() {;}
4071
4075 virtual void onBindTreeEarly_() {;}
4076
4080 virtual void onBindTreeLate_() {;}
4081
4110 virtual void onEnteringTeardown_() noexcept {
4111 }
4112
4127 void addChildNameMapping_(const std::string& name,
4128 TreeNode* child);
4129
4134 template <typename DataT>
4135 uint32_t locateNotificationSources_(std::vector<TreeNode*>& nodes, const std::string* name_id){
4136 uint32_t additions = 0;
4137
4138 const std::string* dummy;
4139 if(canGenerateNotification_(typeid(DataT), name_id, dummy)){
4140 nodes.push_back(this);
4141 ++additions;
4142 }
4143
4144 for(TreeNode* child : children_){
4145 additions += child->template locateNotificationSources_<DataT>(nodes, name_id);
4146 }
4147 return additions;
4148 }
4149
4175 virtual void notificationObserverAdded_(const std::type_info& tinfo,
4176 const std::string* name_id,
4177 TreeNode* obs_node,
4178 const delegate* del) {
4179 (void) tinfo;
4180 (void) name_id;
4181 (void) obs_node;
4182 (void) del;
4183 }
4184
4185
4204 virtual void notificationObserverRemoved_(const std::type_info& tinfo,
4205 const std::string* name_id,
4206 TreeNode* obs_node,
4207 const delegate* del) {
4208 (void) tinfo;
4209 (void) name_id;
4210 (void) obs_node;
4211 (void) del;
4212 }
4213
4242 virtual bool canGenerateNotification_(const std::type_info& tinfo,
4243 const std::string* name,
4244 const std::string*& match) const {
4245 (void) tinfo;
4246 (void) name;
4247 (void) match;
4248 return false;
4249 }
4250
4262 virtual void getPossibleNotifications_(std::vector<NotificationInfo>& infos) const {
4263 (void) infos;
4264 }
4265
4276 virtual void createResource_() {
4277 sparta_assert(isFinalizing()); // Must be in the finalizing phase
4278 }
4279
4290 virtual void validateNode_() const {
4291 }
4292
4300 bool canSeeChild_(const TreeNode* node) const
4301 {
4302 sparta_assert(node != nullptr);
4303 // If the node is not on the same privacy level then we can't see it.
4304 return (privacy_level_ == node->privacy_level_);
4305 }
4306 uint32_t findChildren_(const std::string& pattern,
4307 std::vector<TreeNode*>& results,
4308 std::vector<std::vector<std::string>>& replacements,
4309 bool allow_private);
4310
4314 uint32_t findChildren_(const std::string& pattern,
4315 std::vector<TreeNode*>& results,
4316 bool allow_private);
4321 template <typename DataT, typename T, void (T::*TMethod)(const TreeNode&, const TreeNode&, const DataT&)>
4322 void registerForNotification_(T* obj, const std::string& name, bool ensure_possible=true, bool allow_private=false)
4323 {
4324 (void)allow_private;
4325 const std::type_info& data_type = typeid(DataT);
4326 if(true == ensure_possible && false == canSubtreeGenerateNotification(data_type, name)){
4327 throw SpartaException("Cannot registerForNotification for data type \"")
4328 << demangle(typeid(DataT).name()) << "\" and name=\"" << name << "\" on node " << getLocation()
4329 << " with callback on \"" << demangle(typeid(T).name()) << "\""
4330 << "\" because this notification cannot possibly be generated by any descendant of this "
4331 << "node. Set ensure_possible=false to prevent this check if additional notification "
4332 << "source descendants are expected to be added. "
4333 << "It is possible the node generating the desired notification is in a private sub tree.";
4334 }
4335
4336 DelegateVector& observers = obs_local_[data_type]; // Create notification map
4337 if(findDelegate_<DataT, T, TMethod>(observers, obj, name) != observers.end()){
4338 throw SpartaException("Already observing a notification for data type \"")
4339 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4340 << " with callback on \"" << demangle(typeid(T).name()) << "\""
4341 << "\". Cannot register";
4342 }
4343
4344 delegate d = delegate::from_method<DataT, T, TMethod>(obj, *this, name);
4345 observers.push_back(std::move(d));
4346
4347 // Let children know
4348 broadcastRegistrationForNotificationListStringToChildren_(typeid(DataT), name, this, &observers.back(), allow_private);
4349 }
4350
4351 // Overload which allows registration with a class member function accepting only a data argument
4352 template <typename DataT, typename T, void (T::*TMethod)(const DataT&)>
4353 void registerForNotification_(T* obj, const std::string& name, bool ensure_possible=true, const bool allow_private=false)
4354 {
4355 (void)allow_private;
4356 const std::type_info& data_type = typeid(DataT);
4357 if(true == ensure_possible && false == canSubtreeGenerateNotification(data_type, name)){
4358 throw SpartaException("Cannot registerForNotification for data type \"")
4359 << demangle(typeid(DataT).name()) << "\" and name=\"" << name << "\" on node " << getLocation()
4360 << " with callback on \"" << demangle(typeid(T).name()) << "\""
4361 << "\" because this notification cannot possibly be generated by any descendant of this "
4362 << "node. Set ensure_possible=false to prevent this check if additional notification "
4363 << "source descendants are expected to be added. "
4364 << "It is possible the node generating the desired notification is in a private sub tree.";
4365 }
4366
4367 DelegateVector& observers = obs_local_[data_type]; // Create notification map
4368 if(findDelegate_<DataT, T, TMethod>(observers, obj, name) != observers.end()){
4369 throw SpartaException("Already observing a notification for data type \"")
4370 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4371 << " with callback on \"" << demangle(typeid(T).name()) << "\""
4372 << "\". Cannot register";
4373 }
4374
4375 delegate d = delegate::from_method<DataT, T, TMethod>(obj, *this, name);
4376 observers.push_back(std::move(d));
4377
4378 // Let children know
4379 broadcastRegistrationForNotificationListStringToChildren_(typeid(DataT), name, this, &observers.back(), allow_private);
4380 }
4381
4386 template <typename DataT, typename T, void (T::*TMethod)(const TreeNode&, const TreeNode&, const DataT&)>
4387 void deregisterForNotification_(T* obj, const std::string& name, const bool allow_private)
4388 {
4389 (void)allow_private;
4390 const std::type_info& data_type = typeid(DataT);
4391 auto itr = obs_local_.find(data_type);
4392 if(itr == obs_local_.end()){
4393 throw SpartaException("Not currently observing any notification for data type \"")
4394 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4395 << " with callback on \"" << demangle(typeid(T).name()) << "\" function \"" << TMethod
4396 << "\". Cannot deregister";
4397 }
4398 DelegateVector& observers = itr->second;
4399 DelegateVector::iterator d = findDelegate_<DataT, T, TMethod>(observers, obj, name);
4400 if(observers.end() == d){
4401 throw SpartaException("Not currently observing a notification for data type \"")
4402 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4403 << " . Attempted to deregister \"" << demangle(typeid(T).name()) << "\" function \"" << TMethod
4404 << "\". Cannot deregister";
4405 }
4406
4407 // Let children know that a delegate has been deregistered
4408 broadcastDeregistrationForNotificationListStringToChildren_(data_type, name, this, &(*d), allow_private);
4409
4410 observers.erase(d);
4411 }
4412 // Overload which allows deregistration with a class member function accepting only a data argument
4413 template <typename DataT, typename T, void (T::*TMethod)(const DataT&)>
4414 void deregisterForNotification_(T* obj, const std::string& name, const bool allow_private)
4415 {
4416 (void)allow_private;
4417 const std::type_info& data_type = typeid(DataT);
4418 auto itr = obs_local_.find(data_type);
4419 if(itr == obs_local_.end()){
4420 throw SpartaException("Not currently observing any notification for data type \"")
4421 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4422 << " with callback on \"" << demangle(typeid(T).name()) << "\" function \"" << TMethod
4423 << "\". Cannot deregister";
4424 }
4425 DelegateVector& observers = itr->second;
4426 DelegateVector::iterator d = findDelegate_<DataT, T, TMethod>(observers, obj, name);
4427 if(observers.end() == d){
4428 throw SpartaException("Not currently observing a notification for data type \"")
4429 << demangle(typeid(DataT).name()) << "\" Name \"" << name << "\" on node " << getLocation()
4430 << " . Attempted to deregister \"" << demangle(typeid(T).name()) << "\" function \"" << TMethod
4431 << "\". Cannot deregister";
4432 }
4433
4434 // Let children know that a delegate has been deregistered
4435 broadcastDeregistrationForNotificationListStringToChildren_(data_type, name, this, &(*d), allow_private);
4436
4437 observers.erase(d);
4438 }
4443 const TreeNode::ChildrenVector& getAllChildren_() const
4444 {
4445 return children_;
4446 }
4447
4451 template <typename T> T *getScopeRootImpl_(T *node) const;
4452
4456 TreeNode* getChild_(const std::string& name,
4457 bool must_exist,
4458 bool private_also);
4459
4461 const TreeNode* getChild_(const std::string& name,
4462 bool must_exist,
4463 bool private_also) const;
4464
4469 bool hasChild_(const std::string& name, bool private_also) const noexcept;
4470
4474 TreeNodeExtensionManager * getExtensionManager_(bool must_exist = true);
4475
4479 const TreeNodeExtensionManager * getExtensionManager_(bool must_exist = true) const;
4480
4481 private:
4482
4486 const node_uid_type node_uid_;
4487
4491 const std::string* name_;
4492
4496 const bool anon_;
4497
4503 const bool is_indexable_;
4504
4509 const std::string * const group_ptr_;
4510
4514 const group_idx_type group_idx_;
4515
4521 std::vector<const std::string*> tags_;
4522
4526 const std::string * const desc_ptr_;
4527
4540 const std::string* parent_loc_;
4541
4545 TreeNode* parent_;
4546
4551 bool is_attached_;
4552
4557 const Clock* clock_;
4558
4565 const Clock* working_clock_;
4566
4573 std::unordered_map<std::string, std::weak_ptr<ExtensionsBase>> cached_extensions_;
4574
4578
4583 mutable uint32_t num_children_finds_;
4584
4590 mutable uint32_t num_children_gets_;
4591
4594
4600 const TreeNode* expected_parent_;
4601
4605 bool is_builtin_;
4606
4611 bool is_hidden_;
4612
4616 AliasVector aliases_;
4617
4622 SharedPtr self_ptr_;
4623
4633 ChildrenVector children_;
4634
4639 ChildNameMapping names_;
4640
4647 NotificationObserverMap obs_local_;
4648
4653 bool is_expired_;
4654
4686 uint32_t privacy_level_ = 0;
4687
4699 bool is_scope_root_ = false;
4700
4707 class TreeNodeStatics {
4708 public:
4713 std::map<const TreeNode*, WeakPtr> parentless_map_;
4714
4727 std::map<const TreeNode*, WeakPtr> node_map_;
4728 };
4729 static TreeNodeStatics *statics_;
4730
4736 static node_uid_type next_node_uid_;
4737
4741 static TagsMap global_tags_map_;
4742
4747 static uint32_t teardown_errors_;
4748 };
4749
4751 template<class Ch,class Tr>
4752 inline std::basic_ostream<Ch,Tr>&
4753 operator<< (std::basic_ostream<Ch,Tr>& out, sparta::TreeNode const & tn) {
4754 out << tn.stringize();
4755 return out;
4756 }
4757
4759 inline std::ostream& operator<< (std::ostream& out, sparta::TreeNode const * tn) {
4760 if(nullptr == tn){
4761 out << "null";
4762 }else{
4763 out << tn->stringize();
4764 }
4765 return out;
4766 }
4767} // namespace sparta
Contains a number of ArchData pointers.
Basic Node framework in sparta device tree composite pattern.
Helpers for printing and populating vectors.
Object with a name which holds a Resource.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Helpers for enforcing StaticInitialization order.
Container class for any number of ArchData pointers owned externally.
Manages building a clock tree.
A representation of simulated time.
Definition Clock.hpp:44
virtual bool isFinalizing() const
Is this node (and thus the entire tree above it) "finalized".
virtual bool isFinalized() const
Is this node (and thus the entire tree above it) "finalized".
TreePhase getPhase() const
Gets the trees current phase.
TreePhase
Current phase of tree construction (applies to node and entire tree).
@ TREE_CONFIGURING
Setting parameters, ports, and other pre-instantiation attributes. Hierarchy cannot be modified.
@ TREE_BUILDING
Setting up tree hierarchy only (initial state)
Information describing the type of validation being done.
Definition Resource.hpp:31
PhasedObject which can hold 0 or 1 Resource pointers to an associatedresource. Contains logic for set...
const T getResourceAs() const
Gets the resource contained by this node (if any) as the given type.
virtual std::string getResourceTypeRaw() const
Gets the typename of the resource that this node will eventually contain.
A class that lets you schedule events now and in the future.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Static-initialization order controller.
static StringManager & getStringManager()
Returns the StringManager singleton.
const std::string *const EMPTY
Holds interned empty strings.
std::string * internString(const std::string &s)
Stores a string in shared space within this manager unless it is already stored.
Temporary delegate for notificaiton invokation until the implementation is working....
delegate & operator=(const delegate &d)
void operator()(const TreeNode &origin, const DataT &data) const
Invokes the delegate.
bool operator==(const delegate &d) const
Compares all fields in this delegate against another delegate.
bool observes(const TreeNode &obs_pt, const std::string *name) const
Compares against another delegate based on the observation point and name ignoring delegate callback ...
static delegate from_method(T *obj, const TreeNode &obs_pt, const std::string &name)
Creates delegate with given properties.
constexpr bool equals(T *obj, const TreeNode &obs_pt, const std::string &name) const
Compares against another delegate's information based on DataT, T, TMethod, observer pointer,...
Container for std::type_info.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:204
app::Simulation * getSimulation() const
Gets the simulation (if any) associated with this tree.
bool hasExtension(const std::string &extension_name) const
Check if this tree node has an extension by the given name.
virtual void broadcastRegistrationForNotificationToChildren_(const std::type_info &tinfo, const std::vector< const std::string * > &name_ids, TreeNode *obs_node, const delegate *del, const bool allow_private)
Recursively notifies children that the notification described is now (or still is) being observed at ...
static const uint32_t RENDER_SUBTREE_INDENT
Spaces to indent for each tree level in sparta::TreeNode::renderSubtree.
Definition TreeNode.hpp:361
static constexpr char NODE_NAME_VIRTUAL_GLOBAL[]
Node name for the virtual glopbal node.
Definition TreeNode.hpp:328
uint32_t findImmediateChildren_(std::regex &expr, std::vector< TreeNode * > &found, bool allow_private=false)
Variant of findImmediateChildren_ with no replacements vector.
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
Definition TreeNode.hpp:302
node_uid_type getNodeUID() const
Gets the unique ID of this node.
bool hasObserversRegisteredForNotification(const std::type_info &tinfo, const std::string *name) const noexcept
Determines if this TreeNode (not descendants) has any observers for this type of event and name.
ConstT getAs() const
Retrieves this node after casting to type T.
const std::vector< const std::string * > & getTags() const
Gets the set of tags associated with this TreeNode.
std::string getLocation() const override final
bool canGenerateNotification(const std::type_info &tinfo, const std::string &name) const
Can this TreeNode generate a notification of the given type having the given name (does not require i...
ExtensionsBase * createExtension(const char *extension_name, bool replace=false)
std::map< std::string, const ExtensionsBase * > getAllExtensions() const
Get a map of extensions for this node.
ExtensionT * addExtension(Args &&... args)
Add an extension, specifying the ExtensionsBase subclass type. Forward any arguments needed to your s...
static std::string getNextName(const std::string &name, size_t &pos)
Gets the next name between two '.' chars in a string starting at pos.
static const node_uid_type MAX_NODE_UID
Maximum value of node_uid_ before the framework throws an exception.
Definition TreeNode.hpp:308
void validateTree_()
Iterates the finalized tree and validates each node (e.g. ensures statistics can be evaluated)
ExtensionsBase * getExtension(const std::string &extension_name, bool no_factory_ok=false)
Get an extension object by extension name.
virtual uint32_t findImmediateChildren_(std::regex &expr, std::vector< const TreeNode * > &found, std::vector< std::vector< std::string > > &replacements, bool allow_private=false) const
Const-qualified variant of findImmediateChildren_.
void detachFromChildren_()
Removes a node from its children with the expectation this node will be immediately destroyed (i....
static const std::string DEBUG_DUMP_SECTION_DIVIDER
String dividing sections in a debug dump file.
Definition TreeNode.hpp:323
uint32_t getGroup(const std::string &group, std::vector< TreeNode * > &results)
Gets all nodes in a child group.
void dumpPossibleNotifications(std::ostream &o) const noexcept
Dumps a listing of the notifications which this node can generate to the ostream o.
static constexpr char NODE_NAME_NONE[]
Node name for anonymous node.
Definition TreeNode.hpp:318
static bool hasWildcardCharacters(const std::string &name)
Determines if a given node name has any wildcard characters which will be substituted in createSearch...
static constexpr char GROUP_NAME_BUILTIN[]
Reserved name for built-in nodes.
Definition TreeNode.hpp:369
const std::string & getDesc() const
Gets the description of this node.
TreeNode(TreeNode *parent, const std::string &name, const std::string &group, group_idx_type group_idx, const std::string &desc, bool is_indexable)
TreeNode full constructor. Initializes node and adds it as a child of an existing tree node (if paren...
virtual TreeNode * getRoot()
Gets farthest ancestor of this node.
size_t getNumExtensions() const
Get the number of extensions for this node.
void markHidden(bool hidden=true)
Marks this TreeNode hidden for the purposes of printint out nodes. This does not make the node inacce...
TreeNode(TreeNode *parent, const std::string &name, const std::string &desc)
TreeNode constructor with no group information.
uint32_t findChildren(const std::string &pattern, std::vector< TreeNode * > &results)
Version of findChildren with no replacements vector.
static constexpr char GROUP_NAME_NONE[]
Group name indicating that a node belongs to no group.
Definition TreeNode.hpp:313
void simulationTerminating_()
Hook to allow simulation resources to clean-up before simulation is ended.
static bool notificationCategoryMatch(const std::string *query_id, const std::string *node_id)
Checks if two notification categories match where one is an actual category.
void dumpPossibleSubtreeNotifications(std::ostream &o) const noexcept
Dumps a listing of the notifications which this node and its descendants can generate to the ostream ...
bool isIndexableByGroup() const
Returns whether this object is accessible through its parent's interfaces for getting children by gro...
const T getParentAs(bool must_exist=true) const
Retrieves a parent casted to type T* if this node has a parent.
Definition TreeNode.hpp:989
void enterTeardown_() noexcept
Recursively enter TREE_TEARDOWN phase while alerting nodes through onEnteringTeardown_ and alterting ...
virtual void addLink(TreeNode *node, const std::string &label)
Link this tree node with another tree node.
bool canSubtreeGenerateNotifications(const std::type_info &tinfo, const std::vector< const std::string * > &names) const
Checks to see if any a subtree can generate any of several notification names which may be patterns.
uint32_t findChildrenByTag(const std::string &tag, std::vector< TreeNode * > &results, int32_t max_depth=-1)
Finds a set of all children having the selected tag which this node or descendants of this node withi...
static const uint32_t TEARDOWN_ERROR_LIMIT
Number of teardown-phase-related messages that can be printed before the rest will be suppressed.
Definition TreeNode.hpp:405
void addExtensionFactory(const std::string &extension_name, std::function< ExtensionsBase *()> factory)
Add an extension factory to this tree node by its type (name).
static constexpr char LOCATION_NODE_SEPARATOR_EXPECTING
Separator character between node identifiers in a location string when the child is being attached to...
Definition TreeNode.hpp:345
static std::vector< const std::string * > parseNotificationNameString(const std::string &csl)
Parses a comma-separated list of notification names (or patterns) separated by commas and ignoring wh...
TreeNode * getChildAt(uint32_t idx) const
Gets a child at a position in the children vector in the order in which they were added to this node.
void addAlias(const std::string &alias)
Add a single alias for this node.
uint32_t getPossibleSubtreeNotifications(std::vector< NotificationInfo > &infos) const noexcept
Gets information on the possible notifications generated by this node and all its descendants.
std::shared_ptr< TreeNode > SharedPtr
Shared pointer to TreeNode. Acquire with WeakPtr::lock().
Definition TreeNode.hpp:275
const ExtensionsBase * getExtension(const std::string &extension_name) const
Get an extension object by extension name.
TreeNode(const TreeNode &)=delete
Not copy-constructable.
const TreeNode * getExpectedRoot() const
build-time equivalent to getRoot before an object is actually attached to a tree. This is a mainly a ...
void addChild(TreeNode &child)
AddChild by reference for convenience.
void broadcastDeregistrationForNotificationListStringToChildren_(const std::type_info &tinfo, const std::string &name, TreeNode *obs_node, const delegate *del, const bool private_only)
Symmetric oppostie of broadcastRegistrationForNotificationListStringToChildren_.
void broadcastRegistrationForNotificationListStringToChildren_(const std::type_info &tinfo, const std::string &name, TreeNode *obs_node, const delegate *del, const bool private_only)
Entry point to broadcastRegistrationForNotificationToChildren_ recursion. Breaks a name string.
ExtensionsBase * createExtension(const std::string &extension_name, bool replace=false)
Create an extension on demand. This is useful if you want to add an extension to a node that was not ...
virtual bool isAttached() const
Is this node part of a device tree with a proper RootTreeNode at the root.
Definition TreeNode.hpp:956
bool canSubtreeGenerateNotification(const std::type_info &tinfo, const std::string &name) const
Can this TreeNode or its descendants (of any distance) generate a notification of the given type havi...
bool isBuiltin() const
Is this node in the builtins group.
static const std::vector< std::pair< const char *, std::function< void(std::string &)> > > TREE_NODE_PATTERN_SUBS
List of pattern susbtitutions when creating a search pattern from a TreeNode name containing wildcard...
Definition TreeNode.hpp:411
void registerForNotification(T *obj, const std::string &name, bool ensure_possible=true)
Registers a callback method to listen for all notifications having the specified data type DataT and ...
void invokeDelegatesOn_(TreeNode *to_invoke, const DataT &data, const std::string *name_id)
Protected wrapper for invokeDelegates_ which allows a TreeNode to invoke delegates on another TreeNod...
TreeNode()=delete
Not default-constructable.
const ChildrenVector getChildren() const
Gets a vector of all children of this node in any group in the order in which they were added to this...
std::string renderSubtree(int32_t max_depth=-1, bool show_builtins=false, bool names_only=false, bool hide_hidden=false, bool(*leaf_filt_fxn)(const TreeNode *)=nullptr) const
Renders the subtree starting at this node as a string containing an indentation-based depth-first rep...
group_idx_type getGroupIndexMax(const std::string &group)
Gets the largest index of a node in the given group.
void verifyUniqueChildIdentifier_(const std::string &ident, bool ignore_group_collision=false)
Verifies that the given identifier is unique for all children of this node by comparing against names...
const std::string * getGroupNamePtr() const
Gets the group name string pointer (interned in StringManager singleton) of this node.
void detachFromParent_()
Removes a node from its parent with the expectation this node will be immediately destroyed (i....
const TreeNode * getChild(const std::string &name, bool must_exist=true) const
Overloaded const-qualified.
TreeNode(TreeNode &&rhp)
Move constructor.
uint32_t getLevel() const
Gets the level of this node. 0 is root.
uint32_t getChildren(std::vector< TreeNode * > &results, bool ignore_builtin_group=true, bool ignore_anonymous_nodes=true)
Gets all children of this node in the order in which they were added to this node.
sparta::TreeNode * findAncestorByName(const std::string &name)
Find ancestor by name.
void validatePostRun_(const PostRunValidationInfo &info) const
Hook to check the state of the simulator post-run and throw exceptions if something is incorrect.
bool isScopeRoot() const
void validateGroup(const std::string &name, const std::string &group, group_idx_type idx)
Validates the given group name string and group index for this TreeNode. Does not consider context (e...
static constexpr char LOCATION_NODE_SEPARATOR_ATTACHED
Separator character between node identifiers in a location string when the child is attached to the p...
Definition TreeNode.hpp:336
virtual void broadcastDeregistrationForNotificationToChildren_(const std::type_info &tinfo, const std::vector< const std::string * > &name_ids, TreeNode *obs_node, const delegate *del, const bool allow_private)
Recursively notifies children that the notification described has lost one particular observer (del) ...
DelegateVector::iterator findDelegate_(DelegateVector &dvec, T *obj, const std::string &target_name)
Finds a delegate associated with the given type T, object pointer, DataT, and TMethod within a Deleva...
static const std::map< const TreeNode *, WeakPtr > & getAllNodes()
Gets the vector of all TreeNodes currently known to be constructed.
void enterFinalizing_()
Recursively enter TREE_FINALIZING phase.
bool hasTag(const std::string &tag) const
Does this node have a specific tag (by name)
void validateDesc(const std::string &desc)
Validates the given description string for this TreeNode.
Scheduler * getScheduler(const bool must_exist=false)
Get the scheduler associated with this tree node's root.
const std::string * getNamePtr() const
Gets the name of this node's string pointer which isinterned in StringManager)
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
uint32_t group_idx_type
Index within a group.
Definition TreeNode.hpp:260
TreeNode(TreeNode *parent, const std::string &name, const std::string &group, group_idx_type group_idx, const std::string &desc)
TreeNode constructor with no is_indexable parameter [defaults to true].
bool areParametersLocked_() const
This method informs whether the tree is past the lockdown phase for all LOCKED and HIDDEN parameters....
const TreeNode * getScopeRoot() const
static bool matchesGlobLike(const std::string &pattern, const std::string &other)
Determine if a glob-like search pattern matches some other string.
static std::string getPreviousName_(const std::string &name, size_t &pos)
Gets the previous name between two '.' chars in a string starting at pos.
void postPropagatingNotification_(const TreeNode *origin, const DataT &data, const std::string *name_id)
Starts a notification propagating up the tree.
void enterFinalized_()
Recursively enter TREE_FINALIZED phase.
static const uint64_t CHILD_GET_THRESHOLD
Threshold for number of getChild calls after finalization before a warning message is printed about f...
Definition TreeNode.hpp:399
const Clock * getLocalClock()
Gets the clock associated directly with this Node. This is useful for configuration and simulator deb...
const AliasVector & getAliases() const
Gets a vector of all aliases of this node.
bool hasTag(const std::string *interned_tag_name) const
Does this node have a specific tag (by string pointer interned with StringManager)....
ExtensionsBase * getExtension()
Get an extension without needing to specify any particular extension name. If no extensions exist,...
std::string getDeepestMatchingPath(const std::string &path) const
Gets the deepest whole node location starting from this node that matches some part of path starting ...
void deregisterForNotification(T *obj, const std::string &name)
Removes at most one registration made with registerForNotification.
std::multimap< std::string, TreeNode * > ChildNameMapping
Mapping of names, aliases, and groups to individual child nodes within one node. This must be in a de...
Definition TreeNode.hpp:255
bool canGenerateNotification(const std::type_info &tinfo, const std::string *name) const
Can this TreeNode generate a notification of the given type having the given name or pattern.
std::weak_ptr< TreeNode > WeakPtr
Weak pointer to a TreeNode. Acquire with getWeakPtr.
Definition TreeNode.hpp:265
virtual void activateLink(const std::string &label)
Activate one of the links added with addLink.
TreeNode(TreeNode *parent, const std::string &group, group_idx_type group_idx, const std::string &desc)
TreeNode constructor for anonymous node with group information.
std::vector< std::string > AliasVector
Vector of aliases (other names for this node)
Definition TreeNode.hpp:247
void finalizeTree_()
Recursively create resources based on tree configuration. enter_finalize_ should be invoked after thi...
virtual uint32_t findImmediateChildren_(std::regex &expr, std::vector< TreeNode * > &found, std::vector< std::vector< std::string > > &replacements, bool allow_private=false)
Finds immediate children with some identity (name or alias) matching a regex.
WeakPtr getWeakPtr()
Gets a weak pointer to this TreeNode. This weak pointer is guaranteed to expire when this TreeNode is...
const ExtensionsBase * getExtension() const
Get an extension without needing to specify any particular extension name. If no extensions exist,...
static constexpr char LOCATION_NODE_SEPARATOR_UNATTACHED
Separator character preceding a node identifiers in a location string when that node has no parent an...
Definition TreeNode.hpp:354
TreeNode(const std::string &name, const std::string &group, group_idx_type group_idx, const std::string &desc)
TreeNode constructor with no parent Node.
static TreeNode * getVirtualGlobalNode()
Gets the virtual global node singleton. This node can have no parent and no children....
virtual void setClock(const Clock *clk)
Assigns a clock to this node. This clock will then be accessed by any descendant which has no assigne...
std::string getDisplayLocation() const
Returns the location of this node in the device tree which might not be usable for navigating the dev...
std::pair< uint32_t, std::string > recursGetDeepestMatchingPath_(const std::string &path, size_t name_pos) const
Finds the deepest node path mathing the input path. Implements getDeepestMatchingPath.
uint32_t locateNotificationSources(std::vector< TreeNode * > &nodes, const std::string &name="")
Gets all possible notification info from NotificationSources within this node's subtree.
void getDelegatesRegisteredForNotification(const std::type_info &tinfo, const std::string *name, std::vector< delegate > &dels) noexcept
Gets the vector of delegates registered for a notification on this TreeNode.
std::vector< const std::string * > getIdentifiers() const
Gets all the identifiers for this node (excluding groups)
bool isExpired() const
Is this expired (i.e. has it been the rhp of a move constructor)
virtual TreeNode * getParent()
Gets immediate parent of this node if one exists.
Definition TreeNode.hpp:964
bool isDescendantOf(const TreeNode *ancestor, int32_t max_depth=-1) const
Determines if this node is a descendant of the specified ancestor node within some number of generati...
void dumpDebugContent_(std::ostream &out) const noexcept
Allows resources to write out detailed textual debugging information about the node....
void lockdownParameters()
Method to put the device tree in lockdown phase. All LOCKED and HIDDEN parameters are frozen after th...
Definition TreeNode.hpp:429
static std::string createSearchRegexPattern(const std::string &pat)
Compute a regex pattern for a node child path containing any number of wildcard characters (not a dot...
group_idx_type getGroupIdx() const
Gets the group index of this node.
uint32_t getRecursiveNodeCount() const
Recursively gets the count of a nodes that are a subclass of a particular type (determined by dynamic...
const ConstT getChildAs(const std::string &name, bool must_exist=true) const
Retrieves a child that is castable to T with the given dotted path.
static bool identityMatchesPattern_(const std::string &ident, std::regex &expr, std::vector< std::string > &replacements)
Performs pattern matching on a identity string.
virtual std::string stringize(bool pretty=false) const
Create a string representation of this node.
Definition TreeNode.hpp:722
const T * getAs() const
Retrieves this node after casting to type const T.
std::vector< delegate > DelegateVector
Vector of delegates representing a list of observers to notify.
std::map< const std::string *, std::vector< TreeNode * > > TagsMap
Map of strings (interned in StringManager) tags to TreeNodes.
Definition TreeNode.hpp:280
std::map< type_info_container, DelegateVector > NotificationObserverMap
Map of delegate vectors containing all observers.
void stringizeTags(std::stringstream &ss) const
Render tags to a string in the form: " tags:[tag0, tag1]" If there are any tags. The leading space ma...
Definition TreeNode.hpp:742
const std::string & getName() const override
Gets the name of this node.
void enterConfig_() noexcept
Recursively enter TREE_CONFIGURING phase.
sparta::TreeNode * findAncestorByTag(const std::string &tag)
Find the first ancestor with a particular tag.
uint32_t getNumChildren() const
Gets the number of children that this node has including those in the sparta builtins group.
TreeNode * getChild(const std::string &name, bool must_exist=true)
Retrieves a child with this dotted path name.
Extension * replaceExtension(Args &&... args)
Replace an extension, specifying the ExtensionsBase subclass type. This api is similar to addExtensio...
void addTags(const std::vector< std::string > &v)
Adds each elements of a vector of tags to this node.
bool removeExtension(const std::string &extension_name)
Remove an extension by its name. Returns true if successful, false if the extension was not found.
bool hasExtensionOfType(const std::string &extension_name) const noexcept
Check if this tree node has an extension by the given name and type.
uint32_t getGroupSize(const std::string &group)
Gets the number of nodes in a group.
bool canGenerateNotification(const NotificationInfo &info) const
Can this TreeNode generate a notification of the given NotificationInfo.
uint32_t getChildrenOfType(std::vector< T * > &results) const
return all the children matching a particular type using dynamic cast.
void validateName(const std::string &nm)
Validates the given name string for this TreeNode. Does not consider context (e.g....
bool isHidden() const
Is this TreeNode supposed to be hidden during tree printouts This value does not have to be respected...
std::string getExpectedLocation() const
build-time equivalent to getLocation before an object is actually attached to a tree....
T getAs()
Retrieves this node after casting to type const T.
static std::string formatAllNodes()
Prints the list of all TreeNodes currently known to be constructed.
TreeNode * getScopeRoot()
void removeChildForTeardown_(TreeNode *child)
"Removes" the given child by invoking onDestroyingChild_ then removing this child from the children_ ...
bool hasImmediateChild(const TreeNode *n) const noexcept
Determines if the node n is an immediate child of this node.
void addAliases(const AliasVector &v)
Adds each element of a vector of aliases to this node..
static const uint64_t CHILD_FIND_THRESHOLD
Threshold for number of findChildren calls after finalization before a warning message is printed abo...
Definition TreeNode.hpp:391
void addTag(const std::string &tag)
Adds single tag to this node.
TreeNode(const std::string &name, const std::string &desc)
TreeNode constructor with no parent node or group information.
bool canSubtreeGenerateNotification(const std::type_info &tinfo, const std::string *name) const
Can this TreeNode or its descendants (of any distance) generate a notification of the given type havi...
std::set< std::string > getAllConfigExtensionNames() const
Get a list of extension names found for this node in all arch/config/extension files.
void bindTreeLate_()
Recursively invoke TreeNode::onBindTreeEarly_ and Resource::onBindTreeLate_ (in that order for each n...
uint32_t getChildrenIdentifiers(std::vector< std::string > &idents, bool ignore_builtin_group=true) const
Gets all child identifiers, aliases, group names, and group-aliases which can be used to refer to a c...
static bool isNodeConstructed(const TreeNode *)
Is a given node constructed?
virtual ~TreeNode()
Virtual destructor.
uint32_t findChildren(const std::string &pattern, std::vector< TreeNode * > &results, std::vector< std::vector< std::string > > &replacements)
Finds all children starting at this node with a given pattern relative to this node by matching names...
sparta::TreeNode * findAncestorByType()
Find ancestor by type.
T * getAs()
Retrieves this node after casting to type const T.
TreeNode & operator=(const TreeNode &)=delete
Not assign-constructable.
const std::string & getGroup() const
Gets the group name of this node.
bool isAnonymous() const
Is this node anonymous.
const Clock * getClock() override
Walks up parents (starting with self) until a parent with an associated local clock is found,...
void bindTreeEarly_()
Recursively invoke TreeNode::onBindTreeEarly_ and Resource::onBindTreeEarly_ (in that order for each ...
T * findAncestorResourceByType()
Find an ancestor's resource with a certain type.
void setExpectedParent_(const TreeNode *parent)
Tracks a node as an expected parent without actually adding this node as a child. This is used almost...
uint32_t findImmediateChildren_(std::regex &expr, std::vector< const TreeNode * > &found, bool allow_private=false) const
Variant of const-qualified findImmediateChildren_ with no replacements vector.
void makeSubtreePrivate()
Make the entire subtree private.
ExtensionT * getExtensionAs(const std::string &extension_name)
Get an extension, downcast to the given type.
std::vector< TreeNode * > ChildrenVector
Vector of TreeNode children.
Definition TreeNode.hpp:242
uint32_t getPossibleNotifications(std::vector< NotificationInfo > &infos) const
Gets information on the possible notifications generated by this node (excludes children).
ConstWeakPtr getWeakPtr() const
Const variant of getWeakPtr.
uint64_t node_uid_type
Type of unique-identifier assigned to every node.
Definition TreeNode.hpp:237
void removeFromParentForTeardown_(TreeNode *parent)
Protected Wrapper for getParent()->removeChildForTeardown_ which allows subclases of TreeNode to indi...
bool locationMatchesPattern(const std::string &pattern, const TreeNode *pat_loc) const
Determines if the given pattern (which may contain wildcards) can describe this node.
ExtensionsBase * createExtension(bool replace=false)
Create an extension on demand without needing to specify any particular extension name....
void dumpLocatedNotificationSources(std::ostream &o, const std::string &name="")
Retrieves the relevant NotificationSources from locateNotificationSources and prints them to the outp...
std::set< std::string > getAllInstantiatedExtensionNames() const
Get a list of extension names for all instantiated extensions on this TreeNode.
std::weak_ptr< const TreeNode > ConstWeakPtr
Weak pointer to a const TreeNode. Acquire with getWeakPtr.
Definition TreeNode.hpp:270
static bool identityMatchesPattern_(const std::string &ident, std::regex &expr)
Variant of identityMatchesPattern_ with no replacements vector.
const ExtensionT * getExtensionAs(const std::string &extension_name) const
Get an extension, downcast to the given type.
bool hasChild(const std::string &name) const noexcept
Determines if a child can be found with the given dotted path.
Virtual global node for all device trees in a single simulation. This node acts a potential notificat...
Simulator which builds a sparta DeviceTree.
Macros for handling exponential backoff.
std::ostream & operator<<(std::ostream &o, const SimulationInfo &info)
ostream insertion operator for SimulationInfo
std::string demangle(const std::string &name) noexcept
Demangles a C++ symbol.
Definition Utils.hpp:214
Type for indicating that ANY notification source type should be included in a search performed by loc...
Definition TreeNode.hpp:289
Notification type/name information.
const TreeNode * origin
TreeNode from which this notification can be generated.
NotificationInfo(const NotificationInfo &rhp)
Copy constructor.
void checkValid() const
Ensures the node contains valid data.
NotificationInfo(const NotificationInfo &&rhp)
Move constructor.
const std::string * name
String interned by StringManager. Must not be nullptr.
NotificationInfo & operator=(const NotificationInfo &rhp)
Assignment operator.
const std::type_info * tinfo
Type from typeid() on notification DataT.
NotificationInfo(const TreeNode *_origin, const std::type_info *_tinfo, const std::string *_name)
Basic constructor.