File indexing completed on 2024-05-12 15:57:02
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef KISFOREST_H 0007 #define KISFOREST_H 0008 0009 #include <utility> 0010 0011 #include <boost/iterator/iterator_facade.hpp> 0012 #include <boost/iterator/iterator_adaptor.hpp> 0013 0014 #include "KisCppQuirks.h" 0015 0016 #include "kis_assert.h" 0017 #include "kis_debug.h" 0018 0019 namespace KisForestDetail { 0020 0021 template <typename Base> 0022 struct RootNodeImpl 0023 { 0024 RootNodeImpl<Base> *parent = nullptr; 0025 Base *firstChild = nullptr; 0026 Base *lastChild = nullptr; 0027 0028 inline bool isRoot() const { 0029 return !parent; 0030 } 0031 }; 0032 0033 0034 template <typename Base> 0035 struct BaseNode : RootNodeImpl<Base> 0036 { 0037 Base *nextSibling = nullptr; 0038 Base *prevSibling = nullptr; 0039 }; 0040 0041 template <typename T> 0042 struct Node : public BaseNode<Node<T>> 0043 { 0044 template <typename X> 0045 explicit Node(X &&newValue) 0046 : value(std::forward<X>(newValue)) 0047 { 0048 } 0049 0050 T value; 0051 }; 0052 0053 template <typename T> 0054 using RootNode = RootNodeImpl<Node<T>>; 0055 0056 0057 /*************************************************************************/ 0058 /* BaseIterator */ 0059 /*************************************************************************/ 0060 0061 template <typename BaseClass, typename T, typename Tag> 0062 class BaseIterator : 0063 public boost::iterator_facade <BaseClass, 0064 T, 0065 Tag> 0066 { 0067 public: 0068 using value_type = T; 0069 0070 BaseIterator(Node<T> *node) 0071 : m_node(node) 0072 { 0073 } 0074 0075 Node<T>* node() const { 0076 return m_node; 0077 } 0078 0079 private: 0080 friend class boost::iterator_core_access; 0081 0082 typename std::iterator_traits<BaseIterator>::reference dereference() const { 0083 KIS_ASSERT(m_node); 0084 return m_node->value; 0085 } 0086 0087 bool equal(const BaseClass &other) const { 0088 return m_node == other.m_node; 0089 } 0090 0091 protected: 0092 Node<T> *m_node; 0093 }; 0094 0095 0096 /*************************************************************************/ 0097 /* ChildIterator */ 0098 /*************************************************************************/ 0099 0100 /** 0101 * Child iterator is used to traverse all the children of the current node. 0102 * It models \c BidirectionalIterator concept, so you can traverse with it in both 0103 * directions. 0104 * 0105 * \code{.cpp} 0106 * 0107 * // Forest: 0108 * // 0109 * // 0 1 0110 * // 2 0111 * // 3 5 6 0112 * // 7 0113 * // 4 0114 * // 8 9 0115 * // 10 0116 * 0117 * KisForest<int>::iterator it0 = findValue(forest, 0); 0118 * 0119 * // iterate through all the children of '0' 0120 * for (auto it = childBegin(it0); it != childEnd(it0); ++it) { 0121 * qDebug() << *it; 0122 * } 0123 * // prints: 1,2,3,4 0124 * 0125 * \endcode 0126 * 0127 * It is also possible to convert any iterator type into child iterator 0128 * via siblingCurrent() function. 0129 * 0130 * \code{.cpp} 0131 * 0132 * // Forest: 0133 * // 0134 * // 0 1 0135 * // 2 0136 * // 3 5 6 0137 * // 7 0138 * // 4 0139 * // 8 9 0140 * // 10 0141 * 0142 * KisForest<int>::iterator it2 = findValue(forest, 2); 0143 * 0144 * // iterate the children of '0' from '2' to '4' 0145 * for (auto it = siblingCurrent(it2); it != siblingEnd(it2); ++it) { 0146 * qDebug() << *it; 0147 * } 0148 * // prints: 2,3,4 0149 * 0150 * \endcode 0151 * 0152 * WARNING: converting end() iterator to other iterator types currently leads 0153 * to undefined behavior. 0154 */ 0155 0156 template <typename T> 0157 class ChildIterator : 0158 public BaseIterator <ChildIterator<T>, 0159 T, 0160 boost::bidirectional_traversal_tag> 0161 { 0162 public: 0163 ChildIterator(Node<T> *node, RootNode<T> *parent) 0164 : BaseIterator<ChildIterator<T>, T, boost::bidirectional_traversal_tag>(node), 0165 m_parent(parent) 0166 { 0167 } 0168 0169 private: 0170 friend class boost::iterator_core_access; 0171 template <typename X> 0172 friend ChildIterator<X> parent(const ChildIterator<X> &it); 0173 template <typename X> friend class Forest; 0174 0175 void increment() { 0176 this->m_node = this->m_node->nextSibling; 0177 } 0178 0179 void decrement() { 0180 this->m_node = 0181 this->m_node ? 0182 this->m_node->prevSibling : 0183 m_parent ? m_parent->lastChild : nullptr; 0184 } 0185 0186 bool equal(const ChildIterator<T> &other) const { 0187 return this->m_node == other.m_node && 0188 (this->m_node || this->m_parent == other.m_parent); 0189 } 0190 0191 private: 0192 RootNode<T> *m_parent; 0193 }; 0194 0195 template <typename Iterator, 0196 typename ResultIterator = ChildIterator<typename Iterator::value_type>> 0197 ResultIterator siblingBegin(Iterator it) 0198 { 0199 using RootNodeType = RootNode<typename Iterator::value_type>; 0200 0201 RootNodeType *parent = it.node() ? it.node()->parent : nullptr; 0202 return ResultIterator(parent ? parent->firstChild : nullptr, parent); 0203 } 0204 0205 0206 template <typename Iterator, 0207 typename ResultIterator = ChildIterator<typename Iterator::value_type>> 0208 ResultIterator siblingCurrent(Iterator it) 0209 { 0210 return ResultIterator(it.node(), it.node() ? it.node()->parent : nullptr); 0211 } 0212 0213 template <typename Iterator, 0214 typename ResultIterator = ChildIterator<typename Iterator::value_type>> 0215 ResultIterator siblingEnd(Iterator it) 0216 { 0217 return ResultIterator(nullptr, it.node() ? it.node()->parent : nullptr); 0218 } 0219 0220 template <typename Iterator, 0221 typename ResultIterator = ChildIterator<typename Iterator::value_type>> 0222 ResultIterator childBegin(Iterator it) 0223 { 0224 return ResultIterator(it.node() ? it.node()->firstChild : nullptr, it.node()); 0225 } 0226 0227 template <typename Iterator, 0228 typename ResultIterator = ChildIterator<typename Iterator::value_type>> 0229 ResultIterator childEnd(Iterator it) 0230 { 0231 return ResultIterator(nullptr, it.node()); 0232 } 0233 0234 template <typename T> 0235 ChildIterator<T> parent(const ChildIterator<T> &it) 0236 { 0237 Node<T> *parent = static_cast<Node<T>*>(it.m_parent && !it.m_parent->isRoot() ? it.m_parent : nullptr); 0238 return ChildIterator<T>(parent, parent ? parent->parent : 0); 0239 } 0240 0241 template <typename T> 0242 inline bool isEnd(const ChildIterator<T> &it) { 0243 return !it.node(); 0244 } 0245 0246 0247 /*************************************************************************/ 0248 /* HierarchyIterator */ 0249 /*************************************************************************/ 0250 0251 /** 0252 * Hierarchy iterator is used to traverse from the current node to the root 0253 * of the current subtree of the forest. It models \c ForwardIterator concept. 0254 * 0255 * \code{.cpp} 0256 * 0257 * // Forest: 0258 * // 0259 * // 0 1 0260 * // 2 0261 * // 3 5 6 0262 * // 7 0263 * // 4 0264 * // 8 9 0265 * // 10 0266 * 0267 * KisForest<int>::iterator nodeIt = findValue(forest, 5); 0268 * 0269 * // print all the parent nodes for nodeIt, including nodeIt itself 0270 * for (auto it = hierarchyBegin(nodeIt); it != hierarchyEnd(nodeIt); ++it) { 0271 * qDebug() << *it; 0272 * } 0273 * // prints: 5,3,0 0274 * 0275 * \endcode 0276 * 0277 * WARNING: converting end() iterator to other iterator types currently leads 0278 * to undefined behavior. 0279 */ 0280 0281 template <typename T> 0282 class HierarchyIterator : 0283 public BaseIterator <HierarchyIterator<T>, 0284 T, 0285 boost::forward_traversal_tag> 0286 { 0287 public: 0288 HierarchyIterator(Node<T> *node) 0289 : BaseIterator<HierarchyIterator<T>, T, boost::forward_traversal_tag>(node) 0290 { 0291 } 0292 0293 0294 private: 0295 friend class boost::iterator_core_access; 0296 0297 void increment() { 0298 RootNode<T> *parent = this->m_node->parent; 0299 this->m_node = 0300 static_cast<Node<T>*>( 0301 parent && !parent->isRoot() ? 0302 parent : nullptr); 0303 } 0304 }; 0305 0306 template <typename Iterator, 0307 typename ResultIterator = HierarchyIterator<typename Iterator::value_type>> 0308 ResultIterator hierarchyBegin(Iterator it) 0309 { 0310 return ResultIterator(it.node()); 0311 } 0312 0313 template <typename Iterator, 0314 typename ResultIterator = HierarchyIterator<typename Iterator::value_type>> 0315 ResultIterator hierarchyEnd(Iterator it) 0316 { 0317 Q_UNUSED(it); 0318 return ResultIterator(nullptr); 0319 } 0320 0321 0322 /*************************************************************************/ 0323 /* CompositionIterator */ 0324 /*************************************************************************/ 0325 0326 /** 0327 * Composition iterator is used to traverse entire child-subtree of the node 0328 * recursively in depth-first order. Every node it entered twice: first time, when 0329 * subtree is entered; second time, when subtree is left. To check the current 0330 * state of the iterator (Enter or Leave) use \c it.state() call. 0331 * 0332 * Iterator models \c ForwardIterator concept. 0333 * 0334 * \code{.cpp} 0335 * 0336 * // Forest: 0337 * // 0338 * // 0 1 0339 * // 2 0340 * // 3 5 6 0341 * // 7 0342 * // 4 0343 * // 8 9 0344 * // 10 0345 * 0346 * KisForest<int>::iterator it3 = findValue(forest, 3); 0347 * 0348 * // iterate through all the children of '3' recursively 0349 * for (auto it = compositionBegin(it3); it != compositionEnd(it3); ++it) { 0350 * qDebug() << *it << it.state(); 0351 * } 0352 * // prints: (3, Enter) 0353 * // (5, Enter) 0354 * // (6, Enter) 0355 * // (6, Leave) 0356 * // (7, Enter) 0357 * // (7, Leave) 0358 * // (5, Leave) 0359 * // (3, Leave) 0360 * 0361 * \endcode 0362 * 0363 * WARNING: converting end() iterator to other iterator types currently leads 0364 * to undefined behavior. 0365 */ 0366 0367 enum TraversalState { 0368 Enter, 0369 Leave 0370 }; 0371 0372 template <typename T> 0373 class CompositionIterator : 0374 public boost::iterator_adaptor< 0375 CompositionIterator<T>, 0376 ChildIterator<T>, 0377 boost::use_default, 0378 boost::forward_traversal_tag> 0379 { 0380 using BaseClass = boost::iterator_adaptor< 0381 CompositionIterator<T>, 0382 ChildIterator<T>, 0383 boost::use_default, 0384 boost::forward_traversal_tag>; 0385 0386 public: 0387 using traversal_state = TraversalState; 0388 0389 Node<T>* node() const { 0390 return this->base().node(); 0391 } 0392 0393 public: 0394 CompositionIterator(Node<T> *node, traversal_state state = Enter) 0395 : BaseClass(ChildIterator<T>(node, node ? node->parent : nullptr)), 0396 m_state(state) 0397 { 0398 } 0399 0400 traversal_state state() const { 0401 return m_state; 0402 } 0403 0404 0405 private: 0406 friend class boost::iterator_core_access; 0407 0408 bool tryJumpToPos(typename CompositionIterator::base_type it, 0409 TraversalState newState) { 0410 bool result = false; 0411 0412 if (!isEnd(it)) { 0413 this->base_reference() = it; 0414 result = true; 0415 m_state = newState; 0416 } 0417 0418 return result; 0419 } 0420 0421 void increment() { 0422 switch (m_state) { 0423 case Enter: 0424 if (tryJumpToPos(childBegin(this->base()), Enter)) return; 0425 if (tryJumpToPos(this->base(), Leave)) return; 0426 break; 0427 case Leave: 0428 if (tryJumpToPos(std::next(this->base()), Enter)) return; 0429 if (tryJumpToPos(parent(this->base()), Leave)) return; 0430 break; 0431 } 0432 0433 this->base_reference() = ChildIterator<T>(nullptr, nullptr); 0434 } 0435 0436 private: 0437 traversal_state m_state = Enter; 0438 }; 0439 0440 template <typename Iterator> 0441 CompositionIterator<typename Iterator::value_type> compositionBegin(Iterator it) 0442 { 0443 using CompositionIterator = CompositionIterator<typename Iterator::value_type>; 0444 return CompositionIterator(it.node(), Enter); 0445 } 0446 0447 template <typename Iterator> 0448 CompositionIterator<typename Iterator::value_type> compositionEnd(Iterator it) 0449 { 0450 using CompositionIterator = CompositionIterator<typename Iterator::value_type>; 0451 return it.node() ? 0452 std::next(CompositionIterator(it.node(), Leave)) : 0453 CompositionIterator(nullptr, Leave); 0454 } 0455 0456 0457 /*************************************************************************/ 0458 /* DepthFirstIterator */ 0459 /*************************************************************************/ 0460 0461 /** 0462 * Depth-first iterator is used to traverse entire child-subtree of the node 0463 * recursively in depth-first order. Every node is entered only once. It 0464 * implements standard recursion iteration: 0465 * 0466 * * \c DepthFirstIterator<T, Enter> implements head-recursion, that is, 0467 * the node is visited *before* its children 0468 * 0469 * * \c DepthFirstIterator<T, Leave> implements tail-recursion, that is, 0470 * the node is visited *after* its children 0471 * 0472 * Use \c subtreeBegin() and \c subtreeEnd() for head-recursion and \c tailSubtreeBegin() and 0473 * \c tailSubtreeEnd() for tail-recursion. 0474 * 0475 * Iterator models \c ForwardIterator concept. 0476 * 0477 * \code{.cpp} 0478 * 0479 * // Forest: 0480 * // 0481 * // 0 1 0482 * // 2 0483 * // 3 5 6 0484 * // 7 0485 * // 4 0486 * // 8 9 0487 * // 10 0488 * 0489 * KisForest<int>::iterator it3 = findValue(forest, 3); 0490 * 0491 * // iterate through all the children of '3' in head-recursive way 0492 * for (auto it = subtreeBegin(it3); it != subtreeEnd(it3); ++it) { 0493 * qDebug() << *it << it.state(); 0494 * } 0495 * // prints: 3, 5, 6, 7 0496 * 0497 * // iterate through all the children of '3' in tail-recursive way 0498 * for (auto it = tailSubtreeBegin(it3); it != tailSubtreeEnd(it3); ++it) { 0499 * qDebug() << *it << it.state(); 0500 * } 0501 * // prints: 6, 7, 5, 3 0502 * 0503 * \endcode 0504 * 0505 * WARNING: converting end() iterator to other iterator types currently leads 0506 * to undefined behavior. 0507 */ 0508 0509 template <typename T, TraversalState visit_on> 0510 class DepthFirstIterator : 0511 public boost::iterator_adaptor< 0512 DepthFirstIterator<T, visit_on>, 0513 CompositionIterator<T>, 0514 boost::use_default, 0515 boost::forward_traversal_tag> 0516 { 0517 using BaseClass = boost::iterator_adaptor< 0518 DepthFirstIterator<T, visit_on>, 0519 CompositionIterator<T>, 0520 boost::use_default, 0521 boost::forward_traversal_tag>; 0522 0523 public: 0524 using traversal_state = TraversalState; 0525 0526 DepthFirstIterator(Node<T> *node, 0527 traversal_state state = traversal_state::Enter, 0528 bool shouldSkipToBegin = false) 0529 : BaseClass(CompositionIterator<T>(node, state)) 0530 { 0531 if (shouldSkipToBegin) { 0532 skipToState(visit_on); 0533 } 0534 } 0535 0536 Node<T>* node() const { 0537 return this->base().node(); 0538 } 0539 0540 private: 0541 friend class boost::iterator_core_access; 0542 0543 void increment() { 0544 this->base_reference()++; 0545 skipToState(visit_on); 0546 } 0547 0548 void skipToState(TraversalState state) { 0549 while (this->base().node() && this->base().state() != state) { 0550 this->base_reference()++; 0551 } 0552 } 0553 0554 }; 0555 0556 template <typename Iterator, 0557 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter>> 0558 ResultIterator subtreeBegin(Iterator it) 0559 { 0560 return ResultIterator(it.node(), Enter); 0561 } 0562 0563 template <typename Iterator, 0564 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter>> 0565 ResultIterator subtreeEnd(Iterator it) 0566 { 0567 return it.node() ? 0568 std::next(ResultIterator(it.node(), Leave)) : 0569 ResultIterator(nullptr, Leave); 0570 } 0571 0572 template <typename Iterator, 0573 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave>> 0574 ResultIterator tailSubtreeBegin(Iterator it) 0575 { 0576 return ResultIterator(it.node(), Enter, true); 0577 } 0578 0579 template <typename Iterator, 0580 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave>> 0581 ResultIterator tailSubtreeEnd(Iterator it) 0582 { 0583 return it.node() ? 0584 std::next(ResultIterator(it.node(), Leave)) : 0585 ResultIterator(nullptr, Leave); 0586 } 0587 0588 0589 /*************************************************************************/ 0590 /* Forest */ 0591 /*************************************************************************/ 0592 0593 /** 0594 * Forest implements a container for composing tree-like structures from 0595 * arbitrary objects. 0596 * 0597 * All add/remove operations are implemented via child_iterator. You can 0598 * convert any iterator type into a child iterator via \c siblingCurrent() 0599 * function. 0600 * 0601 * * \code{.cpp} 0602 * 0603 * // Forest: 0604 * // 0605 * // 0 1 0606 * // 2 0607 * // 3 5 6 0608 * // 7 0609 * // 4 0610 * // 8 9 0611 * // 10 0612 * 0613 * KisForest<int> forest; 0614 * 0615 * auto it0 = forest.insert(childBegin(forest), 0); 0616 * auto it8 = forest.insert(childEnd(forest), 8); 0617 * 0618 * auto it1 = forest.insert(childEnd(it0), 1); 0619 * auto it2 = forest.insert(childEnd(it0), 2); 0620 * auto it3 = forest.insert(childEnd(it0), 3); 0621 * auto it4 = forest.insert(childEnd(it0), 4); 0622 * 0623 * auto it5 = forest.insert(childEnd(it3), 5); 0624 * 0625 * auto it6 = forest.insert(childEnd(it5), 6); 0626 * auto it7 = forest.insert(childEnd(it5), 7); 0627 * 0628 * auto it9 = forest.insert(childEnd(it8), 9); 0629 * auto it10 = forest.insert(childEnd(it8), 10); 0630 * 0631 * // iterate through all elements of the forest 0632 * for (auto it = subtreeBegin(forest); it != subtreeEnd(forest); ++it) { 0633 * qDebug() << *it << it.state(); 0634 * } 0635 * // prints: 0,1,2,3,5,6,7,4,8,9,10 0636 * 0637 * \endcode 0638 * 0639 * 0640 */ 0641 0642 template <typename T> 0643 class Forest 0644 { 0645 public: 0646 Forest() 0647 { 0648 } 0649 0650 ~Forest() { 0651 erase(childBegin(), childEnd()); 0652 } 0653 0654 using child_iterator = ChildIterator<T>; 0655 using composition_iterator = CompositionIterator<T>; 0656 using hierarchy_iterator = HierarchyIterator<T>; 0657 using iterator = DepthFirstIterator<T, Enter>; 0658 using depth_first_tail_iterator = DepthFirstIterator<T, Leave>; 0659 0660 iterator begin() { 0661 return iterator(m_root.firstChild); 0662 } 0663 0664 iterator end() { 0665 return iterator(nullptr); 0666 } 0667 0668 depth_first_tail_iterator depthFirstTailBegin() { 0669 return tailSubtreeBegin(begin()); 0670 } 0671 0672 depth_first_tail_iterator depthFirstTailEnd() { 0673 return tailSubtreeEnd(end()); 0674 } 0675 0676 child_iterator childBegin() { 0677 return child_iterator(m_root.firstChild, &m_root); 0678 } 0679 0680 child_iterator childEnd() { 0681 return child_iterator(nullptr, &m_root); 0682 } 0683 0684 composition_iterator compositionBegin() { 0685 return composition_iterator(m_root.firstChild); 0686 } 0687 0688 composition_iterator compositionEnd() { 0689 return composition_iterator(nullptr); 0690 } 0691 0692 /** 0693 * @brief Inserts element \p value into position \p pos. 0694 * \p value becomes the child of the same parent as \p pos 0695 * and is placed right before \p pos. 0696 * @return iterator pointing to the inserted element 0697 */ 0698 template <typename X> 0699 child_iterator insert(child_iterator pos, X &&value) { 0700 Node<T> *node = new Node<T>(std::forward<X>(value)); 0701 0702 linkNode(pos, node); 0703 0704 return child_iterator(node, node->parent); 0705 } 0706 0707 /** 0708 * @brief Removes element at position \p pos. 0709 * If \p pos is 'end', then result is undefined. 0710 * @return the element following \p pos 0711 */ 0712 child_iterator erase(child_iterator pos) { 0713 child_iterator nextNode = std::next(pos); 0714 Node<T> *node = pos.node(); 0715 0716 Node<T> *lastNode = node; 0717 for (auto it = tailSubtreeBegin(pos); it != tailSubtreeEnd(pos); ++it) { 0718 0719 if (lastNode != node) { 0720 delete lastNode; 0721 } 0722 lastNode = it.node(); 0723 } 0724 0725 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(lastNode == node, pos); 0726 0727 unlinkNode(node); 0728 delete node; 0729 0730 return nextNode; 0731 } 0732 0733 /** 0734 * @brief erases all elements from \p pos to \p end (excluding \p end) 0735 * @return \p end 0736 */ 0737 child_iterator erase(child_iterator pos, child_iterator end) { 0738 while (pos != end) { 0739 pos = erase(pos); 0740 } 0741 return pos; 0742 } 0743 0744 /** 0745 * @brief move a subtree to new position 0746 * Moves \p subtree into a new position pointer by \p newPos. \p newPos 0747 * must not be inside the subtree, otherwise cycling links may appear. 0748 * @return iterator to a new position of \p subtree 0749 */ 0750 child_iterator move(child_iterator subtree, child_iterator newPos) { 0751 // sanity check for cycling move 0752 for (auto it = hierarchyBegin(newPos); it != hierarchyEnd(newPos); ++it) { 0753 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(it.node() != subtree.node(), subtree); 0754 } 0755 0756 Node<T> *node = subtree.node(); 0757 unlinkNode(node); 0758 0759 node->prevSibling = nullptr; 0760 node->nextSibling = nullptr; 0761 node->parent = nullptr; 0762 0763 linkNode(newPos, node); 0764 return child_iterator(node, node->parent); 0765 } 0766 0767 private: 0768 0769 inline void linkBefore(Node<T> *node, Node<T> *beforeMe) { 0770 if (beforeMe) { 0771 node->nextSibling = beforeMe; 0772 beforeMe->prevSibling = node; 0773 } 0774 } 0775 0776 inline void linkAfter(Node<T> *node, Node<T> *afterMe) { 0777 if (afterMe) { 0778 node->prevSibling = afterMe; 0779 afterMe->nextSibling = node; 0780 } 0781 } 0782 0783 inline void linkNode(child_iterator pos, Node<T> *node) { 0784 Node<T> *nextNode = pos.node(); 0785 RootNode<T> *parentNode = pos.m_parent; 0786 0787 Node<T> *prevNode = nextNode ? 0788 nextNode->prevSibling : 0789 parentNode ? parentNode->lastChild : m_root.lastChild; 0790 0791 linkAfter(node, prevNode); 0792 linkBefore(node, nextNode); 0793 0794 KIS_SAFE_ASSERT_RECOVER_RETURN(parentNode); 0795 if (!nextNode) { 0796 parentNode->lastChild = node; 0797 } 0798 0799 if (nextNode == parentNode->firstChild) { 0800 parentNode->firstChild = node; 0801 } 0802 node->parent = parentNode; 0803 } 0804 0805 inline void unlinkNode(Node<T> *node) { 0806 RootNode<T> *parentNode = node->parent; 0807 0808 if (node->nextSibling) { 0809 node->nextSibling->prevSibling = node->prevSibling; 0810 } 0811 0812 if (node->prevSibling) { 0813 node->prevSibling->nextSibling = node->nextSibling; 0814 } 0815 0816 KIS_SAFE_ASSERT_RECOVER_RETURN(parentNode); 0817 if (parentNode->firstChild == node) { 0818 parentNode->firstChild = node->nextSibling; 0819 } 0820 0821 if (parentNode->lastChild == node) { 0822 parentNode->lastChild = node->prevSibling; 0823 } 0824 } 0825 private: 0826 RootNode<T> m_root; 0827 }; 0828 0829 template <typename T> 0830 typename Forest<T>::child_iterator childBegin(Forest<T> &forest) 0831 { 0832 return forest.childBegin(); 0833 } 0834 0835 template <typename T> 0836 typename Forest<T>::child_iterator childEnd(Forest<T> &forest) 0837 { 0838 return forest.childEnd(); 0839 } 0840 0841 template <typename T> 0842 typename Forest<T>::composition_iterator compositionBegin(Forest<T> &forest) 0843 { 0844 return forest.compositionBegin(); 0845 } 0846 0847 template <typename T> 0848 typename Forest<T>::composition_iterator compositionEnd(Forest<T> &forest) 0849 { 0850 return forest.compositionEnd(); 0851 } 0852 0853 template <typename T> 0854 typename Forest<T>::depth_first_tail_iterator tailSubtreeBegin(Forest<T> &forest) 0855 { 0856 return forest.depthFirstTailBegin(); 0857 } 0858 0859 template <typename T> 0860 typename Forest<T>::depth_first_tail_iterator tailSubtreeEnd(Forest<T> &forest) 0861 { 0862 return forest.depthFirstTailEnd(); 0863 } 0864 0865 template <typename T> 0866 int depth(typename Forest<T>::child_iterator beginIt, 0867 typename Forest<T>::child_iterator endIt) 0868 { 0869 0870 int currentDepth = 0; 0871 0872 for (auto it = beginIt; it != endIt; ++it) { 0873 currentDepth = std::max(currentDepth, 1 + depth<T>(childBegin(it), childEnd(it))); 0874 } 0875 0876 return currentDepth; 0877 } 0878 0879 template <typename T> 0880 int depth(Forest<T> &forest) { 0881 return depth<T>(childBegin(forest), childEnd(forest)); 0882 } 0883 0884 template <typename T> 0885 int size(Forest<T> &forest) { 0886 return std::distance(begin(forest), end(forest)); 0887 } 0888 0889 using std::begin; 0890 using std::end; 0891 using std::make_reverse_iterator; 0892 0893 using std::find; 0894 using std::find_if; 0895 using std::find_if_not; 0896 } 0897 0898 template<typename T> 0899 using KisForest = KisForestDetail::Forest<T>; 0900 0901 0902 #endif // KISFOREST_H