Honeycomb  0.1
Component-Model Framework
Tree.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/String/Id.h"
7 
8 namespace honey
9 {
10 
12 
16 template<class Data_, class Key_ = Id, template<class> class Alloc = SmallAllocator>
17 class TreeNode
18 {
19  template<class, class, template<class> class> friend class TreeNode;
20 public:
21  typedef Data_ Data;
22  typedef Key_ Key;
23 
25  typedef list<deref_wrap<TreeNode>, Alloc<deref_wrap<TreeNode>>> ChildList;
26  typedef typename ChildList::iterator ChildIter;
27  typedef typename ChildList::const_iterator ChildConstIter;
28  typedef typename ChildList::reverse_iterator ChildIterR;
29  typedef typename ChildList::const_reverse_iterator ChildConstIterR;
30 
33  typedef typename ChildMap::iterator ChildMapIter;
34  typedef typename ChildMap::const_iterator ChildMapConstIter;
35 
38  SIGNAL(sigDestroy, (TreeNode& src));
40  SIGNAL(sigSetData, (TreeNode& src, Data data));
42  SIGNAL(sigSetKey, (TreeNode& src, Key key));
44  SIGNAL(sigInsertChild, (TreeNode& src, TreeNode* childPos, TreeNode& child));
46  SIGNAL(sigRemoveChild, (TreeNode& src, TreeNode& child));
48  SIGNAL(sigSetParent, (TreeNode& src, TreeNode* parent));
49 
50  TreeNode() { init(); }
51  TreeNode(const Data& data) : _data(data) { init(); }
52  TreeNode(const Data& data, const Key& key) : _data(data), _key(key) { init(); }
53 
54  virtual ~TreeNode()
55  {
56  setParent(nullptr);
57  clearChildren();
58  if (hasListenerList()) _listenerList().template dispatch<sigDestroy>(*this);
59  }
60 
62  void setData(const Data& data)
63  {
64  _data = data;
65  if (hasListenerList()) _listenerList().template dispatch<sigSetData>(*this, _data);
66  }
67 
68  const Data& getData() const { return _data; }
69  Data& getData() { return _data; }
71  operator const Data&() const { return getData(); }
72  operator Data&() { return getData(); }
74  const Data& operator*() const { return getData(); }
75  Data& operator*() { return getData(); }
76  const Data& operator->() const { return getData(); }
77  Data& operator->() { return getData(); }
78 
80  void setKey(const Key& key)
81  {
82  if (hasParent() && _key != _keyNull)
83  {
84  //Erase key in parent
85  ChildMapIter itMap = _parent->childMapIter(*this);
86  assert(itMap != _parent->_childMap.end(), sout() << "Child not found in parent's children map. Parent Id: " << _parent->_key << " ; Child Id: " << _key);
87  _parent->_childMap.erase(itMap);
88  }
89 
90  _key = key;
91 
92  //Insert the child at new key
93  if (hasParent()) _parent->_childMap.insert(make_pair(_key, this));
94  if (hasListenerList()) _listenerList().template dispatch<sigSetKey>(*this, _key);
95  }
96 
98  Key& getKey() { return _key; }
99  const Key& getKey() const { return _key; }
100 
102  ChildIter setParent(TreeNode* parent)
103  {
104  if (hasParent()) _parent->removeChild(*this);
105  if (parent) return parent->addChild(*this);
106  return _childList.end();
107  }
108 
110  const TreeNode* getParent() const { return _parent; }
111  TreeNode* getParent() { return _parent; }
113  bool hasParent() const { return _parent; }
114 
116  ChildIter addChild(TreeNode& child)
117  {
118  assert(&child != this);
119  if (child.hasParent()) child._parent->removeChild(child);
120  return insertChild(_childList.end(), child);
121  }
122 
124  ChildIter setChild(ChildIter pos, TreeNode& child) { return insertChild(removeChild(pos), child); }
125 
127  ChildIter insertChild(ChildIter pos, TreeNode& child)
128  {
129  assert(&child != this);
130  //Remove child from parent
131  if (child.hasParent()) child._parent->removeChild(child);
132  if (child.hasListenerList()) child._listenerList().template dispatch<sigSetParent>(child, this);
133  child._parent = this;
134  //Insert child into list
135  child._itSib = _childList.insert(pos, &child);
136  //Insert child key into map
137  if (child._key != _keyNull) _childMap.insert(make_pair(child._key, &child));
138  if (hasListenerList()) _listenerList().template dispatch<sigInsertChild>(*this, pos != _childList.end() ? pos->ptr() : nullptr, child);
139  return child._itSib;
140  }
141 
144  {
145  ChildIter itChild = childPos(child);
146  if (itChild != _childList.end()) return removeChild(itChild);
147  return _childList.end(); //Child not in parent
148  }
149 
151  ChildIter removeChild(ChildIter pos)
152  {
153  TreeNode& child = *pos;
154  assert(child._parent == this);
155  if (hasListenerList()) _listenerList().template dispatch<sigRemoveChild>(*this, child);
156  if (child.hasListenerList()) child._listenerList().template dispatch<sigSetParent>(child, nullptr);
157  child._parent = nullptr;
158  child._itSib = child._childList.end();
159  //Erase from child list
160  auto itRet = _childList.erase(pos);
161  //Erase from map
162  if (child._key != _keyNull)
163  {
164  ChildMapIter itMap = childMapIter(child);
165  assert(itMap != _childMap.end(), sout() << "Child not found in parent's children map. Parent Id: " << _key << " ; Child Id: " << child._key);
166  _childMap.erase(itMap);
167  }
168  return itRet;
169  }
170 
172  void clearChildren() { while (hasChildren()) removeChild(--_childList.end()); }
173 
175  Range_<ChildConstIter, ChildConstIter> children() const { return range(_childList.begin(), _childList.end()); }
176  Range_<ChildIter, ChildIter> children() { return range(_childList.begin(), _childList.end()); }
177 
179  Range_<ChildConstIterR, ChildConstIterR> childrenR() const { return range(_childList.rbegin(), _childList.rend()); }
180  Range_<ChildIterR, ChildIterR> childrenR() { return range(_childList.rbegin(), _childList.rend()); }
181 
183  szt childCount() const { return _childList.size(); }
184 
186  bool hasChildren() const { return childCount() > 0; }
187 
189  ChildConstIter childPos(const Key& key) const
190  {
191  auto it = _childMap.find(key);
192  return it != _childMap.end() ? ChildConstIter(it->second->_itSib) : _childList.end();
193  }
194  ChildIter childPos(const Key& key) { auto ret = const_cast<const TreeNode*>(this)->childPos(key); return reinterpret_cast<ChildIter&>(ret); }
195 
197  ChildConstIter childPos(const TreeNode& child) const { return child._parent == this ? ChildConstIter(child._itSib) : _childList.end(); }
198  ChildIter childPos(const TreeNode& child) { auto ret = const_cast<const TreeNode*>(this)->childPos(child); return reinterpret_cast<ChildIter&>(ret); }
199 
201  const TreeNode* child(const Key& key) const
202  {
203  auto it = _childMap.find(key);
204  return it != _childMap.end() ? it->second.ptr() : nullptr;
205  }
206  TreeNode* child(const Key& key) { return const_cast<TreeNode*>(const_cast<const TreeNode*>(this)->child(key)); }
207 
209  bool hasChild(const TreeNode& child) const { return childPos(child) != _childList.end(); }
210 
212  Range_<ChildMapIter, ChildMapIter> children(const Key& key) { return range(_childMap.equal_range(key)); }
214  { return range(_childMap.equal_range(key)); }
215 
217  Range_<ChildConstIter, ChildConstIter> sibNext() const { return hasParent() ? range(ChildConstIter(next(_itSib)), ChildConstIter(_parent->_childList.end())) : range(_childList.end(), _childList.end()); }
218  Range_<ChildIter, ChildIter> sibNext() { auto ret = const_cast<const TreeNode*>(this)->sibNext(); return reinterpret_cast<Range_<ChildIter, ChildIter>&>(ret); }
219 
221  Range_<ChildConstIterR, ChildConstIterR> sibPrev() const { return hasParent() ? range(ChildConstIterR(_itSib), ChildConstIterR(_parent->_childList.rend())) : range(_childList.rend(), _childList.rend()); }
222  Range_<ChildIterR, ChildIterR> sibPrev() { auto ret = const_cast<const TreeNode*>(this)->sibPrev(); return reinterpret_cast<Range_<ChildIterR, ChildIterR>&>(ret); }
223 
225  szt sibCount() const { return hasParent() ? _parent->childCount() - 1 : 0; }
226 
228  bool sibHasNext() const { return hasParent() ? next(_itSib) != _parent->_childList.end() : false; }
230  bool sibHasPrev() const { return hasParent() ? ChildIterR(_itSib) != _parent->_childList.rend() : false; }
231 
233  const TreeNode& root() const
234  {
235  TreeNode* parent = this;
236  while (parent->hasParent()) parent = parent->_parent;
237  return *parent;
238  }
239  TreeNode& root() { return const_cast<TreeNode&>(const_cast<const TreeNode*>(this)->root()); }
240 
242  bool isRoot() const { return !hasParent(); }
244  bool isLeaf() const { return !hasChildren(); }
245 
247  bool isAncestor(const TreeNode& ancestor) const
248  {
249  for (auto node = getParent(); node; node = node->getParent())
250  if (node == &ancestor) return true;
251  return false;
252  }
253 
255  bool isAncestorOf(const TreeNode& node) const { return node.isAncestor(*this); }
256 
258  const TreeNode* findNode(const Key& key) const
259  {
260  if (_key == key) return this;
261  for (auto& e : preOrd())
262  {
263  auto child = e.child(key);
264  if (child) return child;
265  }
266  return nullptr;
267  }
268  TreeNode* findNode(const Key& key) { return const_cast<TreeNode*>(const_cast<const TreeNode*>(this)->findNode(key)); }
269 
271 
276  template<class TreeNode>
278  {
279  public:
280  typedef std::bidirectional_iterator_tag iterator_category;
283  typedef TreeNode* pointer;
284  typedef TreeNode& reference;
285 
286  PreOrdIter_() : _root(nullptr), _node(nullptr), _skipChildren(false), _count(0) {}
287 
288  PreOrdIter_(TreeNode* root, bool end) :
289  _skipChildren(false),
290  _count(0)
291  {
292  assert(root);
293  _root = root;
294  _node = (!end) ? _root : _root->_parent;
295  }
296 
298  {
299  if (_node == _root->_parent) return *this;
300 
301  if (!_node->isLeaf() && !_skipChildren)
302  {
303  //Non-leaf, move into first child
304  _node = _node->_childList.begin()->ptr();
305  }
306  else
307  {
308  //Leaf, select next sibling. If there is none then backtrack through parents until sibling is found.
309  _skipChildren = false;
310  TreeNode* parent;
311  for (parent = _node; parent != _root->_parent; parent = parent->_parent)
312  {
313  //Don't select siblings of root
314  if (parent != _root && parent->sibHasNext())
315  {
316  parent = begin(parent->sibNext())->ptr();
317  break;
318  }
319  }
320 
321  _node = parent;
322  }
323 
324  ++_count;
325  return *this;
326  }
327 
329  {
330  if (_node == _root) return *this;
331 
332  //If we are at traversal end / have a prev sibling...
333  if (_node == _root->_parent || _node->sibHasPrev())
334  {
335  //Select deepest last child of root / prev sibling
336  _node = (_node == _root->_parent) ? _root : begin(_node->sibPrev())->ptr();
337  while (_node->childCount() > 0) _node = (--_node->_childList.end())->ptr();
338  }
339  else
340  {
341  //No previous sibling, go to parent
342  _node = _node->_parent;
343  }
344 
345  --_count;
346  return *this;
347  }
348 
349  PreOrdIter_ operator++(int) { auto tmp = *this; ++*this; return tmp; }
350  PreOrdIter_ operator--(int) { auto tmp = *this; --*this; return tmp; }
351 
352  bool operator==(const PreOrdIter_& rhs) const { return _node == rhs._node; }
353  bool operator!=(const PreOrdIter_& rhs) const { return !operator==(rhs); }
354 
355  reference operator*() const { assert(_node); return *_node; }
356  pointer operator->() const { return &operator*(); }
357 
359  void skipChildren() { _skipChildren = true; }
360 
362  szt count() const { return _count; }
363 
364  private:
365  TreeNode* _root;
366  TreeNode* _node;
367  bool _skipChildren;
368  szt _count;
369  };
370 
371  typedef PreOrdIter_<TreeNode> PreOrdIter;
372  typedef PreOrdIter_<const TreeNode> PreOrdConstIter;
373 
374  typedef std::reverse_iterator<PreOrdConstIter> PreOrdConstIterR;
375  typedef std::reverse_iterator<PreOrdIter> PreOrdIterR;
376 
379  Range_<PreOrdIter, PreOrdIter> preOrd() { return range(PreOrdIter(this, false), PreOrdIter(this, true)); }
380 
382  Range_<PreOrdConstIterR, PreOrdConstIterR> preOrdR() const { auto range_ = preOrd(); return range(PreOrdConstIterR(end(range_)), PreOrdConstIterR(begin(range_))); }
383  Range_<PreOrdIterR, PreOrdIterR> preOrdR() { auto range_ = preOrd(); return range(PreOrdIterR(end(range_)), PreOrdIterR(begin(range_))); }
384 
386  ListenerList& listeners() { return _listenerList(); }
387 
388 private:
389  void init()
390  {
391  _parent = nullptr;
392  _itSib = _childList.end();
393  }
394 
396  ChildMapIter childMapIter(TreeNode& child) { return stdutil::findVal(_childMap, child._key, &child); }
397 
400  ListenerList& _listenerList() { if (_listenerList_p) return *_listenerList_p; return *(_listenerList_p = make_unique<ListenerList>()); }
401  bool hasListenerList() const { return _listenerList_p; }
403 
404  Data _data;
405  TreeNode* _parent;
406  ChildIter _itSib;
407  ChildList _childList;
408  Key _key;
409  ChildMap _childMap;
410  UniquePtr<ListenerList> _listenerList_p;
411 
412  static const Key _keyNull;
413 };
414 
415 template<class Data, class Key, template<class> class Alloc>
416 const Key TreeNode<Data,Key,Alloc>::_keyNull;
417 
418 }
Range_< ChildConstIter, ChildConstIter > children() const
Get all children.
Definition: Tree.h:175
PreOrdIter_ operator++(int)
Definition: Tree.h:349
PreOrdIter_ & operator++()
Definition: Tree.h:297
Range_< ChildConstIter, ChildConstIter > sibNext() const
Returns forward iterator range starting at next sibling.
Definition: Tree.h:217
stdutil::unordered_multimap< Key, deref_wrap< TreeNode >, Alloc > ChildMap
Map holding children at keys.
Definition: Tree.h:32
std::bidirectional_iterator_tag iterator_category
Definition: Tree.h:280
Range_< PreOrdConstIterR, PreOrdConstIterR > preOrdR() const
Get a reversed depth-first pre-order range.
Definition: Tree.h:382
ChildIter setChild(ChildIter pos, TreeNode &child)
Set child into list at position. Returns position of child in list.
Definition: Tree.h:124
Range_< PreOrdIterR, PreOrdIterR > preOrdR()
Definition: Tree.h:383
const Data & operator*() const
Get the data at this node.
Definition: Tree.h:74
Range_< ChildConstIterR, ChildConstIterR > sibPrev() const
Returns reverse iterator range starting at previous sibling.
Definition: Tree.h:221
ListenerList & listeners()
Get listener list.
Definition: Tree.h:386
auto findVal(MultiMap &map, const Key &key, const Val &val) -> mt_iterOf(map)
Get iterator to key with value. Returns end if not found.
Definition: StdUtil.h:70
Unrooted acyclic tree.
Definition: Tree.h:17
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
ChildMap::iterator ChildMapIter
Definition: Tree.h:33
TreeNode * pointer
Definition: Tree.h:283
Depth-first pre-order traversal.
Definition: Tree.h:277
Data & operator->()
Definition: Tree.h:77
bool hasParent() const
Check if node has a parent.
Definition: Tree.h:113
ChildList::reverse_iterator ChildIterR
Definition: Tree.h:28
Range_< ChildConstIterR, ChildConstIterR > childrenR() const
Get all children in reverse order.
Definition: Tree.h:179
void skipChildren()
Skip the current node's children on next step of this iterator.
Definition: Tree.h:359
ChildConstIter childPos(const TreeNode &child) const
Get child position in list. Returns children().end() if not in parent.
Definition: Tree.h:197
Range_< ChildIter, ChildIter > children()
Definition: Tree.h:176
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
ChildIter insertChild(ChildIter pos, TreeNode &child)
Insert child into list at position. Returns position of child in list.
Definition: Tree.h:127
szt sibCount() const
Get number of siblings (count doesn't include this node)
Definition: Tree.h:225
bool isRoot() const
Check if this is a root node at the top of a tree.
Definition: Tree.h:242
const Data & getData() const
Definition: Tree.h:68
ChildIter removeChild(TreeNode &child)
Remove child from children list. Returns position of next child, or children().end() if child doesn't...
Definition: Tree.h:143
sdt difference_type
Definition: Tree.h:282
bool operator!=(const PreOrdIter_ &rhs) const
Definition: Tree.h:353
PreOrdIter_< const TreeNode > PreOrdConstIter
Definition: Tree.h:372
szt count() const
Get the number of nodes between the current position and the beginning of the iteration.
Definition: Tree.h:362
ChildIter removeChild(ChildIter pos)
Remove child at position in list. Returns position of next child. Will fail if pos is invalid...
Definition: Tree.h:151
const TreeNode & root() const
Get the root (top-most) node of the tree that contains this node.
Definition: Tree.h:233
PreOrdIter_()
Definition: Tree.h:286
std::reverse_iterator< PreOrdIter > PreOrdIterR
Definition: Tree.h:375
ChildList::const_reverse_iterator ChildConstIterR
Definition: Tree.h:29
virtual ~TreeNode()
Definition: Tree.h:54
Key & getKey()
Get key used to identify this node.
Definition: Tree.h:98
ChildIter childPos(const Key &key)
Definition: Tree.h:194
bool hasChild(const TreeNode &child) const
Check if this node has a child in its list.
Definition: Tree.h:209
TreeNode(const Data &data)
Definition: Tree.h:51
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
ChildIter addChild(TreeNode &child)
Add child into list, returns position of child in list.
Definition: Tree.h:116
ChildIter setParent(TreeNode *parent)
Set parent node. Returns position in new parent's child list, or children().end() if parent is null...
Definition: Tree.h:102
ChildIter childPos(const TreeNode &child)
Definition: Tree.h:198
Data & operator*()
Definition: Tree.h:75
TreeNode * findNode(const Key &key)
Definition: Tree.h:268
Range_< PreOrdConstIter, PreOrdConstIter > preOrd() const
Get a depth-first pre-order range.
Definition: Tree.h:378
Range_< ChildIter, ChildIter > sibNext()
Definition: Tree.h:218
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
PreOrdIter_< TreeNode > PreOrdIter
Definition: Tree.h:371
list< deref_wrap< TreeNode >, Alloc< deref_wrap< TreeNode > > > ChildList
Child linked list.
Definition: Tree.h:25
TreeNode * child(const Key &key)
Definition: Tree.h:206
SIGNAL(sigDestroy,(TreeNode &src))
Called before class is destroyed.
TreeNode & root()
Definition: Tree.h:239
ChildList::iterator ChildIter
Definition: Tree.h:26
bool isAncestor(const TreeNode &ancestor) const
Test if ancestor is this node's ancestor. Returns false if ancestor is same as this node...
Definition: Tree.h:247
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
#define SIGNAL_DECL(BaseClass)
Call once inside a class that has signals.
Definition: Signal.h:18
TreeNode & reference
Definition: Tree.h:284
std::unordered_multimap< Key, Value, std::hash< Key >, std::equal_to< Key >, Alloc< pair< const Key, Value >>> unordered_multimap
std::unordered_multimap with custom allocator
Definition: StdUtil.h:86
pointer operator->() const
Definition: Tree.h:356
ChildList::const_iterator ChildConstIter
Definition: Tree.h:27
bool hasChildren() const
Check if node has children.
Definition: Tree.h:186
Iterator range. See range(Iter1&&, Iter2&&) to create.
Definition: Range.h:88
szt childCount() const
Get number of children.
Definition: Tree.h:183
TreeNode(const Data &data, const Key &key)
Definition: Tree.h:52
ChildMap::const_iterator ChildMapConstIter
Definition: Tree.h:34
bool sibHasNext() const
Check if node has a next sibling.
Definition: Tree.h:228
Range_< PreOrdIter, PreOrdIter > preOrd()
Definition: Tree.h:379
PreOrdIter_(TreeNode *root, bool end)
Definition: Tree.h:288
const Key & getKey() const
Definition: Tree.h:99
PreOrdIter_ & operator--()
Definition: Tree.h:328
ChildConstIter childPos(const Key &key) const
Get child position in list. Returns first child found at key, or children().end() if not found...
Definition: Tree.h:189
PreOrdIter_ operator--(int)
Definition: Tree.h:350
std::reverse_iterator< PreOrdConstIter > PreOrdConstIterR
Definition: Tree.h:374
void setKey(const Key &key)
Set the key used to identify this node.
Definition: Tree.h:80
bool isAncestorOf(const TreeNode &node) const
Test if this node is an ancestor of node. Returns false if node is same as this node.
Definition: Tree.h:255
bool isLeaf() const
Check if this is a leaf node at the end of a tree branch.
Definition: Tree.h:244
bool operator==(const PreOrdIter_ &rhs) const
Definition: Tree.h:352
TreeNode * getParent()
Definition: Tree.h:111
const TreeNode * findNode(const Key &key) const
Returns first node found with key in tree of descendants (depth-first pre-order traversal) ...
Definition: Tree.h:258
Range_< ChildIterR, ChildIterR > childrenR()
Definition: Tree.h:180
reference operator*() const
Definition: Tree.h:355
void setData(const Data &data)
Set the data that this node contains.
Definition: Tree.h:62
TreeNode value_type
Definition: Tree.h:281
const Data & operator->() const
Definition: Tree.h:76
Range_< ChildIterR, ChildIterR > sibPrev()
Definition: Tree.h:222
Collection of listeners.
Definition: ListenerList.h:16
Global Honeycomb namespace.
Range_< ChildMapIter, ChildMapIter > children(const Key &key)
Get children that match the key. The child node TreeNode& is stored in the map pair ChildMapIter->sec...
Definition: Tree.h:212
TreeNode()
Definition: Tree.h:50
const TreeNode * getParent() const
Get parent node.
Definition: Tree.h:110
const TreeNode * child(const Key &key) const
Get child in list. Returns first child found at key, or null if not found.
Definition: Tree.h:201
Key_ Key
Definition: Tree.h:22
void clearChildren()
Clear all children.
Definition: Tree.h:172
bool sibHasPrev() const
Check if node has a previous sibling.
Definition: Tree.h:230
Data & getData()
Definition: Tree.h:69
Range_< ChildMapConstIter, ChildMapConstIter > children(const Key &key) const
Definition: Tree.h:213
Data_ Data
Definition: Tree.h:21