carl  24.04
Computer ARithmetic Library
carlTree.h
Go to the documentation of this file.
1 /**
2  * @file carlTree.h
3  * @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
4  */
5 
6 #pragma once
7 
8 #include <cassert>
9 #include <iterator>
10 #include <list>
11 #include <limits>
12 #include <stack>
13 #include <type_traits>
14 #include <vector>
15 
17 
18 
19 namespace carl {
20 
21 template<typename T>
22 class tree;
23 
24 namespace tree_detail {
25 
26 constexpr std::size_t MAXINT = std::numeric_limits<std::size_t>::max();
27 
28 template<typename T>
29 struct Node {
30  std::size_t id;
31  mutable T data;
32  std::size_t parent;
33  std::size_t previousSibling = MAXINT;
34  std::size_t nextSibling = MAXINT;
35  std::size_t firstChild = MAXINT;
36  std::size_t lastChild = MAXINT;
37  std::size_t depth = MAXINT;
38  Node(std::size_t _id, T&& _data, std::size_t _parent, std::size_t _depth):
39  id(_id), data(std::move(_data)), parent(_parent), depth(_depth)
40  {}
41 };
42 template<typename T>
43 bool operator==(const Node<T>& lhs, const Node<T>& rhs) {
44  return &lhs == &rhs;
45 }
46 template<typename T>
47 std::ostream& operator<<(std::ostream& os, const Node<T>& n) {
48  int id = (int)n.id;
49  int parent = (n.parent == MAXINT ? -1 : (int)n.parent);
50  int firstChild = (n.firstChild == MAXINT ? -1 : (int)n.firstChild);
51  int lastChild = (n.lastChild == MAXINT ? -1 : (int)n.lastChild);
52  int previousSibling = (n.previousSibling == MAXINT ? -1 : (int)n.previousSibling);
53  int nextSibling = (n.nextSibling == MAXINT ? -1 : (int)n.nextSibling);
54  os << "(" << n.data << " @ " << id << ", " << parent << ", " << firstChild << ":" << lastChild << ", " << previousSibling << " <-> " << nextSibling << ")\n";
55 
56  return os;
57 }
58 
59 /**
60  * This is the base class for all iterators.
61  * It takes care of correct implementation of all operators and reversion.
62  *
63  * An actual iterator `T<reverse>` only has to
64  * - inherit from `BaseIterator<T, reverse>`,
65  * - provide appropriate constructors,
66  * - implement `next()` and `previous()`.
67  * If the iterator supports only forward iteration, it omits the template
68  * argument, inherits from `BaseIterator<T, false>` and does not implement
69  * `previous()`.
70  */
71 template<typename T, typename Iterator, bool reverse>
72 struct BaseIterator {
73  template<typename TT, typename It, bool rev>
74  friend struct BaseIterator;
75 protected:
76  const tree<T>* mTree;
77  BaseIterator(const tree<T>* t, std::size_t root): mTree(t), current(root) {}
78 public:
79  const auto& nodes() const {
80  return mTree->nodes;
81  }
82  const auto& node(std::size_t id) const {
83  assert(id != MAXINT);
84  return nodes()[id];
85  }
86  const auto& curnode() const {
87  return node(current);
88  }
89  std::size_t current;
90  BaseIterator(const BaseIterator& ii) = default;
91  BaseIterator(BaseIterator&& ii) noexcept = default;
92  template<typename It, bool r>
94  BaseIterator& operator=(const BaseIterator& ii) = default;
95  BaseIterator& operator=(BaseIterator&& ii) noexcept = default;
96  std::size_t depth() const {
97  return node(current).depth;
98  }
99  std::size_t id() const {
100  assert(current != MAXINT);
101  return current;
102  }
103  bool isRoot() const {
104  return current == 0;
105  }
106  bool isValid() const {
107  return (mTree != nullptr) && mTree->is_valid(*this);
108  }
109  T* operator->() {
110  return &(curnode().data);
111  }
112  T const * operator->() const {
113  return &(curnode().data);
114  }
115 };
116 template<typename T, typename I, bool r>
118  return bi.curnode().data;
119 }
120 template<typename T, typename I, bool r>
121 const T& operator*(const BaseIterator<T,I,r>& bi) {
122  return bi.curnode().data;
123 }
124 
125 template<typename T, typename I, bool reverse>
126 typename std::enable_if<!reverse,I>::type& operator++(BaseIterator<T,I,reverse>& it) {
127  return static_cast<I*>(&it)->next();
128 }
129 template<typename T, typename I, bool reverse>
130 typename std::enable_if<reverse,I>::type& operator++(BaseIterator<T,I,reverse>& it) {
131  return static_cast<I*>(&it)->previous();
132 }
133 template<typename T, typename I, bool reverse>
134 typename std::enable_if<!reverse,I>::type operator++(BaseIterator<T,I,reverse>& it, int) {
135  return static_cast<I*>(&it)->next();
136 }
137 template<typename T, typename I, bool reverse>
138 typename std::enable_if<reverse,I>::type operator++(BaseIterator<T,I,reverse>& it, int) {
139  return static_cast<I*>(&it)->previous();
140 }
141 template<typename T, typename I, bool reverse>
142 typename std::enable_if<!reverse,I>::type& operator--(BaseIterator<T,I,reverse>& it) {
143  return static_cast<I*>(&it)->previous();
144 }
145 template<typename T, typename I, bool reverse>
146 typename std::enable_if<reverse,I>::type& operator--(BaseIterator<T,I,reverse>& it) {
147  return static_cast<I*>(&it)->next();
148 }
149 template<typename T, typename I, bool reverse>
150 typename std::enable_if<!reverse,I>::type operator--(BaseIterator<T,I,reverse>& it, int) {
151  return static_cast<I*>(&it)->previous();
152 }
153 template<typename T, typename I, bool reverse>
154 typename std::enable_if<reverse,I>::type operator--(BaseIterator<T,I,reverse>& it, int) {
155  return static_cast<I*>(&it)->next();
156 }
157 
158 
159 template<typename T, typename I, bool r>
161  return i1.current == i2.current;
162 }
163 template<typename T, typename I, bool r>
165  return i1.current != i2.current;
166 }
167 template<typename T, typename I, bool r>
169  return i1.current < i2.current;
170 }
171 
172 /**
173  * Iterator class for pre-order iterations over all elements.
174  */
175 template<typename T, bool reverse = false>
177  BaseIterator<T,PreorderIterator<T,reverse>, reverse>,
178  std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
179 {
182  PreorderIterator(const tree<T>* t, std::size_t root): Base(t, root) {}
184  if (this->current == MAXINT) {
185  this->current = this->mTree->begin_preorder().current;
186  } else if (this->curnode().firstChild == MAXINT) {
187  while (this->curnode().nextSibling == MAXINT) {
188  this->current = this->curnode().parent;
189  if (this->current == MAXINT) return *this;
190  }
191  this->current = this->curnode().nextSibling;
192  } else {
193  this->current = this->curnode().firstChild;
194  }
195  return *this;
196  }
198  if (this->current == MAXINT) {
199  this->current = this->mTree->rbegin_preorder().current;
200  } else if (this->curnode().previousSibling == MAXINT) {
201  this->current = this->curnode().parent;
202  } else {
203  this->current = this->curnode().previousSibling;
204  while (this->curnode().firstChild != MAXINT) {
205  this->current = this->curnode().lastChild;
206  }
207  }
208  return *this;
209  }
210 
211  template<typename It,bool rev>
216  Base::operator=(it);
217  return *this;
218  }
220  Base::operator=(it);
221  return *this;
222  }
223  virtual ~PreorderIterator() noexcept = default;
224 
226  assert(this->current != MAXINT);
227  while (this->curnode().nextSibling == MAXINT) {
228  this->current = this->curnode().parent;
229  if (this->current == MAXINT) return *this;
230  }
231  this->current = this->curnode().nextSibling;
232  return *this;
233  }
234 };
235 static_assert(std::is_copy_constructible<PreorderIterator<int,false>>::value, "");
236 static_assert(std::is_move_constructible<PreorderIterator<int,false>>::value, "");
237 static_assert(std::is_destructible<PreorderIterator<int,false>>::value, "");
238 static_assert(std::is_copy_constructible<PreorderIterator<int,true>>::value, "");
239 static_assert(std::is_move_constructible<PreorderIterator<int,true>>::value, "");
240 static_assert(std::is_destructible<PreorderIterator<int,true>>::value, "");
241 
242 /**
243  * Iterator class for post-order iterations over all elements.
244  */
245 template<typename T, bool reverse = false>
247  BaseIterator<T, PostorderIterator<T, reverse>,reverse>,
248  std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
249 {
252  PostorderIterator(const tree<T>* t, std::size_t root): Base(t, root) {}
254  if (this->current == MAXINT) {
255  this->current = this->mTree->begin_postorder().current;
256  } else if (this->curnode().nextSibling == MAXINT) {
257  this->current = this->curnode().parent;
258  } else {
259  this->current = this->curnode().nextSibling;
260  while (this->curnode().firstChild != MAXINT) {
261  this->current = this->curnode().firstChild;
262  }
263  }
264  return *this;
265  }
267  if (this->current == MAXINT) {
268  this->current = this->mTree->rbegin_postorder().current;
269  } else if (this->curnode().firstChild == MAXINT) {
270  if (this->curnode().previousSibling != MAXINT) {
271  this->current = this->curnode().previousSibling;
272  } else {
273  while (this->curnode().previousSibling == MAXINT) {
274  this->current = this->curnode().parent;
275  if (this->current == MAXINT) return *this;
276  }
277  this->current = this->curnode().previousSibling;
278  }
279  } else {
280  this->current = this->curnode().lastChild;
281  }
282  return *this;
283  }
284 
285  template<typename It>
290  Base::operator=(it);
291  return *this;
292  }
294  Base::operator=(it);
295  return *this;
296  }
297  virtual ~PostorderIterator() noexcept = default;
298 };
299 static_assert(std::is_copy_constructible<PostorderIterator<int,false>>::value, "");
300 static_assert(std::is_move_constructible<PostorderIterator<int,false>>::value, "");
301 static_assert(std::is_destructible<PostorderIterator<int,false>>::value, "");
302 static_assert(std::is_copy_constructible<PostorderIterator<int,true>>::value, "");
303 static_assert(std::is_move_constructible<PostorderIterator<int,true>>::value, "");
304 static_assert(std::is_destructible<PostorderIterator<int,true>>::value, "");
305 
306 /**
307  * Iterator class for iterations over all leaf elements.
308  */
309 template<typename T, bool reverse = false>
312  std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
313 {
315  LeafIterator(const tree<T>* t): Base(t, MAXINT) {}
316  LeafIterator(const tree<T>* t, std::size_t root): Base(t, root) {}
318  if (this->current == MAXINT) {
319  this->current = this->mTree->begin_leaf().current;
320  } else {
321  PreorderIterator<T,false> it(*this);
322  do {
323  ++it;
324  if (it.current == MAXINT) break;
325  } while (this->nodes()[it.current].firstChild != MAXINT);
326  this->current = it.current;
327  }
328  return *this;
329  }
331  if (this->current == MAXINT) {
332  this->current = this->mTree->rbegin_leaf().current;
333  } else {
334  PreorderIterator<T,false> it(*this);
335  do {
336  --it;
337  if (it.current == MAXINT) break;
338  } while (this->nodes()[it.current].firstChild != MAXINT);
339  this->current = it.current;
340  }
341  return *this;
342  }
343 
344  template<typename It>
346  LeafIterator(const LeafIterator& ii): Base(ii) {}
349  Base::operator=(it);
350  return *this;
351  }
353  Base::operator=(it);
354  return *this;
355  }
356  virtual ~LeafIterator() noexcept = default;
357 };
358 static_assert(std::is_copy_constructible<LeafIterator<int,false>>::value, "");
359 static_assert(std::is_move_constructible<LeafIterator<int,false>>::value, "");
360 static_assert(std::is_destructible<LeafIterator<int,false>>::value, "");
361 static_assert(std::is_copy_constructible<LeafIterator<int,true>>::value, "");
362 static_assert(std::is_move_constructible<LeafIterator<int,true>>::value, "");
363 static_assert(std::is_destructible<LeafIterator<int,true>>::value, "");
364 
365 /**
366  * Iterator class for iterations over all elements of a certain depth.
367  */
368 template<typename T, bool reverse = false>
371  std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
372 {
374  std::size_t depth;
375  DepthIterator(const tree<T>* t): Base(t, MAXINT), depth(0) {}
376  DepthIterator(const tree<T>* t, std::size_t root, std::size_t _depth): Base(t, root), depth(_depth) {
377  assert(!this->nodes().empty());
378  if (reverse) {
380  while (it.current != MAXINT && it.depth() != _depth) ++it;
381  this->current = it.current;
382  } else {
383  PreorderIterator<T,reverse> it(*this);
384  while (it.current != MAXINT && it.depth() != _depth) ++it;
385  this->current = it.current;
386  }
387  }
389  if (this->current == MAXINT) {
390  this->current = this->mTree->begin_depth(depth).current;
391  } else if (this->curnode().nextSibling == MAXINT) {
392  std::size_t target = this->curnode().depth;
393  while (this->curnode().nextSibling == MAXINT) {
394  this->current = this->curnode().parent;
395  if (this->current == MAXINT) return *this;
396  }
397  PreorderIterator<T,reverse> it(this->mTree, this->curnode().nextSibling);
398  for (; it.current != MAXINT; ++it) {
399  if (it.depth() == target) break;
400  }
401  this->current = it.current;
402  } else {
403  this->current = this->curnode().nextSibling;
404  }
405  return *this;
406  }
408  if (this->current == MAXINT) {
409  this->current = this->mTree->rbegin_depth(depth).current;
410  } else if (this->curnode().previousSibling == MAXINT) {
411  std::size_t target = this->curnode().depth;
412  while (this->curnode().previousSibling == MAXINT) {
413  this->current = this->curnode().parent;
414  if (this->current == MAXINT) return *this;
415  }
416  PostorderIterator<T,reverse> it(this->mTree, this->curnode().previousSibling);
417  for (; it.current != MAXINT; ++it) {
418  if (it.depth() == target) break;
419  }
420  this->current = it.current;
421  } else {
422  this->current = this->curnode().previousSibling;
423  }
424  return *this;
425  }
426 
427  template<typename It>
429  DepthIterator(const DepthIterator& ii): Base(ii), depth(ii.depth) {}
432  Base::operator=(it);
433  depth = it.depth;
434  return *this;
435  }
437  Base::operator=(it);
438  depth = it.depth;
439  return *this;
440  }
441  virtual ~DepthIterator() noexcept = default;
442 };
443 static_assert(std::is_copy_constructible<DepthIterator<int,false>>::value, "");
444 static_assert(std::is_move_constructible<DepthIterator<int,false>>::value, "");
445 static_assert(std::is_destructible<DepthIterator<int,false>>::value, "");
446 static_assert(std::is_copy_constructible<DepthIterator<int,true>>::value, "");
447 static_assert(std::is_move_constructible<DepthIterator<int,true>>::value, "");
448 static_assert(std::is_destructible<DepthIterator<int,true>>::value, "");
449 
450 /**
451  * Iterator class for iterations over all children of a given element.
452  */
453 template<typename T, bool reverse = false>
456  std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
457 {
459  std::size_t parent;
460  ChildrenIterator(const tree<T>* t, std::size_t base, bool end = false): Base(t, base) {
461  parent = base;
462  assert(base != MAXINT);
463  if (end) this->current = MAXINT;
464  else if (this->curnode().firstChild == MAXINT) this->current = MAXINT;
465  else {
466  if (reverse) {
467  this->current = this->curnode().lastChild;
468  } else {
469  this->current = this->curnode().firstChild;
470  }
471  }
472  }
474  if (this->current == MAXINT) {
475  this->current = this->mTree->begin_children(PreorderIterator<T,false>(this->mTree, parent)).current;
476  } else {
477  this->current = this->curnode().nextSibling;
478  }
479  return *this;
480  }
482  if (this->current == MAXINT) {
483  this->current = this->mTree->rbegin_children(PreorderIterator<T,false>(this->mTree, parent)).current;
484  } else {
485  this->current = this->curnode().previousSibling;
486  }
487  return *this;
488  }
489 
490  template<typename It>
492  if (this->mTree->is_valid(ii)) parent = this->nodes()[ii.current].parent;
493  }
494  ChildrenIterator(const ChildrenIterator& ii): Base(ii), parent(ii.parent) {}
495  ChildrenIterator(ChildrenIterator&& ii): Base(ii), parent(ii.parent) {}
497  Base::operator=(it);
498  parent = it.parent;
499  return *this;
500  }
502  Base::operator=(it);
503  parent = it.parent;
504  return *this;
505  }
506  virtual ~ChildrenIterator() noexcept = default;
507 };
508 static_assert(std::is_copy_constructible<ChildrenIterator<int,false>>::value, "");
509 static_assert(std::is_move_constructible<ChildrenIterator<int,false>>::value, "");
510 static_assert(std::is_destructible<ChildrenIterator<int,false>>::value, "");
511 static_assert(std::is_copy_constructible<ChildrenIterator<int,true>>::value, "");
512 static_assert(std::is_move_constructible<ChildrenIterator<int,true>>::value, "");
513 static_assert(std::is_destructible<ChildrenIterator<int,true>>::value, "");
514 
515 /**
516  * Iterator class for iterations from a given element to the root.
517  */
518 template<typename T>
520  BaseIterator<T, PathIterator<T>,false>,
521  std::iterator<std::forward_iterator_tag, T, std::size_t, T*, T&>
522 {
524  PathIterator(const tree<T>* t, std::size_t root): Base(t, root) {}
526  if (this->current != MAXINT) {
527  this->current = this->curnode().parent;
528  }
529  return *this;
530  }
531 
532  template<typename It>
534  PathIterator(const PathIterator& ii): Base(ii) {}
537  Base::operator=(it);
538  return *this;
539  }
541  Base::operator=(it);
542  return *this;
543  }
544  virtual ~PathIterator() noexcept = default;
545 };
546 static_assert(std::is_copy_constructible<PathIterator<int>>::value, "");
547 static_assert(std::is_move_constructible<PathIterator<int>>::value, "");
548 static_assert(std::is_destructible<PathIterator<int>>::value, "");
549 
550 
551 }
552 
553 /**
554  * This class represents a tree.
555  *
556  * It tries to stick to the STL style as close as possible.
557  */
558 template<typename T>
559 class tree {
560 public:
561  using value_type = T;
563 
564  template<bool reverse>
566  template<bool reverse>
568  template<bool reverse>
570  template<bool reverse>
572  template<bool reverse>
575 private:
576  template<typename TT, typename Iterator, bool reverse>
578 
579  static constexpr std::size_t MAXINT = tree_detail::MAXINT;
580  std::vector<Node> nodes;
581  std::size_t emptyNodes = MAXINT;
582 public:
583 
585 
586  tree() = default;
587  tree(const tree& t) = default;
588  tree(tree&& t) noexcept = default;
589  tree& operator=(const tree& t) = default;
590  tree& operator=(tree&& t) noexcept = default;
591 
592  void debug() const {
593  std::cout << "emptyNodes: " << emptyNodes << std::endl;
594  std::cout << this->nodes << std::endl;
595  }
596 
597  iterator begin() const {
598  return begin_preorder();
599  }
600  iterator end() const {
601  return end_preorder();
602  }
603  iterator rbegin() const {
604  return rbegin_preorder();
605  }
606  iterator rend() const {
607  return rend_preorder();
608  }
609 
611  return PreorderIterator<false>(this, 0);
612  }
614  return PreorderIterator<false>(this);
615  }
617  std::size_t cur = 0;
618  while (nodes[cur].lastChild != MAXINT) cur = nodes[cur].lastChild;
619  return PreorderIterator<true>(this, cur);
620  }
622  return PreorderIterator<true>(this);
623  }
625  std::size_t cur = 0;
626  while (nodes[cur].firstChild != MAXINT) cur = nodes[cur].firstChild;
627  return PostorderIterator<false>(this, cur);
628  }
630  return PostorderIterator<false>(this);
631  }
633  return PostorderIterator<true>(this, 0);
634  }
636  return PostorderIterator<true>(this);
637  }
639  std::size_t cur = 0;
640  while (nodes[cur].firstChild != MAXINT) cur = nodes[cur].firstChild;
641  return LeafIterator<false>(this, cur);
642  }
644  return LeafIterator<false>(this);
645  }
647  std::size_t cur = 0;
648  while (nodes[cur].lastChild != MAXINT) cur = nodes[cur].lastChild;
649  return LeafIterator<true>(this, cur);
650  }
652  return LeafIterator<true>(this);
653  }
655  return DepthIterator<false>(this, 0, depth);
656  }
658  return DepthIterator<false>(this);
659  }
661  return DepthIterator<true>(this, 0, depth);
662  }
664  return DepthIterator<true>(this);
665  }
666  template<typename Iterator>
668  return ChildrenIterator<false>(this, it.current, false);
669  }
670  template<typename Iterator>
672  return ChildrenIterator<false>(this, it.current, true);
673  }
674  template<typename Iterator>
676  return ChildrenIterator<true>(this, it.current, false);
677  }
678  template<typename Iterator>
680  return ChildrenIterator<true>(this, it.current, true);
681  }
682  template<typename Iterator>
683  PathIterator begin_path(const Iterator& it) const {
684  return PathIterator(this, it.current);
685  }
687  return PathIterator(this, MAXINT);
688  }
689 
690  /**
691  * Retrieves the maximum depth of all elements.
692  * @return Maximum depth.
693  */
694  std::size_t max_depth() const {
695  std::size_t max = 0;
696  for (auto it = begin_leaf(); it != end_leaf(); ++it) {
697  if (it.depth() > max) max = it.depth();
698  }
699  return max;
700  }
701  template<typename Iterator>
702  std::size_t max_depth(const Iterator& it) const {
703  std::size_t max = 0;
704  for (auto i = begin_children(it); i != end_children(it); ++i) {
705  std::size_t d = max_depth(i);
706  if (d + 1 > max) max = d + 1;
707  }
708  return max;
709  }
710 
711  /**
712  * Check if the given element is a leaf.
713  * @param it Iterator.
714  * @return If `it` is a leaf.
715  */
716  template<typename Iterator>
717  bool is_leaf(const Iterator& it) const {
718  return nodes[it.current].firstChild == MAXINT;
719  }
720  /**
721  * Check if the given element is a leftmost child.
722  * @param it Iterator.
723  * @return If `it` is a leftmost child.
724  */
725  template<typename Iterator>
726  bool is_leftmost(const Iterator& it) const {
727  return nodes[it.current].previousSibling == MAXINT;
728  }
729  /**
730  * Check if the given element is a rightmost child.
731  * @param it Iterator.
732  * @return If `it` is a rightmost child.
733  */
734  template<typename Iterator>
735  bool is_rightmost(const Iterator& it) const {
736  return nodes[it.current].nextSibling == MAXINT;
737  }
738  template<typename Iterator>
739  bool is_valid(const Iterator& it) const {
740  if (it.current >= nodes.size()) return false;
741  return nodes[it.current].depth < MAXINT;
742  }
743  /**
744  * Retrieves the parent of an element.
745  * @param it Iterator.
746  * @return Parent of `it`.
747  */
748  template<typename Iterator>
749  Iterator get_parent(const Iterator& it) const {
750  return Iterator(this, nodes[it.current].parent);
751  }
752  template<typename Iterator>
753  Iterator left_sibling(const Iterator& it) const {
754  assert(!is_leftmost(it));
755  auto res = it;
756  res.current = nodes[it.current].previousSibling;
757  return res;
758  }
759 
760  /**
761  * Sets the value of the root element.
762  * @param data Data.
763  * @return Iterator to the root.
764  */
765  iterator setRoot(const T& data) {
766  return setRoot(T(data));
767  }
768  iterator setRoot(T&& data) {
769  if (nodes.empty()) nodes.emplace_back(0, std::move(data), MAXINT, 0);
770  else nodes[0].data = data;
771  return iterator(this, 0);
772  }
773  /**
774  * Clears the tree.
775  */
776  void clear() {
777  nodes.clear();
778  emptyNodes = MAXINT;
779  }
780  /**
781  * Add the given data as last child of the root element.
782  * @param data Data.
783  * @return Iterator to inserted element.
784  */
785  iterator append(const T& data) {
786  if (nodes.empty()) setRoot(T());
787  return append(iterator(this, 0), data);
788  }
789 
790  /**
791  * Add the given data as last child of the given element.
792  * @param parent Parent element.
793  * @param data Data.
794  * @return Iterator to inserted element.
795  */
796  template<typename Iterator>
797  Iterator append(Iterator parent, const T& data) {
798  std::size_t id = createNode(data, parent.current, nodes[parent.current].depth + 1);
799  assert(is_consistent());
800  return Iterator(this, id);
801  }
802 
803  /**
804  * Insert element before the given position.
805  * @param position Position to insert before.
806  * @param data Element to insert.
807  * @return PreorderIterator to inserted element.
808  */
809  template<typename Iterator>
810  Iterator insert(Iterator position, const T& data) {
811  std::size_t parent = nodes[position.current].parent;
812  std::size_t newID = newNode(T(data), parent, nodes[position.current].depth);
813  std::size_t prev = nodes[position.current].previousSibling;
814  std::size_t next = position.current;
815  nodes[newID].previousSibling = prev;
816  nodes[newID].nextSibling = next;
817  if (next != MAXINT) {
818  nodes[next].previousSibling = newID;
819  } else {
820  nodes[parent].lastChild = newID;
821  }
822  if (prev != MAXINT) {
823  nodes[prev].nextSibling = newID;
824  } else {
825  nodes[parent].firstChild = newID;
826  }
827  assert(is_consistent());
828  return PreorderIterator<false>(this, newID);
829  }
830 
831  /**
832  * Append another tree as last child of the root element.
833  * @param tree Tree.
834  * @return Iterator to root of inserted subtree.
835  */
837  if (nodes.empty()) std::swap(nodes, tree.nodes);
838  return append(iterator(0), std::move(tree));
839  }
840  /**
841  * Append another tree as last child of the given element.
842  * @param position Element.
843  * @param tree Tree.
844  * @return Iterator to root of inserted subtree.
845  */
846  template<typename Iterator>
847  Iterator append(Iterator position, tree&& data) {
848  Node* r = data.root;
849  r->depth = position.depth() + 1;
850  data.root = nullptr;
851  r->parent = position.current;
852  std::size_t id = position.current->children.size();
853  if (id > 0) r->previousSibling = &(position.current->children.back());
854  position.current->children.push_back(*r);
855  if (id > 0) r->previousSibling->nextSibling = &(position.current->children.back());
856  assert(is_consistent());
857  return Iterator(&(position.current->children.back()));
858  }
859 
860  template<typename Iterator>
861  const Iterator& replace(const Iterator& position, const T& data) {
862  nodes[position.current].data = data;
863  return position;
864  }
865 
866  /**
867  * Erase the element at the given position.
868  * Returns an iterator to the next position.
869  * @param position Element.
870  * @return Next element.
871  */
872  template<typename Iterator>
873  Iterator erase(Iterator position) {
874  assert(this->is_consistent());
875  std::size_t id = position.current;
876  if (id == 0) {
877  clear();
878  ++position;
879  return position;
880  }
881  ++position;
882  if (nodes[id].nextSibling != MAXINT) {
883  nodes[nodes[id].nextSibling].previousSibling = nodes[id].previousSibling;
884  } else {
885  nodes[nodes[id].parent].lastChild = nodes[id].previousSibling;
886  }
887  if (nodes[id].previousSibling != MAXINT) {
888  nodes[nodes[id].previousSibling].nextSibling = nodes[id].nextSibling;
889  } else {
890  nodes[nodes[id].parent].firstChild = nodes[id].nextSibling;
891  }
892  eraseNode(id);
893  assert(this->is_consistent());
894  return position;
895  }
896  /**
897  * Erase all children of the given element.
898  * @param position Element.
899  */
900  template<typename Iterator>
901  void eraseChildren(const Iterator& position) {
902  eraseChildren(position.current);
903  }
904 private:
905  std::size_t newNode(T&& data, std::size_t parent, std::size_t depth) {
906  std::size_t newID = 0;
907  if (emptyNodes == MAXINT) {
908  nodes.emplace_back(nodes.size(), std::move(data), parent, depth);
909  newID = nodes.size() - 1;
910  } else {
911  newID = emptyNodes;
912  emptyNodes = nodes[emptyNodes].nextSibling;
913  nodes[newID].data = data;
914  nodes[newID].parent = parent;
915  nodes[newID].depth = depth;
916  }
917  return newID;
918  }
919  std::size_t createNode(const T& data, std::size_t parent, std::size_t depth) {
920  std::size_t res = newNode(T(data), parent, depth);
921  nodes[res].nextSibling = MAXINT;
922  if (parent != MAXINT) {
923  if (nodes[parent].lastChild != MAXINT) {
924  nodes[nodes[parent].lastChild].nextSibling = res;
925  nodes[res].previousSibling = nodes[parent].lastChild;
926  nodes[parent].lastChild = res;
927  } else {
928  nodes[parent].firstChild = res;
929  nodes[parent].lastChild = res;
930  }
931  }
932  return res;
933  }
934  void eraseChildren(std::size_t id) {
935  if (nodes[id].firstChild == MAXINT) return;
936  std::size_t cur = nodes[id].firstChild;
937  while (cur != MAXINT) {
938  std::size_t tmp = cur;
939  cur = nodes[cur].nextSibling;
940  eraseNode(tmp);
941  }
942  nodes[id].firstChild = MAXINT;
943  nodes[id].lastChild = MAXINT;
944  }
945  void eraseNode(std::size_t id) {
946  eraseChildren(id);
947  nodes[id].nextSibling = emptyNodes;
948  nodes[id].previousSibling = MAXINT;
949  nodes[id].depth = MAXINT;
950  emptyNodes = id;
951  }
952 
953 public:
954  bool is_consistent() const {
955  for (auto it = this->begin(); it != this->end(); ++it) {
956  assert(is_consistent(it.current));
957  }
958  return true;
959  }
960  bool is_consistent(std::size_t node) const {
961  assert(node != MAXINT);
962  assert(node < nodes.size());
963  if (nodes[node].firstChild != MAXINT) {
964  std::size_t child = nodes[node].firstChild;
965  while (nodes[child].nextSibling != MAXINT) {
966  assert(nodes[child].parent == node);
967  assert(nodes[nodes[child].nextSibling].previousSibling == child);
968  child = nodes[child].nextSibling;
969  }
970  assert(child == nodes[node].lastChild);
971 
972  child = nodes[node].lastChild;
973  while (nodes[child].previousSibling != MAXINT) {
974  assert(nodes[child].parent == node);
975  assert(nodes[nodes[child].previousSibling].nextSibling == child);
976  child = nodes[child].previousSibling;
977  }
978  assert(child == nodes[node].firstChild);
979  }
980  return true;
981  }
982 };
983 
984 
985 template<typename TT>
986 std::ostream& operator<<(std::ostream& os, const tree<TT>& tree) {
987  for (auto it = tree.begin_preorder(); it != tree.end_preorder(); ++it) {
988  os << std::string(it.depth(), '\t') << *it << std::endl;
989  }
990  return os;
991 }
992 
993 template<typename T>
994 const std::size_t tree<T>::MAXINT;
995 
996 }
carl is the main namespace for the library.
void swap(Variable &lhs, Variable &rhs)
Definition: Variables.h:202
UnivariatePolynomial< Coefficient > reverse(UnivariatePolynomial< Coefficient > &&p)
Reverses the order of the coefficients of this polynomial.
bool operator<(const BaseIterator< T, I, r > &i1, const BaseIterator< T, I, r > &i2)
Definition: carlTree.h:168
std::enable_if<!reverse, I >::type & operator++(BaseIterator< T, I, reverse > &it)
Definition: carlTree.h:126
std::ostream & operator<<(std::ostream &os, const Node< T > &n)
Definition: carlTree.h:47
T & operator*(BaseIterator< T, I, r > &bi)
Definition: carlTree.h:117
bool operator==(const Node< T > &lhs, const Node< T > &rhs)
Definition: carlTree.h:43
std::enable_if<!reverse, I >::type & operator--(BaseIterator< T, I, reverse > &it)
Definition: carlTree.h:142
bool operator!=(const BaseIterator< T, I, r > &i1, const BaseIterator< T, I, r > &i2)
Definition: carlTree.h:164
constexpr std::size_t MAXINT
Definition: carlTree.h:26
PositionIteratorType Iterator
Definition: OPBImporter.cpp:23
This class represents a tree.
Definition: carlTree.h:559
ChildrenIterator< false > begin_children(const Iterator &it) const
Definition: carlTree.h:667
iterator rend() const
Definition: carlTree.h:606
void eraseChildren(const Iterator &position)
Erase all children of the given element.
Definition: carlTree.h:901
PostorderIterator< true > rbegin_postorder() const
Definition: carlTree.h:632
PostorderIterator< false > begin_postorder() const
Definition: carlTree.h:624
const Iterator & replace(const Iterator &position, const T &data)
Definition: carlTree.h:861
tree()=default
Iterator erase(Iterator position)
Erase the element at the given position.
Definition: carlTree.h:873
void eraseChildren(std::size_t id)
Definition: carlTree.h:934
DepthIterator< true > rbegin_depth(std::size_t depth) const
Definition: carlTree.h:660
Iterator left_sibling(const Iterator &it) const
Definition: carlTree.h:753
tree & operator=(tree &&t) noexcept=default
void clear()
Clears the tree.
Definition: carlTree.h:776
bool is_consistent(std::size_t node) const
Definition: carlTree.h:960
DepthIterator< false > begin_depth(std::size_t depth) const
Definition: carlTree.h:654
iterator end() const
Definition: carlTree.h:600
DepthIterator< false > end_depth() const
Definition: carlTree.h:657
Iterator append(Iterator parent, const T &data)
Add the given data as last child of the given element.
Definition: carlTree.h:797
bool is_valid(const Iterator &it) const
Definition: carlTree.h:739
void debug() const
Definition: carlTree.h:592
bool is_leftmost(const Iterator &it) const
Check if the given element is a leftmost child.
Definition: carlTree.h:726
PathIterator begin_path(const Iterator &it) const
Definition: carlTree.h:683
ChildrenIterator< true > rend_children(const Iterator &it) const
Definition: carlTree.h:679
T value_type
Definition: carlTree.h:561
iterator begin() const
Definition: carlTree.h:597
iterator setRoot(T &&data)
Definition: carlTree.h:768
LeafIterator< true > rbegin_leaf() const
Definition: carlTree.h:646
iterator rbegin() const
Definition: carlTree.h:603
std::size_t createNode(const T &data, std::size_t parent, std::size_t depth)
Definition: carlTree.h:919
DepthIterator< true > rend_depth() const
Definition: carlTree.h:663
tree & operator=(const tree &t)=default
static constexpr std::size_t MAXINT
Definition: carlTree.h:579
LeafIterator< false > end_leaf() const
Definition: carlTree.h:643
LeafIterator< false > begin_leaf() const
Definition: carlTree.h:638
PostorderIterator< true > rend_postorder() const
Definition: carlTree.h:635
ChildrenIterator< false > end_children(const Iterator &it) const
Definition: carlTree.h:671
ChildrenIterator< true > rbegin_children(const Iterator &it) const
Definition: carlTree.h:675
std::size_t max_depth() const
Retrieves the maximum depth of all elements.
Definition: carlTree.h:694
PreorderIterator< true > rbegin_preorder() const
Definition: carlTree.h:616
std::size_t newNode(T &&data, std::size_t parent, std::size_t depth)
Definition: carlTree.h:905
PreorderIterator< false > begin_preorder() const
Definition: carlTree.h:610
PreorderIterator< true > rend_preorder() const
Definition: carlTree.h:621
iterator setRoot(const T &data)
Sets the value of the root element.
Definition: carlTree.h:765
iterator append(const T &data)
Add the given data as last child of the root element.
Definition: carlTree.h:785
LeafIterator< true > rend_leaf() const
Definition: carlTree.h:651
void eraseNode(std::size_t id)
Definition: carlTree.h:945
tree(const tree &t)=default
Iterator get_parent(const Iterator &it) const
Retrieves the parent of an element.
Definition: carlTree.h:749
PostorderIterator< false > end_postorder() const
Definition: carlTree.h:629
bool is_consistent() const
Definition: carlTree.h:954
bool is_rightmost(const Iterator &it) const
Check if the given element is a rightmost child.
Definition: carlTree.h:735
PreorderIterator< false > end_preorder() const
Definition: carlTree.h:613
tree(tree &&t) noexcept=default
std::vector< Node > nodes
Definition: carlTree.h:580
std::size_t max_depth(const Iterator &it) const
Definition: carlTree.h:702
iterator append(tree &&tree)
Append another tree as last child of the root element.
Definition: carlTree.h:836
PathIterator end_path() const
Definition: carlTree.h:686
Iterator insert(Iterator position, const T &data)
Insert element before the given position.
Definition: carlTree.h:810
bool is_leaf(const Iterator &it) const
Check if the given element is a leaf.
Definition: carlTree.h:717
Iterator append(Iterator position, tree &&data)
Append another tree as last child of the given element.
Definition: carlTree.h:847
std::size_t lastChild
Definition: carlTree.h:36
std::size_t depth
Definition: carlTree.h:37
std::size_t previousSibling
Definition: carlTree.h:33
std::size_t parent
Definition: carlTree.h:32
std::size_t firstChild
Definition: carlTree.h:35
std::size_t nextSibling
Definition: carlTree.h:34
Node(std::size_t _id, T &&_data, std::size_t _parent, std::size_t _depth)
Definition: carlTree.h:38
This is the base class for all iterators.
Definition: carlTree.h:72
std::size_t id() const
Definition: carlTree.h:99
BaseIterator & operator=(const BaseIterator &ii)=default
const auto & curnode() const
Definition: carlTree.h:86
const tree< T > * mTree
Definition: carlTree.h:76
BaseIterator(const tree< T > *t, std::size_t root)
Definition: carlTree.h:77
BaseIterator & operator=(BaseIterator &&ii) noexcept=default
const auto & node(std::size_t id) const
Definition: carlTree.h:82
const auto & nodes() const
Definition: carlTree.h:79
BaseIterator(BaseIterator &&ii) noexcept=default
std::size_t depth() const
Definition: carlTree.h:96
T const * operator->() const
Definition: carlTree.h:112
BaseIterator(const BaseIterator &ii)=default
BaseIterator(const BaseIterator< T, It, r > &ii)
Definition: carlTree.h:93
Iterator class for pre-order iterations over all elements.
Definition: carlTree.h:179
PreorderIterator(const BaseIterator< T, It, rev > &ii)
Definition: carlTree.h:212
PreorderIterator & skipChildren()
Definition: carlTree.h:225
PreorderIterator(PreorderIterator &&ii)
Definition: carlTree.h:214
PreorderIterator(const tree< T > *t, std::size_t root)
Definition: carlTree.h:182
PreorderIterator & operator=(PreorderIterator &&it)
Definition: carlTree.h:219
virtual ~PreorderIterator() noexcept=default
PreorderIterator(const tree< T > *t)
Definition: carlTree.h:181
PreorderIterator & operator=(const PreorderIterator &it)
Definition: carlTree.h:215
PreorderIterator & next()
Definition: carlTree.h:183
PreorderIterator(const PreorderIterator &ii)
Definition: carlTree.h:213
PreorderIterator & previous()
Definition: carlTree.h:197
Iterator class for post-order iterations over all elements.
Definition: carlTree.h:249
PostorderIterator(PostorderIterator &&ii)
Definition: carlTree.h:288
PostorderIterator & previous()
Definition: carlTree.h:266
PostorderIterator & next()
Definition: carlTree.h:253
virtual ~PostorderIterator() noexcept=default
PostorderIterator & operator=(const PostorderIterator &it)
Definition: carlTree.h:289
PostorderIterator(const BaseIterator< T, It, reverse > &ii)
Definition: carlTree.h:286
PostorderIterator(const tree< T > *t, std::size_t root)
Definition: carlTree.h:252
PostorderIterator & operator=(PostorderIterator &&it)
Definition: carlTree.h:293
PostorderIterator(const tree< T > *t)
Definition: carlTree.h:251
PostorderIterator(const PostorderIterator &ii)
Definition: carlTree.h:287
Iterator class for iterations over all leaf elements.
Definition: carlTree.h:313
LeafIterator & operator=(LeafIterator &&it)
Definition: carlTree.h:352
LeafIterator(const LeafIterator &ii)
Definition: carlTree.h:346
LeafIterator & previous()
Definition: carlTree.h:330
LeafIterator(const tree< T > *t, std::size_t root)
Definition: carlTree.h:316
LeafIterator & operator=(const LeafIterator &it)
Definition: carlTree.h:348
LeafIterator(const BaseIterator< T, It, reverse > &ii)
Definition: carlTree.h:345
LeafIterator(LeafIterator &&ii)
Definition: carlTree.h:347
virtual ~LeafIterator() noexcept=default
LeafIterator(const tree< T > *t)
Definition: carlTree.h:315
Iterator class for iterations over all elements of a certain depth.
Definition: carlTree.h:372
DepthIterator(const tree< T > *t)
Definition: carlTree.h:375
DepthIterator(DepthIterator &&ii)
Definition: carlTree.h:430
DepthIterator(const DepthIterator &ii)
Definition: carlTree.h:429
DepthIterator & previous()
Definition: carlTree.h:407
DepthIterator & operator=(const DepthIterator &it)
Definition: carlTree.h:431
DepthIterator(const tree< T > *t, std::size_t root, std::size_t _depth)
Definition: carlTree.h:376
virtual ~DepthIterator() noexcept=default
DepthIterator & operator=(DepthIterator &&it)
Definition: carlTree.h:436
DepthIterator(const BaseIterator< T, It, reverse > &ii)
Definition: carlTree.h:428
Iterator class for iterations over all children of a given element.
Definition: carlTree.h:457
ChildrenIterator & previous()
Definition: carlTree.h:481
ChildrenIterator(ChildrenIterator &&ii)
Definition: carlTree.h:495
ChildrenIterator & operator=(const ChildrenIterator &it)
Definition: carlTree.h:496
ChildrenIterator(const ChildrenIterator &ii)
Definition: carlTree.h:494
ChildrenIterator(const BaseIterator< T, It, reverse > &ii)
Definition: carlTree.h:491
ChildrenIterator(const tree< T > *t, std::size_t base, bool end=false)
Definition: carlTree.h:460
ChildrenIterator & next()
Definition: carlTree.h:473
ChildrenIterator & operator=(ChildrenIterator &&it) noexcept
Definition: carlTree.h:501
virtual ~ChildrenIterator() noexcept=default
Iterator class for iterations from a given element to the root.
Definition: carlTree.h:522
PathIterator & operator=(const PathIterator &it)
Definition: carlTree.h:536
virtual ~PathIterator() noexcept=default
PathIterator(const PathIterator &ii)
Definition: carlTree.h:534
PathIterator & operator=(PathIterator &&it) noexcept
Definition: carlTree.h:540
PathIterator(PathIterator &&ii)
Definition: carlTree.h:535
PathIterator(const tree< T > *t, std::size_t root)
Definition: carlTree.h:524
PathIterator(const BaseIterator< T, It, false > &ii)
Definition: carlTree.h:533