13#include <boost/algorithm/string.hpp>
15#include "sparta/utils/Utils.hpp"
72 Node* parent_ =
nullptr;
79 uint32_t write_count_;
80 mutable uint32_t read_count_ = 0;
81 std::map<std::string, std::any> user_data_;
84 class UserDataPrinterBase
87 virtual ~UserDataPrinterBase() =
default;
88 virtual void print(
const std::string& name, std::any user_data, std::ostream& o, uint32_t indent)
const = 0;
93 class UserDataPrinter :
public UserDataPrinterBase
96 void print(
const std::string& name, std::any user_data, std::ostream& o, uint32_t indent)
const override
98 const T& ud = std::any_cast<const T&>(user_data);
99 for (uint32_t i = 0; i < indent; ++i) {
103 print_(o, ud, indent);
108 template <
typename Value>
109 typename std::enable_if<MetaStruct::is_any_pointer<Value>::value,
void>::type
110 print_(std::ostream& o,
const Value& val, uint32_t indent)
const {
115 print_(o, *val, indent);
119 template <
typename Value>
120 typename std::enable_if<!MetaStruct::is_any_pointer<Value>::value,
void>::type
121 print_(std::ostream& o,
const Value& val, uint32_t indent)
const {
122 if constexpr (std::is_same_v<Value, TreeNode::ExtensionsBase>) {
123 if (
auto ps = val.getParameters()) {
124 o << val.getClassName() <<
" extension with parameters:\n";
125 const std::string s = ps->dumpList();
126 std::vector<std::string> lines;
127 boost::split(lines, s, boost::is_any_of(
"\n"));
128 for (
auto & line : lines) {
129 for (uint32_t i = 0; i < indent+2; ++i) {
135 o <<
"extension without parameters";
137 }
else if constexpr (std::is_same_v<Value, bool>) {
138 o << std::boolalpha << val << std::dec;
146 std::unordered_map<std::string, std::unique_ptr<UserDataPrinterBase>> user_data_printers_;
152 uint32_t required_ = 0;
161 Node(
Node* parent,
const std::string& name,
162 const std::string& value,
const std::string& origin) :
205 has_value_(n.has_value_),
206 write_count_(n.write_count_),
207 read_count_(n.read_count_)
209 for(
auto& x : n.children_){
210 children_.emplace_back(new Node(this, *x.get()));
225 has_value_ = n.has_value_;
226 write_count_ =
static_cast<decltype(write_count_)
>(has_value_);
228 for(
auto& x : n.children_){
229 children_.emplace_back(new Node(this, *x.get()));
239 void dump(std::ostream& o)
const {
240 o <<
"<VPT Node: \"" << name_ <<
"\" children:" << children_.size()
241 <<
" writes:" << write_count_ <<
" reads:" << read_count_ <<
" required:" << required_ <<
">";
247 const std::string&
getName()
const {
return name_; }
275 Node const * p =
this;
301 std::stack<const std::string*> names;
302 Node const * n =
this;
303 while(n && n->
getName().size() > 0){
308 std::stringstream ss;
309 if(names.size() > 0){
312 while(names.size() > 0){
313 ss <<
'.' << *names.top();
324 return name_.size() == 0;
391 template <typename T, typename=typename std::enable_if<!std::is_convertible<T, std::string>::value>::type>
399 template <typename T, typename=typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
407 operator std::string ()
const {
415 template <
typename T>
416 operator T ()
const {
424 template <
typename T>
438 static bool matches(
const std::string& pattern,
const std::string& other) {
441 return std::regex_match(other, what, expr);
453 throw SpartaException(
"Cannot call ParameterTree::Node::getChild with a name that is a search pattern: \"")
454 << name <<
"\". addChild must be used instead";
458 auto itr = children_.rbegin();
459 for(; itr != children_.rend(); ++itr){
460 if(
matches((*itr)->getName(), name)){
479 if(path.size() == 0){
484 std::string immediate_child_name;
486 if(immediate_child_name.size() == 0){
500 child =
addChild(immediate_child_name, required);
503 if(name_pos == std::string::npos){
507 const std::string remainder = path.substr(name_pos);
508 return child->
create(remainder, required);
520 if(children_.size() == 0){
541 auto itr = children_.rbegin();
542 for(; itr != children_.rend(); ++itr){
543 if((*itr)->getName() == name){
549 if(name_has_wildcard){
555 }
else if(
matches(name, (*itr)->getName())){
566 }
else if(
matches((*itr)->getName(), name)){
582 "Cannot add a child to a virtual parameter tree node \"" << name_
583 <<
"\" since it already has a value: \"" << value_ <<
"\"");
585 children_.emplace_back(
new Node(
this, name));
587 children_.back()->incRequired();
589 return (children_.back().get());
602 "Node \"" << name_ <<
"\" has no child named \"" << name <<
"\"");
628 void setValue(
const std::string& val,
bool required=
true,
const std::string& origin=
"") {
655 for(
auto & n : children_){
666 return parent_->release_(
this);
682 bool set(
const std::string& path,
const std::string& val,
bool required,
const std::string& origin=
"") {
688 std::string full_path =
getPath();
689 if(full_path.size() > 0 && path.size() > 0){
693 return getOwner()->
set(full_path, val, required, origin);
734 std::vector<Node*> children;
735 for(
auto & n : children_){
736 children.push_back(n.get());
745 std::vector<const Node*> children;
746 for(
auto & n : children_){
747 children.push_back(n.get());
756 const std::string & name,
757 std::vector<Node*> & matching_nodes)
760 matching_nodes.emplace_back(
this);
766 child->recursFindPTreeNodesNamed(name, matching_nodes);
774 const std::string & name,
775 std::vector<const Node*> & matching_nodes)
const
778 matching_nodes.emplace_back(
this);
784 child->recursFindPTreeNodesNamed(name, matching_nodes);
795 template <
typename Callback>
798 recurseVisitNodes_(callback, count);
809 template <
typename Callback>
812 recurseVisitNodes_(callback, count);
823 template <
typename Callback>
826 recurseVisitLeaves_(callback, count);
837 template <
typename Callback>
840 recurseVisitLeaves_(callback, count);
847 void recursePrint(std::ostream& o, uint32_t indent=0,
bool print_user_data=
true)
const {
848 for(uint32_t i=0; i<indent; ++i){
853 o <<
" = \"" << value_ <<
"\" (read " << read_count_ <<
", written " << write_count_
854 <<
", required " << required_ <<
", origin '" <<
getOrigin() <<
"')";
860 for(
auto & n : children_){
861 n->recursePrint(o, indent+2, print_user_data);
869 if (user_data_.empty()) {
873 for(uint32_t i=0; i<indent; ++i){
877 o <<
"User data (" <<
getPath() <<
"):\n";
878 for (
const auto & [ud_name, ud_printer] : user_data_printers_) {
879 std::any ud = user_data_.at(ud_name);
880 ud_printer->print(ud_name, ud, o, indent+2);
897 sparta_assert(ot,
"Cannot append a null virtual parameter tree");
900 const bool required =
false;
902 child->recursAppendTree_(ot);
905 recursAppendTree_(ot);
913 template <
typename T>
915 static_assert(std::is_copy_constructible<T>::value,
"std::any only works with copyable types");
916 user_data_[name] = user_data;
917 user_data_printers_[name] = std::make_unique<UserDataPrinter<T>>();
924 template <
typename T>
926 static_assert(std::is_copy_constructible<T>::value,
"std::any only works with copyable types");
927 user_data_[name] = std::move(user_data);
928 user_data_printers_[name] = std::make_unique<UserDataPrinter<T>>();
934 template <
typename T>
936 constexpr bool must_exist =
true;
943 template <
typename T>
945 constexpr bool must_exist =
true;
952 template <
typename T>
953 const T *
tryGetUserData(
const std::string & name,
bool must_exist =
false)
const {
954 auto it = user_data_.find(name);
955 if (it == user_data_.end()) {
957 throw SpartaException(
"User data '") << name <<
"' does not exist for node '"
962 return &std::any_cast<const T&>(it->second);
968 template <
typename T>
970 auto it = user_data_.find(name);
971 if (it == user_data_.end()) {
973 throw SpartaException(
"User data '") << name <<
"' does not exist for node '"
978 return &std::any_cast<T&>(it->second);
985 std::map<
const Node*, std::map<std::string, const TreeNode::ExtensionsBase*>> & map)
const
988 if (
auto ext =
tryGetUserData<std::shared_ptr<TreeNode::ExtensionsBase>>(key)) {
989 map[
this][key] = ext->get();
994 child->recurseGetAllNodeExtensions(map);
1002 std::set<std::string> keys;
1003 for (
const auto & [key, _] : user_data_) {
1013 user_data_printers_.erase(name);
1014 if (user_data_.count(name)) {
1015 user_data_.erase(name);
1025 user_data_printers_.clear();
1026 auto sz = user_data_.size();
1036 ChildVector::const_reverse_iterator itr_;
1047 return itr_ == rhp.itr_;
1051 return itr_ != rhp.itr_;
1054 void operator++(
int) {++itr_;}
1056 void operator++() {++itr_;}
1058 bool matches(
const std::string& other)
const {
1062 const Node* get()
const {
1070 const Node* operator->()
const {
1093 void recursAppendTree_(
const Node* ot) {
1100 for(
const auto & [ud_name, ud_value] : ot->user_data_){
1101 user_data_[ud_name] = ud_value;
1106 Node* c =
create(child->getName(), child->getRequiredCount() > 0);
1107 c->recursAppendTree_(child);
1111 template <
typename Callback>
1112 bool recurseVisitNodes_(Callback callback,
size_t & count) {
1114 auto keep_going = callback(
this);
1118 for (
auto & child : children_) {
1119 if (!child->recurseVisitNodes_(callback, count)) {
1126 template <
typename Callback>
1127 bool recurseVisitNodes_(Callback callback,
size_t & count)
const {
1129 auto keep_going = callback(
this);
1133 for (
const auto & child : children_) {
1134 if (!child->recurseVisitNodes_(callback, count)) {
1141 template <
typename Callback>
1142 bool recurseVisitLeaves_(Callback callback,
size_t & count) {
1143 if (children_.empty()) {
1145 auto keep_going = callback(
this);
1151 for (
auto & child : children_) {
1152 if (!child->recurseVisitLeaves_(callback, count)) {
1159 template <
typename Callback>
1160 bool recurseVisitLeaves_(Callback callback,
size_t & count)
const {
1161 if (children_.empty()) {
1163 auto keep_going = callback(
this);
1169 for (
const auto & child : children_) {
1170 if (!child->recurseVisitLeaves_(callback, count)) {
1177 std::unique_ptr<Node> release_(
Node *node) {
1178 std::unique_ptr<Node> rtn;
1179 auto it = std::find_if(children_.begin(), children_.end(),
1180 [node] (
const auto & child) ->
bool {
1181 return (child.get() == node);
1183 if (it != children_.end()) {
1184 rtn = std::move(*it);
1185 children_.erase(it);
1195 root_(new
Node(nullptr, this))
1199 root_(new Node(nullptr, this))
1201 root_->appendTree(rhp.getRoot());
1222 root_.reset(
new Node(
nullptr,
this));
1239 bool set(
const std::string& path,
const std::string& value,
bool required,
const std::string& origin=
"") {
1244 n->
setValue(value, required, origin);
1264 if(path.size() == 0){
1268 return getRoot()->
create(path, required);
1285 throw SpartaException(
"Unable to find parameter in tree: \"") << path <<
"\"";
1304 bool hasValue(
const std::string& path,
const bool must_be_leaf =
true)
const {
1305 const Node* n = tryGet_(path, must_be_leaf);
1306 return n !=
nullptr && n->
hasValue();
1315 bool exists(
const std::string& path,
const bool must_be_leaf =
true)
const {
1316 return tryGet_(path, must_be_leaf) !=
nullptr;
1331 return recursCountUnreadValueNodes_<const Node>(root_.get(), nodes);
1346 return recursCountUnreadValueNodes_<Node>(root_.get(), nodes);
1354 const Node*
tryGet(
const std::string& path,
const bool must_be_leaf =
true)
const {
1355 return tryGet_(path, must_be_leaf);
1363 Node*
tryGet(
const std::string& path,
const bool must_be_leaf =
true) {
1364 return tryGet_(path, must_be_leaf);
1374 if(path.size() == 0){
1375 return root_->getRequiredCount() > 0;
1378 std::string immediate_child_name;
1379 size_t name_pos = 0;
1382 if(immediate_child_name.size() == 0){
1385 <<
" is invalid because it contains an empty name (between two '.' "
1386 "characters). Parents cannot currently be refrenced in the parameter tree";
1389 bool match_found =
false;
1390 const bool required = recursGetIsRequired_(root_.get(), path, immediate_child_name, name_pos, match_found);
1392 "Asked ParameterTree if path \"" << path <<
"\" is required but no "
1393 "matching node was found in the ParameterTree");
1403 Node * node = tryGet_(path,
false);
1404 if(
nullptr != node) {
1420 if(path.size() == 0){
1421 return root_->hasValue() && root_->getReadCount() > 0;
1424 std::string immediate_child_name;
1425 size_t name_pos = 0;
1428 if(immediate_child_name.size() == 0){
1431 <<
" is invalid because it contains an empty name (between two '.' "
1432 "characters). Parents cannot currently be refrenced in the parameter tree";
1435 return recursIsRead_(root_.get(), path, immediate_child_name, name_pos);
1438 Node
const * getRoot()
const {
return root_.get(); }
1440 Node * getRoot() {
return root_.get(); }
1450 root_->appendTree(rhp.getRoot());
1460 template <
typename Callback>
1462 return root_->recurseVisitNodes(callback);
1472 template <
typename Callback>
1474 return root_->recurseVisitNodes(callback);
1484 template <
typename Callback>
1486 return root_->recurseVisitLeaves(callback);
1496 template <
typename Callback>
1498 return root_->recurseVisitLeaves(callback);
1505 root_->recursePrint(o, 0, print_user_data);
1511 std::map<const Node*, std::map<std::string, const TreeNode::ExtensionsBase*>>
1514 std::map<const Node*, std::map<std::string, const TreeNode::ExtensionsBase*>> all_ext_map;
1515 root_->recurseGetAllNodeExtensions(all_ext_map);
1525 const Node* tryGet_(
const std::string& path,
const bool must_be_leaf =
true)
const {
1526 if(path.size() == 0){
1530 std::string immediate_child_name;
1531 size_t name_pos = 0;
1534 if(immediate_child_name.size() == 0){
1536 throw SpartaException(
"Parameter ") << path
1537 <<
" is invalid because it contains an empty name (between two '.' "
1538 "characters). Parents cannot currently be refrenced in the parameter tree";
1541 return recursTryGet_<const Node>(
static_cast<const Node*
>(root_.get()), path,
1542 immediate_child_name, name_pos, must_be_leaf);
1549 Node* tryGet_(
const std::string& path,
const bool must_be_leaf =
true) {
1550 if(path.size() == 0){
1554 std::string immediate_child_name;
1555 size_t name_pos = 0;
1558 if(immediate_child_name.size() == 0){
1560 throw SpartaException(
"Parameter ") << path
1561 <<
" is invalid because it contains an empty name (between two '.' "
1562 "characters). Parents cannot currently be refrenced in the parameter tree";
1565 return recursTryGet_(root_.get(), path,
1566 immediate_child_name, name_pos, must_be_leaf);
1569 template<
typename NodeT>
1570 static NodeT* recursTryGet_(NodeT* node,
const std::string& path,
1571 const std::string& match_name,
1572 size_t name_pos,
const bool must_be_leaf)
1575 "Cannot attempt to read a node with a path containing wildcard "
1576 "characters. A specific node path must be used. Error in \""
1577 << match_name <<
"\" from \"" << path <<
"\"");
1579 if(name_pos == std::string::npos){
1581 NodeT* result =
nullptr;
1582 NodeT* backup =
nullptr;
1583 auto itr = node->getMatcherBegin();
1584 for(; itr != node->getMatcherEnd(); ++itr){
1585 if(itr.matches(match_name)){
1586 if(itr.get()->hasValue() || !must_be_leaf){
1587 itr.get()->incrementReadCount();
1603 std::string immediate_child_name;
1606 if(immediate_child_name.size() == 0){
1608 throw SpartaException(
"Parameter ") << path
1609 <<
" is invalid because it contains an empty name (between two '.' "
1610 "characters). Parents cannot currently be refrenced in the parameter tree";
1613 NodeT* result =
nullptr;
1614 auto itr = node->getMatcherBegin();
1615 for(; itr != node->getMatcherEnd(); ++itr){
1616 if(itr.matches(match_name)){
1617 NodeT* match = recursTryGet_(itr.get(), path, immediate_child_name, name_pos, must_be_leaf);
1618 if(match && (match->hasValue() || !must_be_leaf)) {
1619 match->incrementReadCount();
1620 if(result ==
nullptr){
1633 bool recursGetIsRequired_(
const Node* node,
1634 const std::string& path,
1635 const std::string& match_name,
1637 bool& found_match)
const
1639 found_match =
false;
1641 if(name_pos == std::string::npos){
1643 auto itr = node->getMatcherBegin();
1644 for(; itr != node->getMatcherEnd(); ++itr){
1646 ? itr->getName() == match_name
1647 : itr.matches(match_name))
1650 return itr.get()->getRequiredCount() > 0;
1658 std::string immediate_child_name;
1661 if(immediate_child_name.size() == 0){
1663 throw SpartaException(
"Parameter ") << path
1664 <<
" is invalid because it contains an empty name (between two '.' "
1665 "characters). Parents cannot currently be refrenced in the parameter tree";
1668 auto itr = node->getMatcherBegin();
1669 for(; itr != node->getMatcherEnd(); ++itr){
1670 if(itr.matches(match_name)){
1671 const bool required = recursGetIsRequired_(itr.get(), path, immediate_child_name, name_pos, found_match);
1686 template<
class NodeT>
1687 static uint32_t recursCountUnreadValueNodes_(NodeT* n, std::vector<NodeT*> * nodes) {
1689 if(n->hasValue() && (n->getReadCount() == 0)){
1692 nodes->push_back(n);
1695 auto itr = n->getMatcherBegin();
1696 for(; itr != n->getMatcherEnd(); ++itr){
1697 count += recursCountUnreadValueNodes_<NodeT>(itr.get(), nodes);
1705 bool recursIsRead_(
const Node* node,
1706 const std::string& path,
1707 const std::string& match_name,
1708 size_t name_pos)
const
1711 "Cannot attempt to read a node with a path containing wildcard "
1712 "characters. A specific node path must be used. Error in \""
1713 << match_name <<
"\" from \"" << path <<
"\"");
1715 if(name_pos == std::string::npos){
1716 auto itr = node->getMatcherBegin();
1717 for(; itr != node->getMatcherEnd(); ++itr){
1718 if(itr.matches(match_name)){
1719 if(itr.get()->hasValue() && itr.get()->getReadCount() > 0){
1728 std::string immediate_child_name;
1730 if(immediate_child_name.size() == 0){
1732 throw SpartaException(
"Parameter ") << path
1733 <<
" is invalid because it contains an empty name (between two '.' "
1734 "characters). Parents cannot currently be refrenced in the parameter tree";
1737 auto itr = node->getMatcherBegin();
1738 for(; itr != node->getMatcherEnd(); ++itr){
1739 if(itr.matches(match_name)){
1740 bool read = recursIsRead_(itr.get(), path, immediate_child_name, name_pos);
1752 std::unique_ptr<Node> root_;
1756 inline std::ostream&
operator<<(std::ostream& o,
const ParameterTree::Node& n) {
1761 inline std::ostream&
operator<<(std::ostream& o,
const ParameterTree::Node* n) {
1763 o <<
"<null ParameterTree::Node>";
String-to-value helpers and string formatting helpers.
Individual Parameter interface base class, container class, and global helpers methods.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Basic Node framework in sparta device tree composite pattern.
Node containing a Parameter and value to apply. Can be used to describes a value extracted from the t...
const std::string & peekValue() const
Gets the value of this object as a string.
Node(Node *parent, const std::string &name)
Value-less constructor.
uint32_t getReadCount() const
Gets the number of times this node has been accessed to be read (i.e. with get/tryGet)
const std::string & getValue() const
Gets the value of this object as a string.
std::unique_ptr< Node > release()
Release this node and its children from the tree.
size_t recurseVisitNodes(Callback callback) const
Apply the given callback to all nodes.
T getAs() const
Gets the value in this object.
Node * getPriorityChildMatch(const std::string &name) const
Attempts to get an immediate child with an exact match for a given name or pattern string....
std::string getPath() const
Gets the path to this node including the root node.
Node(Node *parent, ParameterTree *tree)
Root node constructor. Constructs node pointing to a new tree having no name. Normal nodes to not hav...
void setUserData(const std::string &name, const T &user_data)
Set any named user data (std::any)
MatchIterator getMatcherBegin() const
Get most recent child added.
static bool matches(const std::string &pattern, const std::string &other)
Does a string, name, interpreted as a sparta TreeNode pattern, match another string interpreted as a ...
std::set< std::string > getUserDataKeys() const
Get all user data keys (names).
Node()=delete
Not default-constructable.
Node * getRoot()
Gets the parent of this node.
void recursFindPTreeNodesNamed(const std::string &name, std::vector< const Node * > &matching_nodes) const
Recursively find all nodes that have a given name.
size_t recurseVisitLeaves(Callback callback) const
Apply the given callback to all leaf nodes.
Node * addChild(const std::string &name, bool required)
void incrementReadCount() const
Increment the read count of this node.
bool operator==(const T &rhp) const
Equality test. Attempts to lexically cast underlying string to requested data-type.
T & getUserData(const std::string &name)
Get any named user data (std::any_cast)
bool isRoot() const
Is this a root node.
size_t clearUserData()
Clear all user data. Returns the number of elements removed.
void resetReadCount() const
Reset the read count back to zero.
Node * create(const std::string &path, bool required)
Get a child for setting a parameter, creating it if needed.
Node & operator[](const std::string &name) const
Gets a child of this node by its name.
Node * getChild(const std::string &name) const
Gets the most recently created child of this node by a concrete child name.
const std::string & getAs() const
getAs template instance for string types (e.g. char[], const char*, std::string)
bool hasValue() const
Does this node have a value written to it which can be accessed through:
const std::string & getName() const
Gets the name of this node.
std::vector< const Node * > getChildren() const
Gets vector of pointers to children of this node.
void dump(std::ostream &o) const
Dumps the content of this node to an ostream on a single line. Does not recurs into children.
ParameterTree * getOwner()
Gets the ParameterTree object that owns this node.
const T * tryGetUserData(const std::string &name, bool must_exist=false) const
Try to get any named user data (std::any_cast)
Node const * getParent() const
Gets the parent of this node.
void recursePrint(std::ostream &o, uint32_t indent=0, bool print_user_data=true) const
Recursively print.
void incRequired()
Increment the required count.
T * tryGetUserData(const std::string &name, bool must_exist=false)
Try to get any named user data (std::any_cast)
bool isRequired() const
Return true if this parameter node is required to exist by the client by 1 or more "set"-ers using th...
std::vector< std::unique_ptr< Node > > ChildVector
Vector of children owned by this node.
std::vector< Node * > getChildren()
Gets vector of pointers to children of this node.
size_t recurseVisitLeaves(Callback callback)
Apply the given callback to all leaf nodes.
bool set(const std::string &path, const std::string &val, bool required, const std::string &origin="")
Set the string value of a child of this node. Note that this may not affect this node directly becaus...
void appendTree(const Node *ot)
Appends a tree as a child of this node.
const std::string & getOrigin() const
Gets the origin associated with the value at this node.
void setUserData(const std::string &name, T &&user_data)
Set any named user data (std::any)
void setValue(const std::string &val, bool required=true, const std::string &origin="")
Set a value on this node directly.
Node * getParent()
Gets the parent of this node.
uint32_t getRequiredCount() const
Returns the number of times this node has been flagged as required.
size_t recurseVisitNodes(Callback callback)
Apply the given callback to all nodes.
void recurseGetAllNodeExtensions(std::map< const Node *, std::map< std::string, const TreeNode::ExtensionsBase * > > &map) const
Get a mapping from Nodes to their extensions recursively.
void printUserData(std::ostream &o, uint32_t indent=0) const
Pretty-print all user data for this node, if any.
Node const * getRoot() const
Gets the parent of this node.
MatchIterator getMatcherEnd() const
Get end of child match iterator (past oldest child added)
bool clearUserData(const std::string &name)
Clear named user data. Returns true if removed, false if not found.
Node & operator=(const Node &n)
Parent-preserving deep-copy assignment operator.
const T & getUserData(const std::string &name) const
Get any named user data (std::any_cast)
void unrequire()
Clear the required count. This is necessary if a parameter is flagged as deprecated or removed in a c...
void recursFindPTreeNodesNamed(const std::string &name, std::vector< Node * > &matching_nodes)
Recursively find all nodes that have a given name.
Node(Node *parent, const Node &n)
Deep-Copy constructor.
const ParameterTree * getOwner() const
Gets the ParameterTree object that owns this node.
Virtual Parameter Tree. This represents a tree of parameters read from some source but does not neces...
Node * create(const std::string &path, bool required=false)
Add a node to the tree, with proper priority.
size_t visitNodes(Callback callback)
Apply the given callback to all nodes.
bool set(const std::string &path, const std::string &value, bool required, const std::string &origin="")
Add a parameter to the tree, replacing any existing parameter.
const Node * tryGet(const std::string &path, const bool must_be_leaf=true) const
Try to get a node if it exists. Returns nullptr it it does not.
size_t visitNodes(Callback callback) const
Apply the given callback to all nodes.
size_t visitLeaves(Callback callback) const
Apply the given callback to all leaf nodes.
bool exists(const std::string &path, const bool must_be_leaf=true) const
Try to check if a node exists.
Node * tryGet(const std::string &path, const bool must_be_leaf=true)
tryGet non-const version
bool unrequire(const std::string &path)
Unrequire a node in the tree.
bool hasValue(const std::string &path, const bool must_be_leaf=true) const
Try to check if a node has value.
uint32_t getUnreadValueNodes(std::vector< Node * > *nodes)
Counts the number of values attached to the parameter tree which have values but have not been read....
virtual ~ParameterTree()
Destructor.
void recursePrint(std::ostream &o, bool print_user_data=true) const
Recursively print.
bool isRequired(const std::string &path) const
Recursively find first leaf node matching this pattern and decide if any node matching that node's pa...
ParameterTree()
Default Constructor.
void clear()
Clear all content from this tree.
uint32_t getUnreadValueNodes(std::vector< const Node * > *nodes) const
Counts the number of values attached to the parameter tree which have values but have not been read....
bool isRead(const std::string &path) const
Has a node with a given path been read.
const Node & operator[](const std::string &name) const
Gets a node form the parameter tree.
const Node & get(const std::string &path) const
Gets a node from the parameter tree while respecting parameter application order. In other words,...
void merge(const ParameterTree &rhp)
Merge this tree with another by applying all of its parameters to this tree. Parameters in the right ...
size_t visitLeaves(Callback callback)
Apply the given callback to all leaf nodes.
std::map< const Node *, std::map< std::string, const TreeNode::ExtensionsBase * > > getAllNodeExtensions() const
Get a mapping from Nodes to their extensions.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
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 bool hasWildcardCharacters(const std::string &name)
Determines if a given node name has any wildcard characters which will be substituted in createSearch...
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...
Macros for handling exponential backoff.
T lexicalCast(const std::string &str, uint32_t base=10)
std::ostream & operator<<(std::ostream &o, const SimulationInfo &info)
ostream insertion operator for SimulationInfo