11 template<
class TreeNode>
18 _listeners.push_back(&ListenerQueue::create<typename TreeNode::sigDestroy>(
bind_fill(&TreeClone::onDestroy,
this)));
19 _listeners.push_back(&ListenerQueue::create<typename TreeNode::sigSetData>(
bind_fill(&TreeClone::onSetData,
this)));
20 _listeners.push_back(&ListenerQueue::create<typename TreeNode::sigSetKey>(
bind_fill(&TreeClone::onSetKey,
this)));
21 _listeners.push_back(&ListenerQueue::create<typename TreeNode::sigInsertChild>(
bind_fill(&TreeClone::onInsertChild,
this)));
22 _listeners.push_back(&ListenerQueue::create<typename TreeNode::sigRemoveChild>(
bind_fill(&TreeClone::onRemoveChild,
this)));
42 auto clone = getRegClone(rootNode);
43 if (clone)
return *clone;
45 return createPhantom(rootNode);
65 for (
auto& e : rootNode.
preOrd())
67 auto clone = unregNodeSingle(e);
68 if (!ret) ret = clone;
86 for (
auto& e : rootClone.
preOrd())
90 auto res = unregNodeSingle(*node);
91 if (!ret && res) ret = node;
101 for (
auto& e : _listeners) e->process();
104 while (!_phantomMap.empty())
105 cloneTree(*_phantomMap.begin()->first);
112 for (
auto& node :
keys(_regMap))
for (
auto& e : _listeners)
const_cast<TreeNode*
>(node)->listeners().remove(*e);
113 for (
auto& e : _listeners) e->clear();
127 auto it = _cloneMap.find(&node);
128 if (it == _cloneMap.end())
return nullptr;
135 auto it = _cloneRMap.find(const_cast<TreeNode*>(&clone));
136 if (it == _cloneRMap.end())
return nullptr;
154 auto clone = getRegClone(src);
155 assert(clone && !_phantomMap.count(&src) && !_unregMap.count(&src));
159 void onSetData(TreeNode& src,
const typename TreeNode::Data& data)
161 auto clone = getRegClone(src);
162 assert(clone && !_phantomMap.count(&src) && !_unregMap.count(&src));
163 clone->setData(data);
166 void onSetKey(TreeNode& src,
const typename TreeNode::Key& key)
168 auto clone = getRegClone(src);
169 assert(clone && !_phantomMap.count(&src) && !_unregMap.count(&src));
173 void onInsertChild(TreeNode& src, TreeNode* childPos, TreeNode& child)
175 auto clone = getRegClone(src);
176 assert(clone && !_phantomMap.count(&src) && !_unregMap.count(&src));
179 auto it = end(clone->children());
183 childPos = getRegClone(*childPos);
184 assert(childPos && !_unregMap.count(childPos));
185 it = clone->childPos(*childPos);
189 auto& cloneChild =
regNode(child);
191 clone->insertChild(it, cloneChild);
194 void onRemoveChild(TreeNode& src, TreeNode& child)
196 auto clone = getRegClone(src);
197 assert(clone && !_phantomMap.count(&src) && !_unregMap.count(&src));
200 auto cloneChild = getRegClone(child);
201 assert(cloneChild && !_unregMap.count(cloneChild));
203 auto it = clone->childPos(*cloneChild);
204 assert(it != end(clone->children()));
206 clone->removeChild(it);
209 void deleteClone(TreeNode& clone)
211 auto it = _cloneRMap.find(&clone);
212 assert(it != _cloneRMap.end() && it->second && !_phantomMap.count(it->second) && !_unregMap.count(it->second));
213 _cloneMap.erase(it->second);
214 _regMap.erase(it->second);
215 _cloneRMap.erase(it);
219 TreeNode& allocClone(
const TreeNode& node)
221 assert(!_cloneMap.count(&node));
222 auto clone =
new TreeNode();
223 _cloneMap[&node] = clone;
224 _cloneRMap[clone] = &node;
228 TreeNode* phantom(
const TreeNode& node)
const
230 auto it = _phantomMap.find(&node);
231 if (it == _phantomMap.end())
return nullptr;
235 TreeNode* getRegClone(
const TreeNode&
regNode)
const
237 auto it = _regMap.find(®Node);
238 if (it == _regMap.end())
return nullptr;
242 TreeNode* getUnregClone(
const TreeNode& node)
const
244 auto it = _unregMap.find(&node);
245 if (it == _unregMap.end())
return nullptr;
250 TreeNode& createPhantom(
const TreeNode& node)
253 assert(!_phantomMap.count(&node));
255 auto phantom = getUnregClone(node);
256 if (phantom) _unregMap.erase(&node);
257 else phantom = &allocClone(node);
258 _phantomMap[&node] = phantom;
259 _regMap[&node] = phantom;
260 phantom->setParent(
nullptr);
261 phantom->clearChildren();
262 phantom->setData(node.getData());
263 phantom->setKey(node.getKey());
267 void cloneTree(
const TreeNode& parent)
269 auto phantom = this->phantom(parent);
271 _phantomMap.erase(&parent);
274 for (
auto& child : parent.children())
276 auto phantomChild = getRegClone(child);
277 if (!phantomChild || phantomChild == this->phantom(child))
280 if (!phantomChild) phantomChild = &createPhantom(child);
283 phantom->addChild(*phantomChild);
286 for (
auto& e : _listeners)
const_cast<TreeNode&
>(parent).listeners().add(*e);
290 TreeNode* unregNodeSingle(
const TreeNode& node)
292 auto clone = getRegClone(node);
293 if (!clone)
return nullptr;
297 sout() <<
"Node can't be unregistered because its parent is registered. Parent Id: "
298 << clone->getParent()->getKey() <<
" ; Child Id: " << clone->getKey());
300 for (
auto& e : _listeners)
const_cast<TreeNode&
>(node).listeners().remove(*e);
302 _regMap.erase(&node);
303 _phantomMap.erase(&node);
304 _unregMap[&node] = clone;
310 typedef unordered_map<const TreeNode*, TreeNode*> CloneMap;
312 typedef unordered_map<TreeNode*, const TreeNode*> CloneRMap;
314 vector<ListenerQueue::Ptr> _listeners;
316 CloneRMap _cloneRMap;
318 CloneMap _phantomMap;
const TreeNode * unregClone(const TreeNode &rootClone)
Stop a clone and its entire subtree from tracking changes to their original nodes. Returns original node of first clone unregistered (or null if none found).
Definition: TreeClone.h:79
bool isRegNode(const TreeNode &node) const
Check if a node is registered.
Definition: TreeClone.h:141
void update()
Update clones to make them mirror the current data and hierarchy of registered nodes.
Definition: TreeClone.h:98
Unrooted acyclic tree.
Definition: Tree.h:17
Clone and track changes to an entire tree.
Definition: TreeClone.h:12
void delete_(T *&p)
Destruct object, free memory and set pointer to null.
Definition: Allocator.h:75
void clear()
Reset the state of the tree clone structure, unregister all nodes and destroy all clones...
Definition: TreeClone.h:109
const TreeNode * getOrigNode(const TreeNode &clone) const
Get the original node of a clone. Returns null if not found.
Definition: TreeClone.h:133
~TreeClone()
Definition: TreeClone.h:25
auto bind_fill(Func &&f, Args &&...args) -> decltype( priv::bind_fill< mt::funcTraits< typename mt::removeRef< Func >::type >::arity >()(forward< Func >(f), forward< Args >(args)...))
Version of bind that automatically fills in placeholders for unspecified arguments.
Definition: StdUtil.h:138
szt cloneCount() const
Get total number of clones being handled by this tree.
Definition: TreeClone.h:146
TreeNode * getClone(const TreeNode &node) const
Get the cloned version of a node (node may be registered or unregistered). Returns null if not found...
Definition: TreeClone.h:125
auto keys(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 0 >, TupleIter< mt_iterOf(range), 0 >>
Create a range over the keys of a map or map iterator range.
Definition: StdUtil.h:23
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
Range_< PreOrdConstIter, PreOrdConstIter > preOrd() const
Get a depth-first pre-order range.
Definition: Tree.h:378
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
szt regNodeCount() const
Get total number of registered nodes.
Definition: TreeClone.h:148
void deleteRange(Range &&range)
Delete all elements in range.
Definition: Range.h:428
bool isRegClone(const TreeNode &clone) const
Check if a clone is registered.
Definition: TreeClone.h:143
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
auto values(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 1 >, TupleIter< mt_iterOf(range), 1 >>
Create a range over the values of a map or map iterator range.
Definition: StdUtil.h:30
TreeNode & regNode(const TreeNode &rootNode)
Register a node to clone. Returns clone. Clone's state is invalid (not equal to original) until updat...
Definition: TreeClone.h:39
Global Honeycomb namespace.
Key_ Key
Definition: Tree.h:22
TreeClone()
Definition: TreeClone.h:16
TreeNode * unregNode(const TreeNode &rootNode)
Stop tracking changes to a node and its entire subtree. Returns clone of first node unregistered (or ...
Definition: TreeClone.h:58
Data_ Data
Definition: Tree.h:21