File indexing completed on 2024-05-19 04:25:08

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, bool is_const>
0062 class BaseIterator :
0063         public boost::iterator_facade <BaseClass,
0064                                        T,
0065                                        Tag,
0066                                        std::add_lvalue_reference_t<
0067                                                        std::add_const_if_t<is_const, T>>>
0068 {
0069 public:
0070     using value_type = T;
0071     using NodeType = std::add_const_if_t<is_const, Node<T>>;
0072 
0073     BaseIterator(NodeType *node)
0074         : m_node(node)
0075     {
0076     }
0077 
0078     NodeType* node() const {
0079         return m_node;
0080     }
0081 
0082 private:
0083     friend class boost::iterator_core_access;
0084 
0085     typename std::iterator_traits<BaseIterator>::reference dereference() const {
0086         KIS_ASSERT(m_node);
0087         return m_node->value;
0088     }
0089 
0090     bool equal(const BaseClass &other) const {
0091         return m_node == other.m_node;
0092     }
0093 
0094 protected:
0095     NodeType *m_node;
0096 };
0097 
0098 
0099 /*************************************************************************/
0100 /*               ChildIterator                                           */
0101 /*************************************************************************/
0102 
0103 /**
0104  * Child iterator is used to traverse all the children of the current node.
0105  * It models \c BidirectionalIterator concept, so you can traverse with it in both
0106  * directions.
0107  *
0108  * \code{.cpp}
0109  *
0110  * // Forest:
0111  * //
0112  * // 0 1
0113  * //   2
0114  * //   3 5 6
0115  * //       7
0116  * //   4
0117  * // 8 9
0118  * //   10
0119  *
0120  * KisForest<int>::iterator it0 = findValue(forest, 0);
0121  *
0122  * // iterate through all the children of '0'
0123  * for (auto it = childBegin(it0); it != childEnd(it0); ++it) {
0124  *     qDebug() << *it;
0125  * }
0126  * // prints: 1,2,3,4
0127  *
0128  * \endcode
0129  *
0130  * It is also possible to convert any iterator type into child iterator
0131  * via siblingCurrent() function.
0132  *
0133  * \code{.cpp}
0134  *
0135  * // Forest:
0136  * //
0137  * // 0 1
0138  * //   2
0139  * //   3 5 6
0140  * //       7
0141  * //   4
0142  * // 8 9
0143  * //   10
0144  *
0145  * KisForest<int>::iterator it2 = findValue(forest, 2);
0146  *
0147  * // iterate the children of '0' from '2' to '4'
0148  * for (auto it = siblingCurrent(it2); it != siblingEnd(it2); ++it) {
0149  *     qDebug() << *it;
0150  * }
0151  * // prints: 2,3,4
0152  *
0153  * \endcode
0154  *
0155  * WARNING: converting end() iterator to other iterator types currently leads
0156  *          to undefined behavior.
0157  */
0158 
0159 template <typename T, bool is_const>
0160 class ChildIterator :
0161         public BaseIterator <ChildIterator<T, is_const>,
0162                              T,
0163                              boost::bidirectional_traversal_tag,
0164                              is_const>
0165 {
0166     using BaseClass =
0167         BaseIterator <ChildIterator<T, is_const>,
0168                      T,
0169                      boost::bidirectional_traversal_tag,
0170                      is_const>;
0171 
0172 public:
0173     using RootNodeType = std::add_const_if_t<is_const, RootNode<T>>;
0174     using NodeType = typename BaseClass::NodeType;
0175 
0176     ChildIterator(NodeType *node, RootNodeType *parent, int offsetToParent)
0177         : BaseClass(node),
0178           m_parent(parent),
0179           m_offsetToParent(offsetToParent)
0180     {
0181     }
0182 
0183     operator ChildIterator<T, true>() const {
0184         return ChildIterator<T, true>(this->m_node, m_parent, m_offsetToParent);
0185     }
0186 
0187 private:
0188     friend class boost::iterator_core_access;
0189     template <typename X, bool c>
0190     friend ChildIterator<X, c> parent(const ChildIterator<X, c> &it);
0191     template <typename X, bool c>
0192     friend ChildIterator<X, c> siblingBegin(const ChildIterator<X, c> &it);
0193     template <typename X, bool c>
0194     friend ChildIterator<X, c> siblingEnd(const ChildIterator<X, c> &it);
0195     template <typename X, bool c>
0196     friend ChildIterator<X, c> childBegin(const ChildIterator<X, c> &it);
0197     template <typename X, bool c>
0198     friend ChildIterator<X, c> childEnd(const ChildIterator<X, c> &it);
0199 
0200     template <typename X, bool c>
0201     friend QDebug operator<<(QDebug dbg, const ChildIterator<X, c> &it);
0202     template <typename X> friend class Forest;
0203 
0204     void increment() {
0205         this->m_node = this->m_node->nextSibling;
0206     }
0207 
0208     void decrement() {
0209         this->m_node =
0210             this->m_node ?
0211             this->m_node->prevSibling :
0212             (m_parent && m_offsetToParent == 0) ? m_parent->lastChild : nullptr;
0213     }
0214 
0215     bool equal(const ChildIterator<T, is_const> &other) const {
0216         return this->m_node == other.m_node &&
0217             (this->m_node ||
0218              (this->m_parent == other.m_parent &&
0219               this->m_offsetToParent == other.m_offsetToParent));
0220     }
0221 
0222 private:
0223     RootNodeType *m_parent;
0224     int m_offsetToParent;
0225 };
0226 
0227 template <typename value_type, bool is_const>
0228 QDebug operator<<(QDebug dbg, const ChildIterator<value_type, is_const> &it)
0229 {
0230     if (it.node()) {
0231         dbg.nospace() << "ChildIterator(" << it.node() << "(" <<  it.node()->value << ")" << ", parent:" << it.m_parent << ")";
0232     } else {
0233         dbg.nospace() << "ChildIterator(" << "nullptr" << ", parent:" << it.m_parent << ", offset:" << it.m_offsetToParent << ")";
0234     }
0235     return dbg;
0236 }
0237 
0238 
0239 template <typename value_type, bool is_const>
0240 ChildIterator<value_type, is_const> siblingCurrent(ChildIterator<value_type, is_const> it)
0241 {
0242     return it;
0243 }
0244 
0245 template <typename value_type, bool is_const>
0246 ChildIterator<value_type, is_const> siblingBegin(const ChildIterator<value_type, is_const> &it)
0247 {
0248     using RootNodeType = typename ChildIterator<value_type, is_const>::RootNodeType;
0249     if (!it.node() && it.m_offsetToParent != 0) return it;
0250     RootNodeType *parent = it.m_parent;
0251     return ChildIterator<value_type, is_const>(parent ? parent->firstChild : nullptr, parent, 0);
0252 }
0253 
0254 template <typename value_type, bool is_const>
0255 ChildIterator<value_type, is_const> siblingEnd(const ChildIterator<value_type, is_const> &it)
0256 {
0257     if (!it.node() && it.m_offsetToParent != 0) return it;
0258     return ChildIterator<value_type, is_const>(nullptr, it.m_parent, 0);
0259 }
0260 
0261 template <typename Iterator,
0262           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0263           typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
0264 ResultIterator siblingCurrent(Iterator it)
0265 {
0266     // TODO: conversion of an end-iterator into a child iterator is still not implemented
0267     //       and considered as UB. We need to implement all special-cases for that.
0268     KIS_SAFE_ASSERT_RECOVER_NOOP(it.node());
0269 
0270     return ResultIterator(it.node(), it.node() ? it.node()->parent : nullptr, 0);
0271 }
0272 
0273 template <typename Iterator,
0274           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0275           typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
0276 ResultIterator siblingBegin(Iterator it)
0277 {
0278     return siblingBegin(siblingCurrent(it));
0279 }
0280 
0281 template <typename Iterator,
0282           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0283           typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
0284 ResultIterator siblingEnd(Iterator it)
0285 {
0286     return siblingEnd(siblingCurrent(it));
0287 }
0288 
0289  template <typename value_type, bool is_const>
0290  ChildIterator<value_type, is_const> childBegin(const ChildIterator<value_type, is_const> &it)
0291 {
0292     if (it.node()) {
0293         return ChildIterator<value_type, is_const>(it.node()->firstChild, it.node(), 0);
0294     } else {
0295         return ChildIterator<value_type, is_const>(nullptr, it.m_parent, it.m_offsetToParent + 1);
0296     }
0297 }
0298 
0299 template <typename value_type, bool is_const>
0300 ChildIterator<value_type, is_const> childEnd(const ChildIterator<value_type, is_const> &it)
0301 {
0302     if (it.node()) {
0303         return ChildIterator<value_type, is_const>(nullptr, it.node(), 0);
0304     } else {
0305         return ChildIterator<value_type, is_const>(nullptr, it.m_parent, it.m_offsetToParent + 1);
0306     }
0307 }
0308 
0309 template <typename Iterator,
0310           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0311           typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
0312 ResultIterator childBegin(Iterator it)
0313 {
0314     return childBegin(siblingCurrent(it));
0315 }
0316 
0317 template <typename Iterator,
0318           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0319           typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
0320 ResultIterator childEnd(Iterator it)
0321 {
0322     return childEnd(siblingCurrent(it));
0323 }
0324 
0325 
0326 template <typename value_type, bool is_const>
0327 ChildIterator<value_type, is_const> parent(const ChildIterator<value_type, is_const> &it)
0328 {
0329     if (it.m_parent->isRoot()) {
0330         return ChildIterator<value_type, is_const>(nullptr, it.m_parent, qMax(-1, it.m_offsetToParent - 1));
0331     } else if (it.m_offsetToParent == 0) {
0332         using NodeType = typename ChildIterator<value_type, is_const>::NodeType;
0333         NodeType *parentNode = static_cast<NodeType*>(it.m_parent);
0334         return ChildIterator<value_type, is_const>(parentNode, parentNode->parent, 0);
0335     } else {
0336         return ChildIterator<value_type, is_const>(nullptr, it.m_parent, it.m_offsetToParent - 1);
0337     }
0338 }
0339 
0340 template <typename T, bool is_const>
0341 inline bool isEnd(const ChildIterator<T, is_const> &it) {
0342     return !it.node();
0343 }
0344 
0345 
0346 /*************************************************************************/
0347 /*               HierarchyIterator                                       */
0348 /*************************************************************************/
0349 
0350 /**
0351  * Hierarchy iterator is used to traverse from the current node to the root
0352  * of the current subtree of the forest. It models \c ForwardIterator concept.
0353  *
0354  * \code{.cpp}
0355  *
0356  * // Forest:
0357  * //
0358  * // 0 1
0359  * //   2
0360  * //   3 5 6
0361  * //       7
0362  * //   4
0363  * // 8 9
0364  * //   10
0365  *
0366  * KisForest<int>::iterator nodeIt = findValue(forest, 5);
0367  *
0368  * // print all the parent nodes for nodeIt, including nodeIt itself
0369  * for (auto it = hierarchyBegin(nodeIt); it != hierarchyEnd(nodeIt); ++it) {
0370  *     qDebug() << *it;
0371  * }
0372  * // prints: 5,3,0
0373  *
0374  * \endcode
0375  *
0376  * WARNING: converting end() iterator to other iterator types currently leads
0377  *          to undefined behavior.
0378  */
0379 
0380 template <typename T, bool is_const>
0381 class HierarchyIterator :
0382         public BaseIterator <HierarchyIterator<T, is_const>,
0383                              T,
0384                              boost::forward_traversal_tag,
0385                              is_const>
0386 {
0387     using BaseClass = BaseIterator <HierarchyIterator<T, is_const>,
0388                                    T,
0389                                    boost::forward_traversal_tag,
0390                                    is_const>;
0391 public:
0392     using RootNodeType = std::add_const_if_t<is_const, RootNode<T>>;
0393     using NodeType = typename BaseClass::NodeType;
0394 
0395     HierarchyIterator(NodeType *node)
0396         : BaseClass(node)
0397     {
0398     }
0399 
0400     operator HierarchyIterator<T, true>() const {
0401         return HierarchyIterator<T, true>(this->m_node);
0402     }
0403 
0404 private:
0405     friend class boost::iterator_core_access;
0406 
0407     void increment() {
0408         RootNodeType *parent = this->m_node->parent;
0409         this->m_node =
0410             static_cast<NodeType*>(
0411                 parent && !parent->isRoot() ?
0412                 parent : nullptr);
0413     }
0414 };
0415 
0416 template <typename Iterator,
0417           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0418           typename ResultIterator = HierarchyIterator<typename Iterator::value_type, is_const>>
0419 ResultIterator hierarchyBegin(Iterator it)
0420 {
0421     return ResultIterator(it.node());
0422 }
0423 
0424 template <typename Iterator,
0425           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0426           typename ResultIterator = HierarchyIterator<typename Iterator::value_type, is_const>>
0427 ResultIterator hierarchyEnd(Iterator it)
0428 {
0429     Q_UNUSED(it);
0430     return ResultIterator(nullptr);
0431 }
0432 
0433 
0434 /*************************************************************************/
0435 /*               CompositionIterator                                     */
0436 /*************************************************************************/
0437 
0438 /**
0439  * Composition iterator is used to traverse entire child-subtree of the node
0440  * recursively in depth-first order. Every node it entered twice: first time, when
0441  * subtree is entered; second time, when subtree is left. To check the current
0442  * state of the iterator (Enter or Leave) use \c it.state() call.
0443  *
0444  * Iterator models \c ForwardIterator concept.
0445  *
0446  * \code{.cpp}
0447  *
0448  * // Forest:
0449  * //
0450  * // 0 1
0451  * //   2
0452  * //   3 5 6
0453  * //       7
0454  * //   4
0455  * // 8 9
0456  * //   10
0457  *
0458  * KisForest<int>::iterator it3 = findValue(forest, 3);
0459  *
0460  * // iterate through all the children of '3' recursively
0461  * for (auto it = compositionBegin(it3); it != compositionEnd(it3); ++it) {
0462  *     qDebug() << *it << it.state();
0463  * }
0464  * // prints: (3, Enter)
0465  * //           (5, Enter)
0466  * //             (6, Enter)
0467  * //             (6, Leave)
0468  * //             (7, Enter)
0469  * //             (7, Leave)
0470  * //           (5, Leave)
0471  * //         (3, Leave)
0472  *
0473  * \endcode
0474  *
0475  * WARNING: converting end() iterator to other iterator types currently leads
0476  *          to undefined behavior.
0477  */
0478 
0479 enum TraversalState {
0480     Enter,
0481     Leave
0482 };
0483 
0484 template <typename T, bool is_const>
0485 class CompositionIterator :
0486         public boost::iterator_adaptor<
0487             CompositionIterator<T, is_const>,
0488             ChildIterator<T, is_const>,
0489             boost::use_default,
0490             boost::forward_traversal_tag>
0491 {
0492     using BaseClass = boost::iterator_adaptor<
0493         CompositionIterator<T, is_const>,
0494         ChildIterator<T, is_const>,
0495         boost::use_default,
0496         boost::forward_traversal_tag>;
0497 
0498     using BaseIteratorType = typename CompositionIterator::base_type;
0499 
0500 public:
0501     using traversal_state = TraversalState;
0502     using RootNodeType = typename BaseIteratorType::RootNodeType;
0503     using NodeType = typename BaseIteratorType::NodeType;
0504 
0505     NodeType* node() const {
0506         return this->base().node();
0507     }
0508 
0509 public:
0510     CompositionIterator(NodeType *node, traversal_state state = Enter)
0511         : BaseClass(BaseIteratorType(node, node ? node->parent : nullptr, 0)),
0512           m_state(state)
0513     {
0514     }
0515 
0516     traversal_state state() const {
0517         return m_state;
0518     }
0519 
0520     operator CompositionIterator<T, true>() const {
0521         return CompositionIterator<T, true>(this->m_node, this->m_state);
0522     }
0523 
0524 private:
0525     friend class boost::iterator_core_access;
0526 
0527     bool tryJumpToPos(typename CompositionIterator::base_type it,
0528                       TraversalState newState) {
0529         bool result = false;
0530 
0531         if (!isEnd(it)) {
0532             this->base_reference() = it;
0533             result = true;
0534             m_state = newState;
0535         }
0536 
0537         return result;
0538     }
0539 
0540     void increment() {
0541         switch (m_state) {
0542         case Enter:
0543             if (tryJumpToPos(childBegin(this->base()), Enter)) return;
0544             if (tryJumpToPos(this->base(), Leave)) return;
0545             break;
0546         case Leave:
0547             if (tryJumpToPos(std::next(this->base()), Enter)) return;
0548             if (tryJumpToPos(parent(this->base()), Leave)) return;
0549             break;
0550         }
0551 
0552         this->base_reference() = BaseIteratorType(nullptr, nullptr, 0);
0553     }
0554 
0555 private:
0556     traversal_state m_state = Enter;
0557 };
0558 
0559 template <typename Iterator,
0560          bool is_const = std::is_const_v<typename Iterator::NodeType>,
0561          typename ResultIterator = CompositionIterator<typename Iterator::value_type, is_const>>
0562 ResultIterator compositionBegin(Iterator it)
0563 {
0564     return ResultIterator(it.node(), Enter);
0565 }
0566 
0567 template <typename Iterator,
0568          bool is_const = std::is_const_v<typename Iterator::NodeType>,
0569          typename ResultIterator = CompositionIterator<typename Iterator::value_type, is_const>>
0570 ResultIterator compositionEnd(Iterator it)
0571 {
0572     return it.node() ?
0573         std::next(ResultIterator(it.node(), Leave)) :
0574         ResultIterator(nullptr, Leave);
0575 }
0576 
0577 
0578 /*************************************************************************/
0579 /*               DepthFirstIterator                                      */
0580 /*************************************************************************/
0581 
0582 /**
0583  * Depth-first iterator is used to traverse entire child-subtree of the node
0584  * recursively in depth-first order. Every node is entered only once. It
0585  * implements standard recursion iteration:
0586  *
0587  *   * \c DepthFirstIterator<T, Enter> implements head-recursion, that is,
0588  *     the node is visited *before* its children
0589  *
0590  *   * \c DepthFirstIterator<T, Leave> implements tail-recursion, that is,
0591  *     the node is visited *after* its children
0592  *
0593  * Use \c subtreeBegin() and \c subtreeEnd() for head-recursion and \c tailSubtreeBegin() and
0594  * \c tailSubtreeEnd() for tail-recursion.
0595  *
0596  * Iterator models \c ForwardIterator concept.
0597  *
0598  * \code{.cpp}
0599  *
0600  * // Forest:
0601  * //
0602  * // 0 1
0603  * //   2
0604  * //   3 5 6
0605  * //       7
0606  * //   4
0607  * // 8 9
0608  * //   10
0609  *
0610  * KisForest<int>::iterator it3 = findValue(forest, 3);
0611  *
0612  * // iterate through all the children of '3' in head-recursive way
0613  * for (auto it = subtreeBegin(it3); it != subtreeEnd(it3); ++it) {
0614  *     qDebug() << *it << it.state();
0615  * }
0616  * // prints: 3, 5, 6, 7
0617  *
0618  * // iterate through all the children of '3' in tail-recursive way
0619  * for (auto it = tailSubtreeBegin(it3); it != tailSubtreeEnd(it3); ++it) {
0620  *     qDebug() << *it << it.state();
0621  * }
0622  * // prints: 6, 7, 5, 3
0623  *
0624  * \endcode
0625  *
0626  * WARNING: converting end() iterator to other iterator types currently leads
0627  *          to undefined behavior.
0628  */
0629 
0630 template <typename T, TraversalState visit_on, bool is_const>
0631 class DepthFirstIterator :
0632         public boost::iterator_adaptor<
0633             DepthFirstIterator<T, visit_on, is_const>,
0634             CompositionIterator<T, is_const>,
0635             boost::use_default,
0636             boost::forward_traversal_tag>
0637 {
0638     using BaseClass = boost::iterator_adaptor<
0639         DepthFirstIterator<T, visit_on, is_const>,
0640         CompositionIterator<T, is_const>,
0641         boost::use_default,
0642         boost::forward_traversal_tag>;
0643 
0644     using BaseIteratorType = typename DepthFirstIterator::base_type;
0645 
0646 public:
0647     using traversal_state = TraversalState;
0648     using RootNodeType = typename BaseIteratorType::RootNodeType;
0649     using NodeType = typename BaseIteratorType::NodeType;
0650 
0651     DepthFirstIterator(NodeType *node,
0652                        traversal_state state = traversal_state::Enter,
0653                        bool shouldSkipToBegin = false)
0654         : BaseClass(BaseIteratorType(node, state))
0655     {
0656         if (shouldSkipToBegin) {
0657             skipToState(visit_on);
0658         }
0659     }
0660 
0661     NodeType* node() const {
0662         return this->base().node();
0663     }
0664 
0665     operator DepthFirstIterator<T, visit_on, true>() const {
0666         return DepthFirstIterator<T, visit_on, true>(this->m_node, this->m_state);
0667     }
0668 
0669 private:
0670     friend class boost::iterator_core_access;
0671 
0672     void increment() {
0673         this->base_reference()++;
0674         skipToState(visit_on);
0675     }
0676 
0677     void skipToState(TraversalState state) {
0678         while (this->base().node() && this->base().state() != state) {
0679             this->base_reference()++;
0680         }
0681     }
0682 
0683 };
0684 
0685 template <typename Iterator,
0686           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0687           typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter, is_const>>
0688 ResultIterator subtreeBegin(Iterator it)
0689 {
0690     return ResultIterator(it.node(), Enter);
0691 }
0692 
0693 template <typename Iterator,
0694           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0695           typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter, is_const>>
0696 ResultIterator subtreeEnd(Iterator it)
0697 {
0698     return it.node() ?
0699         std::next(ResultIterator(it.node(), Leave)) :
0700         ResultIterator(nullptr, Leave);
0701 }
0702 
0703 template <typename Iterator,
0704           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0705           typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave, is_const>>
0706 ResultIterator tailSubtreeBegin(Iterator it)
0707 {
0708     return ResultIterator(it.node(), Enter, true);
0709 }
0710 
0711 template <typename Iterator,
0712           bool is_const = std::is_const_v<typename Iterator::NodeType>,
0713           typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave, is_const>>
0714 ResultIterator tailSubtreeEnd(Iterator it)
0715 {
0716     return it.node() ?
0717         std::next(ResultIterator(it.node(), Leave)) :
0718         ResultIterator(nullptr, Leave);
0719 }
0720 
0721 
0722 /*************************************************************************/
0723 /*               Forest                                                  */
0724 /*************************************************************************/
0725 
0726 /**
0727  * Forest implements a container for composing tree-like structures from
0728  * arbitrary objects.
0729  *
0730  * All add/remove operations are implemented via child_iterator. You can
0731  * convert any iterator type into a child iterator via \c siblingCurrent()
0732  * function.
0733  *
0734  * * \code{.cpp}
0735  *
0736  * // Forest:
0737  * //
0738  * // 0 1
0739  * //   2
0740  * //   3 5 6
0741  * //       7
0742  * //   4
0743  * // 8 9
0744  * //   10
0745  *
0746  * KisForest<int> forest;
0747  *
0748  * auto it0 = forest.insert(childBegin(forest), 0);
0749  * auto it8 = forest.insert(childEnd(forest), 8);
0750  *
0751  * auto it1 = forest.insert(childEnd(it0), 1);
0752  * auto it2 = forest.insert(childEnd(it0), 2);
0753  * auto it3 = forest.insert(childEnd(it0), 3);
0754  * auto it4 = forest.insert(childEnd(it0), 4);
0755  *
0756  * auto it5 = forest.insert(childEnd(it3), 5);
0757  *
0758  * auto it6 = forest.insert(childEnd(it5), 6);
0759  * auto it7 = forest.insert(childEnd(it5), 7);
0760  *
0761  * auto it9 = forest.insert(childEnd(it8), 9);
0762  * auto it10 = forest.insert(childEnd(it8), 10);
0763  *
0764  * // iterate through all elements of the forest
0765  * for (auto it = subtreeBegin(forest); it != subtreeEnd(forest); ++it) {
0766  *     qDebug() << *it << it.state();
0767  * }
0768  * // prints: 0,1,2,3,5,6,7,4,8,9,10
0769  *
0770  * \endcode
0771  *
0772  *
0773  */
0774 
0775 template <typename T>
0776 class Forest
0777 {
0778 public:
0779     Forest()
0780     {
0781     }
0782 
0783     ~Forest() {
0784         erase(childBegin(), childEnd());
0785     }
0786 
0787     Forest(const Forest<T> &rhs) {
0788         for (auto it = rhs.childBegin(); it != rhs.childEnd(); ++it) {
0789             auto cloneIt = this->insert(this->childEnd(), *it);
0790             cloneChildren(it, cloneIt);
0791         }
0792     }
0793 
0794     using value_type = T;
0795 
0796     using child_iterator = ChildIterator<T, false>;
0797     using const_child_iterator = ChildIterator<T, true>;
0798 
0799     using composition_iterator = CompositionIterator<T, false>;
0800     using const_composition_iterator = CompositionIterator<T, true>;
0801 
0802     using hierarchy_iterator = HierarchyIterator<T, false>;
0803     using const_hierarchy_iterator = HierarchyIterator<T, true>;
0804 
0805     using iterator = DepthFirstIterator<T, Enter, false>;
0806     using const_iterator = DepthFirstIterator<T, Enter, true>;
0807 
0808     using depth_first_tail_iterator = DepthFirstIterator<T, Leave, false>;
0809     using const_depth_first_tail_iterator = DepthFirstIterator<T, Leave, true>;
0810 
0811     iterator begin() {
0812         return beginImpl(*this);
0813     }
0814 
0815     iterator end() {
0816         return endImpl(*this);
0817     }
0818 
0819     const_iterator begin() const {
0820         return beginImpl(*this);
0821     }
0822 
0823     const_iterator end() const {
0824         return endImpl(*this);
0825     }
0826 
0827     const_iterator constBegin() const {
0828         return beginImpl(*this);
0829     }
0830 
0831     const_iterator constEnd() const {
0832         return endImpl(*this);
0833     }
0834 
0835     depth_first_tail_iterator depthFirstTailBegin() {
0836         return tailSubtreeBegin(begin());
0837     }
0838 
0839     depth_first_tail_iterator depthFirstTailEnd() {
0840         return tailSubtreeEnd(end());
0841     }
0842 
0843     const_depth_first_tail_iterator depthFirstTailBegin() const {
0844         return tailSubtreeBegin(constBegin());
0845     }
0846 
0847     const_depth_first_tail_iterator depthFirstTailEnd() const {
0848         return tailSubtreeEnd(constEnd());
0849     }
0850 
0851     const_depth_first_tail_iterator constDepthFirstTailBegin() const {
0852         return tailSubtreeBegin(constBegin());
0853     }
0854 
0855     const_depth_first_tail_iterator constDepthFirstTailEnd() const {
0856         return tailSubtreeEnd(constEnd());
0857     }
0858 
0859     child_iterator childBegin() {
0860         return childBeginImpl(*this);
0861     }
0862 
0863     child_iterator childEnd() {
0864         return childEndImpl(*this);
0865     }
0866 
0867     child_iterator parentEnd() {
0868         return parentEndImpl(*this);
0869     }
0870 
0871     const_child_iterator childBegin() const {
0872         return childBeginImpl(*this);
0873     }
0874 
0875     const_child_iterator childEnd() const {
0876         return childEndImpl(*this);
0877     }
0878 
0879     const_child_iterator parentEnd() const {
0880         return parentEndImpl(*this);
0881     }
0882 
0883     const_child_iterator constChildBegin() const {
0884         return childBeginImpl(*this);
0885     }
0886 
0887     const_child_iterator constChildEnd() const {
0888         return childEndImpl(*this);
0889     }
0890 
0891     const_child_iterator constParentEnd() const {
0892         return parentEndImpl(*this);
0893     }
0894 
0895     composition_iterator compositionBegin() {
0896         return compositionBeginImpl(*this);
0897     }
0898 
0899     composition_iterator compositionEnd() {
0900         return compositionEndImpl(*this);
0901     }
0902 
0903     const_composition_iterator compositionBegin() const {
0904         return compositionBeginImpl(*this);
0905     }
0906 
0907     const_composition_iterator compositionEnd() const {
0908         return compositionEndImpl(*this);
0909     }
0910 
0911     const_composition_iterator constCompositionBegin() const {
0912         return compositionBeginImpl(*this);
0913     }
0914 
0915     const_composition_iterator constCompositionEnd() const {
0916         return compositionEndImpl(*this);
0917     }
0918 
0919     /**
0920      * @brief Inserts element \p value into position \p pos.
0921      * \p value becomes the child of the same parent as \p pos
0922      * and is placed right before \p pos.
0923      * @return iterator pointing to the inserted element
0924      */
0925     template <typename X>
0926     child_iterator insert(child_iterator pos, X &&value) {
0927         Node<T> *node = new Node<T>(std::forward<X>(value));
0928 
0929         linkNode(pos, node);
0930 
0931         return child_iterator(node, node->parent, 0);
0932     }
0933 
0934     /**
0935      * @brief Removes element at position \p pos.
0936      * If \p pos is 'end', then result is undefined.
0937      * @return the element following \p pos
0938      */
0939     child_iterator erase(child_iterator pos) {
0940         child_iterator nextNode = std::next(pos);
0941         Node<T> *node = pos.node();
0942 
0943         Node<T> *lastNode = node;
0944         for (auto it = tailSubtreeBegin(pos); it != tailSubtreeEnd(pos); ++it) {
0945 
0946             if (lastNode != node) {
0947                 delete lastNode;
0948             }
0949             lastNode = it.node();
0950         }
0951 
0952         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(lastNode == node, pos);
0953 
0954         unlinkNode(node);
0955         delete node;
0956 
0957         return nextNode;
0958     }
0959 
0960     /**
0961      * @brief erases all elements from \p pos to \p end (excluding \p end)
0962      * @return \p end
0963      */
0964     child_iterator erase(child_iterator pos, child_iterator end) {
0965         while (pos != end) {
0966             pos = erase(pos);
0967         }
0968         return pos;
0969     }
0970 
0971     /**
0972      * @brief move a subtree to new position
0973      * Moves \p subtree into a new position pointer by \p newPos. \p newPos
0974      * must not be inside the subtree, otherwise cycling links may appear.
0975      * @return iterator to a new position of \p subtree
0976      */
0977     child_iterator move(child_iterator subtree, child_iterator newPos) {
0978         // sanity check for cycling move
0979         for (auto it = hierarchyBegin(newPos); it != hierarchyEnd(newPos); ++it) {
0980             KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(it.node() != subtree.node(), subtree);
0981         }
0982 
0983         Node<T> *node = subtree.node();
0984         unlinkNode(node);
0985 
0986         node->prevSibling = nullptr;
0987         node->nextSibling = nullptr;
0988         node->parent = nullptr;
0989 
0990         linkNode(newPos, node);
0991         return child_iterator(node, node->parent, 0);
0992     }
0993 
0994 private:
0995 
0996     inline void linkBefore(Node<T> *node, Node<T> *beforeMe) {
0997         if (beforeMe) {
0998             node->nextSibling = beforeMe;
0999             beforeMe->prevSibling = node;
1000         }
1001     }
1002 
1003     inline void linkAfter(Node<T> *node, Node<T> *afterMe) {
1004         if (afterMe) {
1005             node->prevSibling = afterMe;
1006             afterMe->nextSibling = node;
1007         }
1008     }
1009 
1010     inline void linkNode(child_iterator pos, Node<T> *node) {
1011         Node<T> *nextNode = pos.node();
1012         RootNode<T> *parentNode = pos.m_parent;
1013 
1014         Node<T> *prevNode = nextNode ?
1015                             nextNode->prevSibling :
1016                             parentNode ? parentNode->lastChild : m_root.lastChild;
1017 
1018         linkAfter(node, prevNode);
1019         linkBefore(node, nextNode);
1020 
1021         KIS_SAFE_ASSERT_RECOVER_RETURN(parentNode);
1022         if (!nextNode) {
1023             parentNode->lastChild = node;
1024         }
1025 
1026         if (nextNode == parentNode->firstChild) {
1027             parentNode->firstChild = node;
1028         }
1029         node->parent = parentNode;
1030     }
1031 
1032     inline void unlinkNode(Node<T> *node) {
1033         RootNode<T> *parentNode = node->parent;
1034 
1035         if (node->nextSibling) {
1036             node->nextSibling->prevSibling = node->prevSibling;
1037         }
1038 
1039         if (node->prevSibling) {
1040             node->prevSibling->nextSibling = node->nextSibling;
1041         }
1042 
1043         KIS_SAFE_ASSERT_RECOVER_RETURN(parentNode);
1044         if (parentNode->firstChild == node) {
1045             parentNode->firstChild = node->nextSibling;
1046         }
1047 
1048         if (parentNode->lastChild == node) {
1049             parentNode->lastChild = node->prevSibling;
1050         }
1051     }
1052 
1053     void cloneChildren(const_child_iterator oldParent, child_iterator parent) {
1054         auto it = KisForestDetail::childBegin(oldParent);
1055         auto end = KisForestDetail::childEnd(oldParent);
1056         for (;it != end; ++it) {
1057             auto itClone = this->insert(KisForestDetail::childEnd(parent), *it);
1058             cloneChildren(it, itClone);
1059         }
1060     }
1061 
1062 private:
1063     template <class ForestType,
1064               class IteratorType = ChildIterator<typename ForestType::value_type,
1065                                                  std::is_const_v<ForestType>>>
1066     static IteratorType childBeginImpl(ForestType &forest) {
1067         return IteratorType(forest.m_root.firstChild, &forest.m_root, 0);
1068     }
1069 
1070     template <class ForestType,
1071               class IteratorType = ChildIterator<typename ForestType::value_type,
1072                                                  std::is_const_v<ForestType>>>
1073     static IteratorType childEndImpl(ForestType &forest) {
1074         return IteratorType(nullptr, &forest.m_root, 0);
1075     }
1076 
1077     template <class ForestType,
1078               class IteratorType = ChildIterator<typename ForestType::value_type,
1079                                                  std::is_const_v<ForestType>>>
1080     static IteratorType parentEndImpl(ForestType &forest) {
1081         return IteratorType(nullptr, &forest.m_root, -1);
1082     }
1083 
1084     template <class ForestType,
1085               class IteratorType = DepthFirstIterator<typename ForestType::value_type,
1086                                                       Enter,
1087                                                       std::is_const_v<ForestType>>>
1088     static IteratorType beginImpl(ForestType &forest) {
1089         return IteratorType(forest.m_root.firstChild);
1090     }
1091 
1092     template <class ForestType,
1093              class IteratorType = DepthFirstIterator<typename ForestType::value_type,
1094                                                      Enter,
1095                                                      std::is_const_v<ForestType>>>
1096     static IteratorType endImpl(ForestType &forest) {
1097         Q_UNUSED(forest);
1098         return IteratorType(nullptr);
1099     }
1100 
1101     template <class ForestType,
1102               class IteratorType = CompositionIterator<typename ForestType::value_type,
1103                                                       std::is_const_v<ForestType>>>
1104     static IteratorType compositionBeginImpl(ForestType &forest) {
1105         return IteratorType(forest.m_root.firstChild);
1106     }
1107 
1108     template <class ForestType,
1109               class IteratorType = CompositionIterator<typename ForestType::value_type,
1110                                                        std::is_const_v<ForestType>>>
1111     static IteratorType compositionEndImpl(ForestType &forest) {
1112         Q_UNUSED(forest);
1113         return IteratorType(nullptr);
1114     }
1115 
1116 private:
1117     RootNode<T> m_root;
1118 };
1119 
1120 template <typename T>
1121 typename Forest<T>::child_iterator childBegin(Forest<T> &forest)
1122 {
1123     return forest.childBegin();
1124 }
1125 
1126 template <typename T>
1127 typename Forest<T>::const_child_iterator childBegin(const Forest<T> &forest)
1128 {
1129     return forest.childBegin();
1130 }
1131 
1132 
1133 template <typename T>
1134 typename Forest<T>::child_iterator childEnd(Forest<T> &forest)
1135 {
1136     return forest.childEnd();
1137 }
1138 
1139 template <typename T>
1140 typename Forest<T>::const_child_iterator childEnd(const Forest<T> &forest)
1141 {
1142     return forest.childEnd();
1143 }
1144 
1145 template <typename T>
1146 typename Forest<T>::composition_iterator compositionBegin(Forest<T> &forest)
1147 {
1148     return forest.compositionBegin();
1149 }
1150 
1151 template <typename T>
1152 typename Forest<T>::const_composition_iterator compositionBegin(const Forest<T> &forest)
1153 {
1154     return forest.compositionBegin();
1155 }
1156 
1157 
1158 template <typename T>
1159 typename Forest<T>::composition_iterator compositionEnd(Forest<T> &forest)
1160 {
1161     return forest.compositionEnd();
1162 }
1163 
1164 template <typename T>
1165 typename Forest<T>::const_composition_iterator compositionEnd(const Forest<T> &forest)
1166 {
1167     return forest.compositionEnd();
1168 }
1169 
1170 
1171 template <typename T>
1172 typename Forest<T>::depth_first_tail_iterator tailSubtreeBegin(Forest<T> &forest)
1173 {
1174     return forest.depthFirstTailBegin();
1175 }
1176 
1177 template <typename T>
1178 typename Forest<T>::const_depth_first_tail_iterator tailSubtreeBegin(const Forest<T> &forest)
1179 {
1180     return forest.depthFirstTailBegin();
1181 }
1182 
1183 template <typename T>
1184 typename Forest<T>::depth_first_tail_iterator tailSubtreeEnd(Forest<T> &forest)
1185 {
1186     return forest.depthFirstTailEnd();
1187 }
1188 
1189 template <typename T>
1190 typename Forest<T>::const_depth_first_tail_iterator tailSubtreeEnd(const Forest<T> &forest)
1191 {
1192     return forest.depthFirstTailEnd();
1193 }
1194 
1195 template <typename T>
1196 int depth(typename Forest<T>::const_child_iterator beginIt,
1197           typename Forest<T>::const_child_iterator endIt)
1198 {
1199 
1200     int currentDepth = 0;
1201 
1202     for (auto it = beginIt; it != endIt; ++it) {
1203         currentDepth = std::max(currentDepth, 1 + depth<T>(childBegin(it), childEnd(it)));
1204     }
1205 
1206     return currentDepth;
1207 }
1208 
1209 template <typename T>
1210 int depth(const Forest<T> &forest) {
1211     return depth<T>(childBegin(forest), childEnd(forest));
1212 }
1213 
1214 template <typename T>
1215 int size(const Forest<T> &forest) {
1216     return std::distance(begin(forest), end(forest));
1217 }
1218 
1219 using std::begin;
1220 using std::end;
1221 using std::make_reverse_iterator;
1222 
1223 using std::find;
1224 using std::find_if;
1225 using std::find_if_not;
1226 }
1227 
1228 template<typename T>
1229 using KisForest = KisForestDetail::Forest<T>;
1230 
1231 
1232 #endif // KISFOREST_H