Krita Source Code Documentation
Loading...
Searching...
No Matches
KisForest.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6#ifndef KISFOREST_H
7#define KISFOREST_H
8
9#include <utility>
10
11#include <boost/iterator/iterator_facade.hpp>
12#include <boost/iterator/iterator_adaptor.hpp>
13
14#include "KisCppQuirks.h"
15
16#include "kis_assert.h"
17#include "kis_debug.h"
18
19namespace KisForestDetail {
20
21template <typename Base>
23{
25 Base *firstChild = nullptr;
26 Base *lastChild = nullptr;
27
28 inline bool isRoot() const {
29 return !parent;
30 }
31};
32
33
34template <typename Base>
35struct BaseNode : RootNodeImpl<Base>
36{
37 Base *nextSibling = nullptr;
38 Base *prevSibling = nullptr;
39};
40
41template <typename T>
42struct Node : public BaseNode<Node<T>>
43{
44 template <typename X>
45 explicit Node(X &&newValue)
46 : value(std::forward<X>(newValue))
47 {
48 }
49
51};
52
53template <typename T>
55
56
57/*************************************************************************/
58/* BaseIterator */
59/*************************************************************************/
60
61template <typename BaseClass, typename T, typename Tag, bool is_const>
63 public boost::iterator_facade <BaseClass,
64 T,
65 Tag,
66 std::add_lvalue_reference_t<
67 std::add_const_if_t<is_const, T>>>
68{
69public:
70 using value_type = T;
72
77
78 NodeType* node() const {
79 return m_node;
80 }
81
82private:
84
85 typename std::iterator_traits<BaseIterator>::reference dereference() const {
87 return m_node->value;
88 }
89
90 bool equal(const BaseClass &other) const {
91 return m_node == other.m_node;
92 }
93
94protected:
96};
97
98
99/*************************************************************************/
100/* ChildIterator */
101/*************************************************************************/
102
159template <typename T, bool is_const>
161 public BaseIterator <ChildIterator<T, is_const>,
162 T,
163 boost::bidirectional_traversal_tag,
164 is_const>
165{
166 using BaseClass =
167 BaseIterator <ChildIterator<T, is_const>,
168 T,
169 boost::bidirectional_traversal_tag,
170 is_const>;
171
172public:
175
177 : BaseClass(node),
179 m_offsetToParent(offsetToParent)
180 {
181 }
182
183 operator ChildIterator<T, true>() const {
185 }
186
187private:
189 template <typename X, bool c>
191 template <typename X, bool c>
193 template <typename X, bool c>
195 template <typename X, bool c>
197 template <typename X, bool c>
199
200 template <typename X, bool c>
201 friend QDebug operator<<(QDebug dbg, const ChildIterator<X, c> &it);
202 template <typename X> friend class Forest;
203
204 void increment() {
205 this->m_node = this->m_node->nextSibling;
206 }
207
208 void decrement() {
209 this->m_node =
210 this->m_node ?
211 this->m_node->prevSibling :
212 (m_parent && m_offsetToParent == 0) ? m_parent->lastChild : nullptr;
213 }
214
215 bool equal(const ChildIterator<T, is_const> &other) const {
216 return this->m_node == other.m_node &&
217 (this->m_node ||
218 (this->m_parent == other.m_parent &&
219 this->m_offsetToParent == other.m_offsetToParent));
220 }
221
222private:
225};
226
227template <typename value_type, bool is_const>
229{
230 if (it.node()) {
231 dbg.nospace() << "ChildIterator(" << it.node() << "(" << it.node()->value << ")" << ", parent:" << it.m_parent << ")";
232 } else {
233 dbg.nospace() << "ChildIterator(" << "nullptr" << ", parent:" << it.m_parent << ", offset:" << it.m_offsetToParent << ")";
234 }
235 return dbg;
236}
237
238
239template <typename value_type, bool is_const>
244
245template <typename value_type, bool is_const>
247{
248 using RootNodeType = typename ChildIterator<value_type, is_const>::RootNodeType;
249 if (!it.node() && it.m_offsetToParent != 0) return it;
250 RootNodeType *parent = it.m_parent;
251 return ChildIterator<value_type, is_const>(parent ? parent->firstChild : nullptr, parent, 0);
252}
253
254template <typename value_type, bool is_const>
260
261template <typename Iterator,
262 bool is_const = std::is_const_v<typename Iterator::NodeType>,
263 typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
264ResultIterator siblingCurrent(Iterator it)
265{
266 // TODO: conversion of an end-iterator into a child iterator is still not implemented
267 // and considered as UB. We need to implement all special-cases for that.
269
270 return ResultIterator(it.node(), it.node() ? it.node()->parent : nullptr, 0);
271}
272
273template <typename Iterator,
274 bool is_const = std::is_const_v<typename Iterator::NodeType>,
275 typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
276ResultIterator siblingBegin(Iterator it)
277{
278 return siblingBegin(siblingCurrent(it));
279}
280
281template <typename Iterator,
282 bool is_const = std::is_const_v<typename Iterator::NodeType>,
283 typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
284ResultIterator siblingEnd(Iterator it)
285{
286 return siblingEnd(siblingCurrent(it));
287}
288
289 template <typename value_type, bool is_const>
291{
292 if (it.node()) {
293 return ChildIterator<value_type, is_const>(it.node()->firstChild, it.node(), 0);
294 } else {
296 }
297}
298
299template <typename value_type, bool is_const>
301{
302 if (it.node()) {
303 return ChildIterator<value_type, is_const>(nullptr, it.node(), 0);
304 } else {
306 }
307}
308
309template <typename Iterator,
310 bool is_const = std::is_const_v<typename Iterator::NodeType>,
311 typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
312ResultIterator childBegin(Iterator it)
313{
314 return childBegin(siblingCurrent(it));
315}
316
317template <typename Iterator,
318 bool is_const = std::is_const_v<typename Iterator::NodeType>,
319 typename ResultIterator = ChildIterator<typename Iterator::value_type, is_const>>
320ResultIterator childEnd(Iterator it)
321{
322 return childEnd(siblingCurrent(it));
323}
324
325
326template <typename value_type, bool is_const>
328{
329 if (it.m_parent->isRoot()) {
330 return ChildIterator<value_type, is_const>(nullptr, it.m_parent, qMax(-1, it.m_offsetToParent - 1));
331 } else if (it.m_offsetToParent == 0) {
332 using NodeType = typename ChildIterator<value_type, is_const>::NodeType;
333 NodeType *parentNode = static_cast<NodeType*>(it.m_parent);
334 return ChildIterator<value_type, is_const>(parentNode, parentNode->parent, 0);
335 } else {
337 }
338}
339
340template <typename T, bool is_const>
341inline bool isEnd(const ChildIterator<T, is_const> &it) {
342 return !it.node();
343}
344
345
346/*************************************************************************/
347/* HierarchyIterator */
348/*************************************************************************/
349
380template <typename T, bool is_const>
382 public BaseIterator <HierarchyIterator<T, is_const>,
383 T,
384 boost::forward_traversal_tag,
385 is_const>
386{
387 using BaseClass = BaseIterator <HierarchyIterator<T, is_const>,
388 T,
389 boost::forward_traversal_tag,
390 is_const>;
391public:
394
399
400 operator HierarchyIterator<T, true>() const {
402 }
403
404private:
406
407 void increment() {
408 RootNodeType *parent = this->m_node->parent;
409 this->m_node =
410 static_cast<NodeType*>(
411 parent && !parent->isRoot() ?
412 parent : nullptr);
413 }
414};
415
416template <typename Iterator,
417 bool is_const = std::is_const_v<typename Iterator::NodeType>,
418 typename ResultIterator = HierarchyIterator<typename Iterator::value_type, is_const>>
419ResultIterator hierarchyBegin(Iterator it)
420{
421 return ResultIterator(it.node());
422}
423
424template <typename Iterator,
425 bool is_const = std::is_const_v<typename Iterator::NodeType>,
426 typename ResultIterator = HierarchyIterator<typename Iterator::value_type, is_const>>
427ResultIterator hierarchyEnd(Iterator it)
428{
429 Q_UNUSED(it);
430 return ResultIterator(nullptr);
431}
432
433
434/*************************************************************************/
435/* CompositionIterator */
436/*************************************************************************/
437
483
484template <typename T, bool is_const>
486 public boost::iterator_adaptor<
487 CompositionIterator<T, is_const>,
488 ChildIterator<T, is_const>,
489 boost::use_default,
490 boost::forward_traversal_tag>
491{
492 using BaseClass = boost::iterator_adaptor<
495 boost::use_default,
496 boost::forward_traversal_tag>;
497
498 using BaseIteratorType = typename CompositionIterator::base_type;
499
500public:
502 using RootNodeType = typename BaseIteratorType::RootNodeType;
503 using NodeType = typename BaseIteratorType::NodeType;
504
505 NodeType* node() const {
506 return this->base().node();
507 }
508
509public:
515
517 return m_state;
518 }
519
521 return CompositionIterator<T, true>(this->m_node, this->m_state);
522 }
523
524private:
526
527 bool tryJumpToPos(typename CompositionIterator::base_type it,
528 TraversalState newState) {
529 bool result = false;
530
531 if (!isEnd(it)) {
532 this->base_reference() = it;
533 result = true;
534 m_state = newState;
535 }
536
537 return result;
538 }
539
540 void increment() {
541 switch (m_state) {
542 case Enter:
543 if (tryJumpToPos(childBegin(this->base()), Enter)) return;
544 if (tryJumpToPos(this->base(), Leave)) return;
545 break;
546 case Leave:
547 if (tryJumpToPos(std::next(this->base()), Enter)) return;
548 if (tryJumpToPos(parent(this->base()), Leave)) return;
549 break;
550 }
551
552 this->base_reference() = BaseIteratorType(nullptr, nullptr, 0);
553 }
554
555private:
557};
558
559template <typename Iterator,
560 bool is_const = std::is_const_v<typename Iterator::NodeType>,
562ResultIterator compositionBegin(Iterator it)
563{
564 return ResultIterator(it.node(), Enter);
565}
566
567template <typename Iterator,
568 bool is_const = std::is_const_v<typename Iterator::NodeType>,
569 typename ResultIterator = CompositionIterator<typename Iterator::value_type, is_const>>
570ResultIterator compositionEnd(Iterator it)
571{
572 return it.node() ?
573 std::next(ResultIterator(it.node(), Leave)) :
574 ResultIterator(nullptr, Leave);
575}
576
577
578/*************************************************************************/
579/* DepthFirstIterator */
580/*************************************************************************/
581
630template <typename T, TraversalState visit_on, bool is_const>
632 public boost::iterator_adaptor<
633 DepthFirstIterator<T, visit_on, is_const>,
634 CompositionIterator<T, is_const>,
635 boost::use_default,
636 boost::forward_traversal_tag>
637{
638 using BaseClass = boost::iterator_adaptor<
641 boost::use_default,
642 boost::forward_traversal_tag>;
643
644 using BaseIteratorType = typename DepthFirstIterator::base_type;
645
646public:
648 using RootNodeType = typename BaseIteratorType::RootNodeType;
649 using NodeType = typename BaseIteratorType::NodeType;
650
652 traversal_state state = traversal_state::Enter,
653 bool shouldSkipToBegin = false)
655 {
656 if (shouldSkipToBegin) {
657 skipToState(visit_on);
658 }
659 }
660
661 NodeType* node() const {
662 return this->base().node();
663 }
664
666 return DepthFirstIterator<T, visit_on, true>(this->m_node, this->m_state);
667 }
668
669private:
671
672 void increment() {
673 this->base_reference()++;
674 skipToState(visit_on);
675 }
676
678 while (this->base().node() && this->base().state() != state) {
679 this->base_reference()++;
680 }
681 }
682
683};
684
685template <typename Iterator,
686 bool is_const = std::is_const_v<typename Iterator::NodeType>,
687 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter, is_const>>
688ResultIterator subtreeBegin(Iterator it)
689{
690 return ResultIterator(it.node(), Enter);
691}
692
693template <typename Iterator,
694 bool is_const = std::is_const_v<typename Iterator::NodeType>,
695 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Enter, is_const>>
696ResultIterator subtreeEnd(Iterator it)
697{
698 return it.node() ?
699 std::next(ResultIterator(it.node(), Leave)) :
700 ResultIterator(nullptr, Leave);
701}
702
703template <typename Iterator,
704 bool is_const = std::is_const_v<typename Iterator::NodeType>,
705 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave, is_const>>
706ResultIterator tailSubtreeBegin(Iterator it)
707{
708 return ResultIterator(it.node(), Enter, true);
709}
710
711template <typename Iterator,
712 bool is_const = std::is_const_v<typename Iterator::NodeType>,
713 typename ResultIterator = DepthFirstIterator<typename Iterator::value_type, Leave, is_const>>
714ResultIterator tailSubtreeEnd(Iterator it)
715{
716 return it.node() ?
717 std::next(ResultIterator(it.node(), Leave)) :
718 ResultIterator(nullptr, Leave);
719}
720
721
722/*************************************************************************/
723/* Forest */
724/*************************************************************************/
725
775template <typename T>
777{
778public:
780 {
781 }
782
785 }
786
787 Forest(const Forest<T> &rhs) {
788 for (auto it = rhs.childBegin(); it != rhs.childEnd(); ++it) {
789 auto cloneIt = this->insert(this->childEnd(), *it);
790 cloneChildren(it, cloneIt);
791 }
792 }
793
796 for (auto it = rhs.childBegin(); it != rhs.childEnd(); ++it) {
797 auto cloneIt = this->insert(this->childEnd(), *it);
798 cloneChildren(it, cloneIt);
799 }
800 return *this;
801 }
802
803 using value_type = T;
804
807
810
813
816
819
820 bool empty() const {
821 return !m_root.firstChild;
822 }
823
824 void swap(Forest &other) {
825 std::swap(m_root, other.m_root);
826 }
827
829 return beginImpl(*this);
830 }
831
833 return endImpl(*this);
834 }
835
837 return beginImpl(*this);
838 }
839
841 return endImpl(*this);
842 }
843
845 return beginImpl(*this);
846 }
847
849 return endImpl(*this);
850 }
851
855
859
863
867
871
875
877 return childBeginImpl(*this);
878 }
879
881 return childEndImpl(*this);
882 }
883
885 return parentEndImpl(*this);
886 }
887
889 return childBeginImpl(*this);
890 }
891
893 return childEndImpl(*this);
894 }
895
897 return parentEndImpl(*this);
898 }
899
901 return childBeginImpl(*this);
902 }
903
905 return childEndImpl(*this);
906 }
907
909 return parentEndImpl(*this);
910 }
911
915
919
923
927
931
935
942 template <typename X>
944 Node<T> *node = new Node<T>(std::forward<X>(value));
945
946 linkNode(pos, node);
947
948 return child_iterator(node, node->parent, 0);
949 }
950
957 child_iterator nextNode = std::next(pos);
958 Node<T> *node = pos.node();
959
960 Node<T> *lastNode = node;
961 for (auto it = tailSubtreeBegin(pos); it != tailSubtreeEnd(pos); ++it) {
962
963 if (lastNode != node) {
964 delete lastNode;
965 }
966 lastNode = it.node();
967 }
968
969 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(lastNode == node, pos);
970
971 unlinkNode(node);
972 delete node;
973
974 return nextNode;
975 }
976
982 while (pos != end) {
983 pos = erase(pos);
984 }
985 return pos;
986 }
987
995 // sanity check for cycling move
996 for (auto it = hierarchyBegin(newPos); it != hierarchyEnd(newPos); ++it) {
997 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(it.node() != subtree.node(), subtree);
998 }
999
1000 Node<T> *node = subtree.node();
1001 unlinkNode(node);
1002
1003 node->prevSibling = nullptr;
1004 node->nextSibling = nullptr;
1005 node->parent = nullptr;
1006
1007 linkNode(newPos, node);
1008 return child_iterator(node, node->parent, 0);
1009 }
1010
1011private:
1012
1013 inline void linkBefore(Node<T> *node, Node<T> *beforeMe) {
1014 if (beforeMe) {
1015 node->nextSibling = beforeMe;
1016 beforeMe->prevSibling = node;
1017 }
1018 }
1019
1020 inline void linkAfter(Node<T> *node, Node<T> *afterMe) {
1021 if (afterMe) {
1022 node->prevSibling = afterMe;
1023 afterMe->nextSibling = node;
1024 }
1025 }
1026
1027 inline void linkNode(child_iterator pos, Node<T> *node) {
1028 Node<T> *nextNode = pos.node();
1029 RootNode<T> *parentNode = pos.m_parent;
1030
1031 Node<T> *prevNode = nextNode ?
1032 nextNode->prevSibling :
1033 parentNode ? parentNode->lastChild : m_root.lastChild;
1034
1035 linkAfter(node, prevNode);
1036 linkBefore(node, nextNode);
1037
1039 if (!nextNode) {
1040 parentNode->lastChild = node;
1041 }
1042
1043 if (nextNode == parentNode->firstChild) {
1044 parentNode->firstChild = node;
1045 }
1046 node->parent = parentNode;
1047 }
1048
1049 inline void unlinkNode(Node<T> *node) {
1050 RootNode<T> *parentNode = node->parent;
1051
1052 if (node->nextSibling) {
1053 node->nextSibling->prevSibling = node->prevSibling;
1054 }
1055
1056 if (node->prevSibling) {
1057 node->prevSibling->nextSibling = node->nextSibling;
1058 }
1059
1061 if (parentNode->firstChild == node) {
1062 parentNode->firstChild = node->nextSibling;
1063 }
1064
1065 if (parentNode->lastChild == node) {
1066 parentNode->lastChild = node->prevSibling;
1067 }
1068 }
1069
1071 auto it = KisForestDetail::childBegin(oldParent);
1072 auto end = KisForestDetail::childEnd(oldParent);
1073 for (;it != end; ++it) {
1074 auto itClone = this->insert(KisForestDetail::childEnd(parent), *it);
1075 cloneChildren(it, itClone);
1076 }
1077 }
1078
1079private:
1080 template <class ForestType,
1081 class IteratorType = ChildIterator<typename ForestType::value_type,
1082 std::is_const_v<ForestType>>>
1083 static IteratorType childBeginImpl(ForestType &forest) {
1084 return IteratorType(forest.m_root.firstChild, &forest.m_root, 0);
1085 }
1086
1087 template <class ForestType,
1088 class IteratorType = ChildIterator<typename ForestType::value_type,
1089 std::is_const_v<ForestType>>>
1090 static IteratorType childEndImpl(ForestType &forest) {
1091 return IteratorType(nullptr, &forest.m_root, 0);
1092 }
1093
1094 template <class ForestType,
1095 class IteratorType = ChildIterator<typename ForestType::value_type,
1096 std::is_const_v<ForestType>>>
1097 static IteratorType parentEndImpl(ForestType &forest) {
1098 return IteratorType(nullptr, &forest.m_root, -1);
1099 }
1100
1101 template <class ForestType,
1102 class IteratorType = DepthFirstIterator<typename ForestType::value_type,
1103 Enter,
1104 std::is_const_v<ForestType>>>
1105 static IteratorType beginImpl(ForestType &forest) {
1106 return IteratorType(forest.m_root.firstChild);
1107 }
1108
1109 template <class ForestType,
1110 class IteratorType = DepthFirstIterator<typename ForestType::value_type,
1111 Enter,
1112 std::is_const_v<ForestType>>>
1113 static IteratorType endImpl(ForestType &forest) {
1114 Q_UNUSED(forest);
1115 return IteratorType(nullptr);
1116 }
1117
1118 template <class ForestType,
1119 class IteratorType = CompositionIterator<typename ForestType::value_type,
1120 std::is_const_v<ForestType>>>
1121 static IteratorType compositionBeginImpl(ForestType &forest) {
1122 return IteratorType(forest.m_root.firstChild);
1123 }
1124
1125 template <class ForestType,
1126 class IteratorType = CompositionIterator<typename ForestType::value_type,
1127 std::is_const_v<ForestType>>>
1128 static IteratorType compositionEndImpl(ForestType &forest) {
1129 Q_UNUSED(forest);
1130 return IteratorType(nullptr);
1131 }
1132
1133private:
1135};
1136
1137template <typename T>
1139{
1140 return forest.childBegin();
1141}
1142
1143template <typename T>
1145{
1146 return forest.childBegin();
1147}
1148
1149
1150template <typename T>
1152{
1153 return forest.childEnd();
1154}
1155
1156template <typename T>
1158{
1159 return forest.childEnd();
1160}
1161
1162template <typename T>
1164{
1165 return forest.compositionBegin();
1166}
1167
1168template <typename T>
1170{
1171 return forest.compositionBegin();
1172}
1173
1174
1175template <typename T>
1177{
1178 return forest.compositionEnd();
1179}
1180
1181template <typename T>
1183{
1184 return forest.compositionEnd();
1185}
1186
1187
1188template <typename T>
1193
1194template <typename T>
1196{
1197 return forest.depthFirstTailBegin();
1198}
1199
1200template <typename T>
1202{
1203 return forest.depthFirstTailEnd();
1204}
1205
1206template <typename T>
1208{
1209 return forest.depthFirstTailEnd();
1210}
1211
1212template <typename T>
1214 typename Forest<T>::const_child_iterator endIt)
1215{
1216
1217 int currentDepth = 0;
1218
1219 for (auto it = beginIt; it != endIt; ++it) {
1220 currentDepth = std::max(currentDepth, 1 + depth<T>(childBegin(it), childEnd(it)));
1221 }
1222
1223 return currentDepth;
1224}
1225
1226template <typename T>
1227int depth(const Forest<T> &forest) {
1228 return depth<T>(childBegin(forest), childEnd(forest));
1229}
1230
1231template <typename T>
1232int size(const Forest<T> &forest) {
1233 return std::distance(begin(forest), end(forest));
1234}
1235
1236using std::begin;
1237using std::end;
1238using std::make_reverse_iterator;
1239
1240using std::find;
1241using std::find_if;
1242using std::find_if_not;
1243}
1244
1245template<typename T>
1247
1248
1249#endif // KISFOREST_H
float value(const T *src, size_t ch)
std::iterator_traits< BaseIterator >::reference dereference() const
Definition KisForest.h:85
bool equal(const BaseClass &other) const
Definition KisForest.h:90
NodeType * node() const
Definition KisForest.h:78
BaseIterator(NodeType *node)
Definition KisForest.h:73
friend class boost::iterator_core_access
Definition KisForest.h:83
std::add_const_if_t< is_const, Node< T > > NodeType
Definition KisForest.h:71
bool equal(const ChildIterator< T, is_const > &other) const
Definition KisForest.h:215
friend QDebug operator<<(QDebug dbg, const ChildIterator< X, c > &it)
friend ChildIterator< X, c > childBegin(const ChildIterator< X, c > &it)
friend ChildIterator< X, c > childEnd(const ChildIterator< X, c > &it)
friend ChildIterator< X, c > parent(const ChildIterator< X, c > &it)
friend ChildIterator< X, c > siblingBegin(const ChildIterator< X, c > &it)
ChildIterator(NodeType *node, RootNodeType *parent, int offsetToParent)
Definition KisForest.h:176
typename BaseClass::NodeType NodeType
Definition KisForest.h:174
std::add_const_if_t< is_const, RootNode< T > > RootNodeType
Definition KisForest.h:173
friend class boost::iterator_core_access
Definition KisForest.h:188
friend ChildIterator< X, c > siblingEnd(const ChildIterator< X, c > &it)
typename BaseIteratorType::RootNodeType RootNodeType
Definition KisForest.h:502
CompositionIterator(NodeType *node, traversal_state state=Enter)
Definition KisForest.h:510
typename CompositionIterator::base_type BaseIteratorType
Definition KisForest.h:498
typename BaseIteratorType::NodeType NodeType
Definition KisForest.h:503
friend class boost::iterator_core_access
Definition KisForest.h:525
bool tryJumpToPos(typename CompositionIterator::base_type it, TraversalState newState)
Definition KisForest.h:527
traversal_state state() const
Definition KisForest.h:516
boost::iterator_adaptor< CompositionIterator< T, is_const >, ChildIterator< T, is_const >, boost::use_default, boost::forward_traversal_tag > BaseClass
Definition KisForest.h:492
boost::iterator_adaptor< DepthFirstIterator< T, visit_on, is_const >, CompositionIterator< T, is_const >, boost::use_default, boost::forward_traversal_tag > BaseClass
Definition KisForest.h:638
typename BaseIteratorType::NodeType NodeType
Definition KisForest.h:649
typename BaseIteratorType::RootNodeType RootNodeType
Definition KisForest.h:648
typename DepthFirstIterator::base_type BaseIteratorType
Definition KisForest.h:644
friend class boost::iterator_core_access
Definition KisForest.h:670
DepthFirstIterator(NodeType *node, traversal_state state=traversal_state::Enter, bool shouldSkipToBegin=false)
Definition KisForest.h:651
void skipToState(TraversalState state)
Definition KisForest.h:677
const_composition_iterator constCompositionBegin() const
Definition KisForest.h:928
child_iterator childEnd()
Definition KisForest.h:880
const_iterator constBegin() const
Definition KisForest.h:844
const_child_iterator constChildBegin() const
Definition KisForest.h:900
void swap(Forest &other)
Definition KisForest.h:824
static IteratorType parentEndImpl(ForestType &forest)
Definition KisForest.h:1097
const_iterator begin() const
Definition KisForest.h:836
const_child_iterator constParentEnd() const
Definition KisForest.h:908
const_depth_first_tail_iterator constDepthFirstTailBegin() const
Definition KisForest.h:868
const_depth_first_tail_iterator depthFirstTailBegin() const
Definition KisForest.h:860
const_child_iterator parentEnd() const
Definition KisForest.h:896
const_iterator end() const
Definition KisForest.h:840
const_child_iterator childEnd() const
Definition KisForest.h:892
child_iterator insert(child_iterator pos, X &&value)
Inserts element value into position pos. value becomes the child of the same parent as pos and is pla...
Definition KisForest.h:943
child_iterator parentEnd()
Definition KisForest.h:884
Forest< T > & operator=(const Forest< T > &rhs)
Definition KisForest.h:794
depth_first_tail_iterator depthFirstTailEnd()
Definition KisForest.h:856
child_iterator childBegin()
Definition KisForest.h:876
child_iterator move(child_iterator subtree, child_iterator newPos)
move a subtree to new position Moves subtree into a new position pointer by newPos....
Definition KisForest.h:994
const_composition_iterator compositionBegin() const
Definition KisForest.h:920
const_child_iterator constChildEnd() const
Definition KisForest.h:904
const_depth_first_tail_iterator constDepthFirstTailEnd() const
Definition KisForest.h:872
const_depth_first_tail_iterator depthFirstTailEnd() const
Definition KisForest.h:864
composition_iterator compositionBegin()
Definition KisForest.h:912
const_child_iterator childBegin() const
Definition KisForest.h:888
ChildIterator< T, false > child_iterator
Definition KisForest.h:805
static IteratorType beginImpl(ForestType &forest)
Definition KisForest.h:1105
composition_iterator compositionEnd()
Definition KisForest.h:916
void linkNode(child_iterator pos, Node< T > *node)
Definition KisForest.h:1027
static IteratorType childBeginImpl(ForestType &forest)
Definition KisForest.h:1083
const_composition_iterator constCompositionEnd() const
Definition KisForest.h:932
const_iterator constEnd() const
Definition KisForest.h:848
void cloneChildren(const_child_iterator oldParent, child_iterator parent)
Definition KisForest.h:1070
depth_first_tail_iterator depthFirstTailBegin()
Definition KisForest.h:852
static IteratorType childEndImpl(ForestType &forest)
Definition KisForest.h:1090
Forest(const Forest< T > &rhs)
Definition KisForest.h:787
child_iterator erase(child_iterator pos, child_iterator end)
erases all elements from pos to end (excluding end)
Definition KisForest.h:981
static IteratorType compositionEndImpl(ForestType &forest)
Definition KisForest.h:1128
void linkBefore(Node< T > *node, Node< T > *beforeMe)
Definition KisForest.h:1013
const_composition_iterator compositionEnd() const
Definition KisForest.h:924
static IteratorType compositionBeginImpl(ForestType &forest)
Definition KisForest.h:1121
static IteratorType endImpl(ForestType &forest)
Definition KisForest.h:1113
void unlinkNode(Node< T > *node)
Definition KisForest.h:1049
child_iterator erase(child_iterator pos)
Removes element at position pos. If pos is 'end', then result is undefined.
Definition KisForest.h:956
void linkAfter(Node< T > *node, Node< T > *afterMe)
Definition KisForest.h:1020
std::add_const_if_t< is_const, RootNode< T > > RootNodeType
Definition KisForest.h:392
friend class boost::iterator_core_access
Definition KisForest.h:405
typename BaseClass::NodeType NodeType
Definition KisForest.h:393
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
ResultIterator subtreeBegin(Iterator it)
Definition KisForest.h:688
bool isEnd(const ChildIterator< T, is_const > &it)
Definition KisForest.h:341
ResultIterator hierarchyBegin(Iterator it)
Definition KisForest.h:419
ChildIterator< value_type, is_const > childBegin(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:290
ResultIterator hierarchyEnd(Iterator it)
Definition KisForest.h:427
ChildIterator< value_type, is_const > siblingCurrent(ChildIterator< value_type, is_const > it)
Definition KisForest.h:240
ResultIterator compositionEnd(Iterator it)
Definition KisForest.h:570
QDebug operator<<(QDebug dbg, const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:228
ResultIterator tailSubtreeBegin(Iterator it)
Definition KisForest.h:706
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327
int size(const Forest< T > &forest)
Definition KisForest.h:1232
ResultIterator compositionBegin(Iterator it)
Definition KisForest.h:562
ChildIterator< value_type, is_const > siblingEnd(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:255
ResultIterator tailSubtreeEnd(Iterator it)
Definition KisForest.h:714
ChildIterator< value_type, is_const > siblingBegin(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:246
ChildIterator< value_type, is_const > childEnd(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:300
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
Definition KisForest.h:1213
ResultIterator subtreeEnd(Iterator it)
Definition KisForest.h:696
typename add_const_if< is_const, T >::type add_const_if_t
Node(X &&newValue)
Definition KisForest.h:45
RootNodeImpl< Base > * parent
Definition KisForest.h:24