13 #include <type_traits>
24 namespace tree_detail {
26 constexpr std::size_t
MAXINT = std::numeric_limits<std::size_t>::max();
38 Node(std::size_t _id, T&& _data, std::size_t _parent, std::size_t _depth):
54 os <<
"(" << n.
data <<
" @ " <<
id <<
", " << parent <<
", " << firstChild <<
":" << lastChild <<
", " << previousSibling <<
" <-> " << nextSibling <<
")\n";
71 template<
typename T,
typename Iterator,
bool reverse>
73 template<
typename TT,
typename It,
bool rev>
82 const auto&
node(std::size_t
id)
const {
92 template<
typename It,
bool r>
99 std::size_t
id()
const {
107 return (
mTree !=
nullptr) &&
mTree->is_valid(*
this);
116 template<
typename T,
typename I,
bool r>
120 template<
typename T,
typename I,
bool r>
125 template<
typename T,
typename I,
bool reverse>
127 return static_cast<I*
>(&it)->next();
129 template<
typename T,
typename I,
bool reverse>
131 return static_cast<I*
>(&it)->previous();
133 template<
typename T,
typename I,
bool reverse>
135 return static_cast<I*
>(&it)->next();
137 template<
typename T,
typename I,
bool reverse>
139 return static_cast<I*
>(&it)->previous();
141 template<
typename T,
typename I,
bool reverse>
143 return static_cast<I*
>(&it)->previous();
145 template<
typename T,
typename I,
bool reverse>
147 return static_cast<I*
>(&it)->next();
149 template<
typename T,
typename I,
bool reverse>
151 return static_cast<I*
>(&it)->previous();
153 template<
typename T,
typename I,
bool reverse>
155 return static_cast<I*
>(&it)->next();
159 template<
typename T,
typename I,
bool r>
163 template<
typename T,
typename I,
bool r>
167 template<
typename T,
typename I,
bool r>
175 template<
typename T,
bool reverse = false>
178 std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
189 if (this->
current == MAXINT)
return *
this;
211 template<
typename It,
bool rev>
226 assert(this->
current != MAXINT);
229 if (this->
current == MAXINT)
return *
this;
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,
"");
245 template<
typename T,
bool reverse = false>
248 std::iterator<std::bidirectional_iterator_tag, T, std::size_t, T*, T&>
268 this->
current = this->
mTree->rbegin_postorder().current;
275 if (this->
current == MAXINT)
return *
this;
285 template<
typename It>
299 static_assert(std::is_copy_constructible<
PostorderIterator<
int,false>>::value, "");
300 static_assert(std::is_move_constructible<
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, "");
309 template<typename T,
bool reverse = false>
312 std::iterator<std::bidirectional_iterator_tag, T, std::
size_t, T*, T&>
344 template<
typename It>
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, "");
368 template<typename T,
bool reverse = false>
371 std::iterator<std::bidirectional_iterator_tag, T, std::
size_t, T*, T&>
377 assert(!this->
nodes().empty());
390 this->
current = this->
mTree->begin_depth(depth).current;
392 std::size_t target = this->
curnode().depth;
395 if (this->
current == MAXINT)
return *
this;
399 if (it.
depth() == target)
break;
409 this->
current = this->
mTree->rbegin_depth(depth).current;
411 std::size_t target = this->
curnode().depth;
414 if (this->
current == MAXINT)
return *
this;
418 if (it.
depth() == target)
break;
427 template<
typename It>
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, "");
453 template<typename T,
bool reverse = false>
456 std::iterator<std::bidirectional_iterator_tag, T, std::
size_t, T*, T&>
490 template<
typename It>
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, "");
521 std::iterator<std::forward_iterator_tag, T, std::
size_t, T*, T&>
532 template<
typename It>
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, "");
564 template<
bool reverse>
566 template<
bool reverse>
568 template<
bool reverse>
570 template<
bool reverse>
572 template<
bool reverse>
576 template<
typename TT,
typename Iterator,
bool reverse>
593 std::cout <<
"emptyNodes: " << emptyNodes << std::endl;
594 std::cout << this->nodes << std::endl;
598 return begin_preorder();
601 return end_preorder();
604 return rbegin_preorder();
607 return rend_preorder();
666 template<
typename Iterator>
670 template<
typename Iterator>
674 template<
typename Iterator>
678 template<
typename Iterator>
682 template<
typename Iterator>
696 for (
auto it = begin_leaf(); it != end_leaf(); ++it) {
697 if (it.depth() > max) max = it.depth();
701 template<
typename Iterator>
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;
716 template<
typename Iterator>
725 template<
typename Iterator>
727 return nodes[it.current].previousSibling ==
MAXINT;
734 template<
typename Iterator>
738 template<
typename Iterator>
740 if (it.current >=
nodes.size())
return false;
748 template<
typename Iterator>
752 template<
typename Iterator>
754 assert(!is_leftmost(it));
756 res.current =
nodes[it.current].previousSibling;
766 return setRoot(T(data));
770 else nodes[0].data = data;
786 if (
nodes.empty()) setRoot(T());
787 return append(
iterator(
this, 0), data);
796 template<
typename Iterator>
798 std::size_t
id = createNode(data, parent.current,
nodes[parent.current].depth + 1);
799 assert(is_consistent());
809 template<
typename Iterator>
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;
815 nodes[newID].previousSibling = prev;
820 nodes[parent].lastChild = newID;
823 nodes[prev].nextSibling = newID;
825 nodes[parent].firstChild = newID;
827 assert(is_consistent());
846 template<
typename Iterator>
849 r->
depth = position.depth() + 1;
851 r->
parent = position.current;
852 std::size_t
id = position.current->children.size();
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()));
860 template<
typename Iterator>
862 nodes[position.current].data = data;
872 template<
typename Iterator>
874 assert(this->is_consistent());
875 std::size_t
id = position.current;
893 assert(this->is_consistent());
900 template<
typename Iterator>
902 eraseChildren(position.current);
906 std::size_t newID = 0;
907 if (emptyNodes ==
MAXINT) {
909 newID =
nodes.size() - 1;
912 emptyNodes =
nodes[emptyNodes].nextSibling;
913 nodes[newID].data = data;
914 nodes[newID].parent = parent;
920 std::size_t res = newNode(T(data), parent,
depth);
924 nodes[
nodes[parent].lastChild].nextSibling = res;
925 nodes[res].previousSibling =
nodes[parent].lastChild;
926 nodes[parent].lastChild = res;
928 nodes[parent].firstChild = res;
929 nodes[parent].lastChild = res;
936 std::size_t cur =
nodes[
id].firstChild;
938 std::size_t tmp = cur;
939 cur =
nodes[cur].nextSibling;
947 nodes[
id].nextSibling = emptyNodes;
955 for (
auto it = this->begin(); it != this->end(); ++it) {
956 assert(is_consistent(it.current));
964 std::size_t child =
nodes[
node].firstChild;
967 assert(
nodes[
nodes[child].nextSibling].previousSibling == child);
968 child =
nodes[child].nextSibling;
975 assert(
nodes[
nodes[child].previousSibling].nextSibling == child);
976 child =
nodes[child].previousSibling;
985 template<
typename TT>
988 os << std::string(it.depth(),
'\t') << *it << std::endl;
carl is the main namespace for the library.
void swap(Variable &lhs, Variable &rhs)
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)
std::enable_if<!reverse, I >::type & operator++(BaseIterator< T, I, reverse > &it)
std::ostream & operator<<(std::ostream &os, const Node< T > &n)
T & operator*(BaseIterator< T, I, r > &bi)
bool operator==(const Node< T > &lhs, const Node< T > &rhs)
std::enable_if<!reverse, I >::type & operator--(BaseIterator< T, I, reverse > &it)
bool operator!=(const BaseIterator< T, I, r > &i1, const BaseIterator< T, I, r > &i2)
constexpr std::size_t MAXINT
PositionIteratorType Iterator
This class represents a tree.
ChildrenIterator< false > begin_children(const Iterator &it) const
void eraseChildren(const Iterator &position)
Erase all children of the given element.
PostorderIterator< true > rbegin_postorder() const
PostorderIterator< false > begin_postorder() const
const Iterator & replace(const Iterator &position, const T &data)
Iterator erase(Iterator position)
Erase the element at the given position.
void eraseChildren(std::size_t id)
DepthIterator< true > rbegin_depth(std::size_t depth) const
Iterator left_sibling(const Iterator &it) const
tree & operator=(tree &&t) noexcept=default
void clear()
Clears the tree.
bool is_consistent(std::size_t node) const
DepthIterator< false > begin_depth(std::size_t depth) const
DepthIterator< false > end_depth() const
Iterator append(Iterator parent, const T &data)
Add the given data as last child of the given element.
bool is_valid(const Iterator &it) const
bool is_leftmost(const Iterator &it) const
Check if the given element is a leftmost child.
PathIterator begin_path(const Iterator &it) const
ChildrenIterator< true > rend_children(const Iterator &it) const
iterator setRoot(T &&data)
LeafIterator< true > rbegin_leaf() const
std::size_t createNode(const T &data, std::size_t parent, std::size_t depth)
DepthIterator< true > rend_depth() const
tree & operator=(const tree &t)=default
static constexpr std::size_t MAXINT
LeafIterator< false > end_leaf() const
LeafIterator< false > begin_leaf() const
PostorderIterator< true > rend_postorder() const
ChildrenIterator< false > end_children(const Iterator &it) const
ChildrenIterator< true > rbegin_children(const Iterator &it) const
std::size_t max_depth() const
Retrieves the maximum depth of all elements.
PreorderIterator< true > rbegin_preorder() const
std::size_t newNode(T &&data, std::size_t parent, std::size_t depth)
PreorderIterator< false > begin_preorder() const
PreorderIterator< true > rend_preorder() const
iterator setRoot(const T &data)
Sets the value of the root element.
iterator append(const T &data)
Add the given data as last child of the root element.
LeafIterator< true > rend_leaf() const
void eraseNode(std::size_t id)
tree(const tree &t)=default
Iterator get_parent(const Iterator &it) const
Retrieves the parent of an element.
PostorderIterator< false > end_postorder() const
bool is_consistent() const
bool is_rightmost(const Iterator &it) const
Check if the given element is a rightmost child.
PreorderIterator< false > end_preorder() const
tree(tree &&t) noexcept=default
std::vector< Node > nodes
std::size_t max_depth(const Iterator &it) const
iterator append(tree &&tree)
Append another tree as last child of the root element.
PathIterator end_path() const
Iterator insert(Iterator position, const T &data)
Insert element before the given position.
bool is_leaf(const Iterator &it) const
Check if the given element is a leaf.
Iterator append(Iterator position, tree &&data)
Append another tree as last child of the given element.
std::size_t previousSibling
Node(std::size_t _id, T &&_data, std::size_t _parent, std::size_t _depth)
This is the base class for all iterators.
BaseIterator & operator=(const BaseIterator &ii)=default
const auto & curnode() const
BaseIterator(const tree< T > *t, std::size_t root)
BaseIterator & operator=(BaseIterator &&ii) noexcept=default
const auto & node(std::size_t id) const
const auto & nodes() const
BaseIterator(BaseIterator &&ii) noexcept=default
std::size_t depth() const
T const * operator->() const
BaseIterator(const BaseIterator &ii)=default
BaseIterator(const BaseIterator< T, It, r > &ii)
Iterator class for pre-order iterations over all elements.
PreorderIterator(const BaseIterator< T, It, rev > &ii)
PreorderIterator & skipChildren()
PreorderIterator(PreorderIterator &&ii)
PreorderIterator(const tree< T > *t, std::size_t root)
PreorderIterator & operator=(PreorderIterator &&it)
virtual ~PreorderIterator() noexcept=default
PreorderIterator(const tree< T > *t)
PreorderIterator & operator=(const PreorderIterator &it)
PreorderIterator & next()
PreorderIterator(const PreorderIterator &ii)
PreorderIterator & previous()
Iterator class for post-order iterations over all elements.
PostorderIterator(PostorderIterator &&ii)
PostorderIterator & previous()
PostorderIterator & next()
virtual ~PostorderIterator() noexcept=default
PostorderIterator & operator=(const PostorderIterator &it)
PostorderIterator(const BaseIterator< T, It, reverse > &ii)
PostorderIterator(const tree< T > *t, std::size_t root)
PostorderIterator & operator=(PostorderIterator &&it)
PostorderIterator(const tree< T > *t)
PostorderIterator(const PostorderIterator &ii)
Iterator class for iterations over all leaf elements.
LeafIterator & operator=(LeafIterator &&it)
LeafIterator(const LeafIterator &ii)
LeafIterator & previous()
LeafIterator(const tree< T > *t, std::size_t root)
LeafIterator & operator=(const LeafIterator &it)
LeafIterator(const BaseIterator< T, It, reverse > &ii)
LeafIterator(LeafIterator &&ii)
virtual ~LeafIterator() noexcept=default
LeafIterator(const tree< T > *t)
Iterator class for iterations over all elements of a certain depth.
DepthIterator(const tree< T > *t)
DepthIterator(DepthIterator &&ii)
DepthIterator(const DepthIterator &ii)
DepthIterator & previous()
DepthIterator & operator=(const DepthIterator &it)
DepthIterator(const tree< T > *t, std::size_t root, std::size_t _depth)
virtual ~DepthIterator() noexcept=default
DepthIterator & operator=(DepthIterator &&it)
DepthIterator(const BaseIterator< T, It, reverse > &ii)
Iterator class for iterations over all children of a given element.
ChildrenIterator & previous()
ChildrenIterator(ChildrenIterator &&ii)
ChildrenIterator & operator=(const ChildrenIterator &it)
ChildrenIterator(const ChildrenIterator &ii)
ChildrenIterator(const BaseIterator< T, It, reverse > &ii)
ChildrenIterator(const tree< T > *t, std::size_t base, bool end=false)
ChildrenIterator & next()
ChildrenIterator & operator=(ChildrenIterator &&it) noexcept
virtual ~ChildrenIterator() noexcept=default
Iterator class for iterations from a given element to the root.
PathIterator & operator=(const PathIterator &it)
virtual ~PathIterator() noexcept=default
PathIterator(const PathIterator &ii)
PathIterator & operator=(PathIterator &&it) noexcept
PathIterator(PathIterator &&ii)
PathIterator(const tree< T > *t, std::size_t root)
PathIterator(const BaseIterator< T, It, false > &ii)