25 #ifndef INCLUDED_TreeNode_h_GUID_EEC6C5AF_332A_4780_55C2_D794B3BF5106
26 #define INCLUDED_TreeNode_h_GUID_EEC6C5AF_332A_4780_55C2_D794B3BF5106
32 #include <boost/noncopyable.hpp>
33 #include <boost/operators.hpp>
34 #include <boost/assert.hpp>
48 struct NoSuchChild : std::runtime_error {
49 NoSuchChild(std::string
const &name)
50 : std::runtime_error(
"No child found with the name " + name) {}
71 template <
typename ValueType>
73 boost::operators<TreeNode<ValueType> > {
98 value_type
const &val);
104 static ptr_type
createRoot(value_type
const &val);
116 std::string
const &
getName()
const;
134 value_type &
value() {
return m_value; }
137 value_type
const &
value()
const {
return m_value; }
142 typedef typename ChildList::size_type size_type;
143 for (size_type i = 0; i < m_children.size(); ++i) {
146 visitor(*(m_children[i]));
153 for (
auto const &node : m_children) {
154 visitor(const_cast<type const &>(*node));
170 typedef type *weak_ptr_type;
173 TreeNode(type &parent, std::string
const &name);
176 TreeNode(type &parent, std::string
const &name,
177 value_type
const &val);
183 explicit TreeNode(value_type
const &val);
187 weak_ptr_type m_getChildByName(std::string
const &name)
const;
191 void m_addChild(ptr_type
const &child);
196 typedef std::vector<ptr_type> ChildList;
198 ChildList m_children;
201 std::string
const m_name;
204 parent_ptr_type m_parent;
207 template <
typename ValueType>
208 inline TreeNode<ValueType> &
210 std::string
const &name) {
211 if (parent.m_getChildByName(name)) {
212 throw std::logic_error(
213 "Can't create a child with the same name as "
214 "an existing child!");
217 parent.m_addChild(ret);
221 template <
typename ValueType>
224 std::string
const &name,
225 ValueType
const &val) {
226 if (parent.m_getChildByName(name)) {
227 throw std::logic_error(
228 "Can't create a child with the same name as "
229 "an existing child!");
232 parent.m_addChild(ret);
236 template <
typename ValueType>
243 template <
typename ValueType>
250 template <
typename ValueType>
254 if (child !=
nullptr) {
260 template <
typename ValueType>
264 if (child !=
nullptr) {
267 throw NoSuchChild(name);
270 template <
typename ValueType>
275 template <
typename ValueType>
278 (getParent() ==
nullptr) == m_name.empty(),
279 "The root and only the root should have an empty name "
281 return getParent() ==
nullptr;
284 template <
typename ValueType>
290 template <
typename ValueType>
292 return !m_children.empty();
295 template <
typename ValueType>
297 BOOST_ASSERT_MSG((m_children.size() != 0) == hasChildren(),
298 "hasChildren should return true iff size != 0!");
299 return m_children.size();
302 template <
typename ValueType>
307 auto it = std::find_if(
308 begin(m_children), end(m_children),
309 [&](ptr_type
const &n) {
return n->getName() == name; });
310 weak_ptr_type ret =
nullptr;
311 if (it != end(m_children)) {
317 template <
typename ValueType>
318 inline void TreeNode<ValueType>::m_addChild(
319 typename TreeNode<ValueType>::ptr_type
const &child) {
320 m_children.push_back(child);
323 template <
typename ValueType>
324 inline TreeNode<ValueType>::TreeNode(TreeNode<ValueType> &parent,
325 std::string
const &name)
326 : m_value(), m_children(), m_name(name), m_parent(&parent) {
327 if (m_name.empty()) {
328 throw std::logic_error(
329 "Can't create a named tree node with an empty name!");
333 template <
typename ValueType>
334 inline TreeNode<ValueType>::TreeNode(TreeNode<ValueType> &parent,
335 std::string
const &name,
336 ValueType
const &val)
337 : m_value(val), m_children(), m_name(name), m_parent(&parent) {
338 if (m_name.empty()) {
339 throw std::logic_error(
340 "Can't create a named tree node with an empty name!");
344 template <
typename ValueType>
345 inline TreeNode<ValueType>::TreeNode()
346 : m_value(), m_children(), m_name(), m_parent(nullptr) {
350 template <
typename ValueType>
351 inline TreeNode<ValueType>::TreeNode(ValueType
const &val)
352 : m_value(val), m_children(), m_name(), m_parent(nullptr) {
360 #endif // INCLUDED_TreeNode_h_GUID_EEC6C5AF_332A_4780_55C2_D794B3BF5106
type * parent_ptr_type
The pointer for accessing a node's parent. Does not confer ownership.
void visitConstChildren(F &visitor) const
Generic constant visitation method that calls a functor on each of the children (as const) in an unde...
bool hasChildren() const
Does the node have any children?
std::string const & getName() const
Gets the name of the current node. This will be empty if and only if this is the root.
bool operator==(const type &x) const
Equality comparison operator - tests object identity.
TreeNode< ValueType > type
This template instantiation's type.
A node in a generic tree, which can contain an object by value.
ValueType value_type
The contained value type.
The main namespace for all C++ elements of the framework, internal and external.
shared_ptr< TreeNode< ValueType > > type
Tree node pointer type (metafunction result type)
value_type & value()
Reference accessor for contained value.
bool isRoot() const
Is the current node a root node?
size_t numChildren() const
How many children does the node have?
TreeNodePointer< ValueType >::type ptr_type
The pointer for holding this template instantiation - used primarily/only in holding the root node...
type & getOrCreateChildByName(std::string const &name)
Get the named child, creating it if it doesn't exist.
value_type const & value() const
Const reference accessor for contained value.
void visitChildren(F &visitor)
Generic visitation method that calls a functor on each of the children in an undefined order...
parent_ptr_type getParent() const
Gets the node's parent, or nullptr if no parent (root node)
static type & create(TreeNode &parent, std::string const &name)
Create a child tree node.
void visitChildren(F &visitor) const
Generic constant visitation method that calls a functor on each of the children in an undefined order...
static ptr_type createRoot()
Create a root.
type const & getChildByName(std::string const &name) const
Get the named child, throwing NoSuchChild if it doesn't exist.