65 auto link1_u = utils::make_unique< TreeLink >();
66 auto link2_u = utils::make_unique< TreeLink >();
67 auto node1_u = utils::make_unique< TreeNode >();
68 auto node2_u = utils::make_unique< TreeNode >();
69 auto edge0_u = utils::make_unique< TreeEdge >();
72 link1_u->reset_index( 0 );
73 link1_u->reset_next( link1_u.get() );
74 link1_u->reset_outer( link2_u.get() );
75 link1_u->reset_node( node1_u.get() );
76 link1_u->reset_edge( edge0_u.get() );
78 link2_u->reset_index( 1 );
79 link2_u->reset_next( link2_u.get() );
80 link2_u->reset_outer( link1_u.get() );
81 link2_u->reset_node( node2_u.get() );
82 link2_u->reset_edge( edge0_u.get() );
84 node1_u->reset_index( 0 );
85 node1_u->reset_primary_link( link1_u.get() );
87 node2_u->reset_index( 1 );
88 node2_u->reset_primary_link( link2_u.get() );
90 edge0_u->reset_index( 0 );
91 edge0_u->reset_primary_link( link1_u.get() );
92 edge0_u->reset_secondary_link( link2_u.get() );
95 links.push_back( std::move( link1_u ));
96 links.push_back( std::move( link2_u ));
97 nodes.push_back( std::move( node1_u ));
98 nodes.push_back( std::move( node2_u ));
99 edges.push_back( std::move( edge0_u ));
113 throw std::runtime_error(
114 "Cannot add Node to a Tree where the given Node is not part of the Tree."
128 auto con_link_u = utils::make_unique< TreeLink >();
129 auto end_link_u = utils::make_unique< TreeLink >();
130 auto end_node_u = utils::make_unique< TreeNode >();
131 auto con_edge_u = utils::make_unique< TreeEdge >();
134 auto const con_link = con_link_u.get();
135 auto const end_link = end_link_u.get();
136 auto const end_node = end_node_u.get();
137 auto const con_edge = con_edge_u.get();
140 con_link->reset_index( links.size() );
141 con_link->reset_node( &target_node );
142 con_link->reset_edge( con_edge );
143 con_link->reset_outer( end_link );
147 auto last_link = up_link;
148 while( &last_link->next() != up_link ) {
149 last_link = &last_link->
next();
153 assert( &last_link->next() == up_link );
154 last_link->reset_next( con_link );
155 con_link->reset_next( up_link );
156 assert( &last_link->next() == con_link );
157 assert( &con_link->next() == up_link );
161 links.push_back( std::move( con_link_u ));
164 end_link->reset_index( links.size() );
165 end_link->reset_node( end_node );
166 end_link->reset_edge( con_edge );
167 end_link->reset_next( end_link );
168 end_link->reset_outer( con_link );
169 links.push_back( std::move( end_link_u ));
172 end_node->reset_index( nodes.size() );
173 end_node->reset_primary_link( end_link );
175 nodes.push_back( std::move( end_node_u ));
178 con_edge->reset_index( edges.size() );
179 con_edge->reset_primary_link( con_link );
180 con_edge->reset_secondary_link( end_link );
182 edges.push_back( std::move( con_edge_u ));
191 std::function<
void(
TreeEdge& target_edge,
TreeEdge& new_edge )> adjust_edges
195 throw std::runtime_error(
196 "Cannot add Node to Tree on an Edge that is not part of the Tree."
209 auto pri_link_u = utils::make_unique< TreeLink >();
210 auto sec_link_u = utils::make_unique< TreeLink >();
211 auto mid_node_u = utils::make_unique< TreeNode >();
212 auto sec_edge_u = utils::make_unique< TreeEdge >();
215 auto const pri_link = pri_link_u.get();
216 auto const sec_link = sec_link_u.get();
217 auto const mid_node = mid_node_u.get();
218 auto const sec_edge = sec_edge_u.get();
221 pri_link->reset_index( links.size() );
222 pri_link->reset_next( sec_link );
224 pri_link->reset_node( mid_node );
225 pri_link->reset_edge( &target_edge );
226 links.push_back( std::move( pri_link_u ));
229 sec_link->reset_index( links.size() );
230 sec_link->reset_next( pri_link );
232 sec_link->reset_node( mid_node );
233 sec_link->reset_edge( sec_edge );
234 links.push_back( std::move( sec_link_u ));
237 mid_node->reset_index( nodes.size() );
238 mid_node->reset_primary_link( pri_link );
240 nodes.push_back( std::move( mid_node_u ));
243 sec_edge->reset_index( edges.size() );
244 sec_edge->reset_primary_link( sec_link );
247 edges.push_back( std::move( sec_edge_u ));
257 adjust_edges( target_edge, *sec_edge );
266 std::function<
void(
TreeEdge& target_edge,
TreeEdge& new_edge )> adjust_edges
269 auto& mid_node =
add_new_node( tree, target_edge, adjust_edges );
281 throw std::runtime_error(
282 "Cannot delete Node from a Tree that is not part of the Tree."
286 auto const deg =
degree( target_node );
289 }
else if( deg == 2 ) {
300 throw std::runtime_error(
301 "Cannot delete node from a tree that is not part of the tree."
304 if(
degree( target_node ) != 1 ) {
305 throw std::runtime_error(
306 "Cannot delete leaf node if the node is not actually a leaf."
311 throw std::runtime_error(
312 "Cannot delete leaf node from a minmal tree that only contains two nodes."
317 assert( &target_node.
link().
next() == &target_node.
link() );
337 assert( &root_link->node() == &target_node.
link().
outer().
node() );
344 edges.erase( edges.begin() + edge_idx );
345 for(
size_t i = edge_idx; i < tree.
edge_count(); ++i ) {
351 auto& attach_link = target_node.
link().
outer();
352 assert( &attach_link.edge() == &target_node.
link().
edge() );
353 assert( &attach_link.outer() == &target_node.
link() );
354 auto link_ptr = &( attach_link.next() );
355 while( &link_ptr->next() != &attach_link ) {
356 link_ptr = &link_ptr->next();
358 assert( &link_ptr->next() == &attach_link );
359 assert( &link_ptr->next().next() == &attach_link.next() );
360 link_ptr->reset_next( &link_ptr->next().next() );
364 auto const minmax_link_idx =
utils::minmax_value( attach_link.index(), attach_link.outer().index() );
365 links.erase( links.begin() + minmax_link_idx.first );
366 links.erase( links.begin() + minmax_link_idx.second - 1 );
367 for(
size_t i = minmax_link_idx.first; i < links.size(); ++i ) {
373 auto const node_idx = target_node.
index();
374 nodes.erase( nodes.begin() + node_idx );
375 for(
size_t i = node_idx; i < tree.
node_count(); ++i ) {
388 std::function<
void(
TreeEdge& remaining_edge,
TreeEdge& deleted_edge )> adjust_edges
392 throw std::runtime_error(
393 "Cannot delete Node from a Tree that is not part of the Tree."
396 if(
degree( target_node ) != 2 ) {
397 throw std::runtime_error(
398 "Cannot delete linear Node if the Node is not actually linear (degree 2)."
420 auto& pr_link = target_node.
link();
421 auto& adj_link_p = pr_link.
outer();
422 auto& adj_link_d = pr_link.
next().
outer();
423 assert( &adj_link_p.outer().node() == &adj_link_d.outer().node() );
424 adj_link_p.reset_outer( &adj_link_d );
425 adj_link_d.reset_outer( &adj_link_p );
431 assert( &adj_link_p.edge().secondary_node() == &target_node || root_link != &tree.
root_link() );
432 assert( &adj_link_p.edge() == &target_node.
link().
edge() );
433 assert( &adj_link_d.edge() == &target_node.
link().
next().
edge() );
434 assert( &adj_link_d.edge().primary_node() == &target_node );
435 adj_link_p.edge().reset_primary_link( &adj_link_p );
436 adj_link_p.edge().reset_secondary_link( &adj_link_d );
440 auto const edge_idx = pr_link.next().edge().index();
441 edges.erase( edges.begin() + edge_idx );
442 for(
size_t i = edge_idx; i < tree.
edge_count(); ++i ) {
449 auto const minmax_link_idx =
utils::minmax_value( pr_link.index(), pr_link.next().index() );
450 links.erase( links.begin() + minmax_link_idx.first );
451 links.erase( links.begin() + minmax_link_idx.second - 1 );
452 for(
size_t i = minmax_link_idx.first; i < links.size(); ++i ) {
458 auto const node_idx = target_node.
index();
459 nodes.erase( nodes.begin() + node_idx );
460 for(
size_t i = node_idx; i < tree.
node_count(); ++i ) {
479 std::sort( del_elems.begin(), del_elems.end() );
480 assert( std::adjacent_find( del_elems.begin(), del_elems.end()) == del_elems.end() );
483 assert( del_elems.size() < old_elems.size() );
488 auto new_elems = T{};
489 new_elems.reserve( old_elems.size() - del_elems.size() );
492 size_t del_elems_idx = 0;
493 for(
size_t i = 0; i < old_elems.size(); ++i ) {
494 assert( i == old_elems[i]->index() );
495 if( del_elems_idx < del_elems.size() && del_elems[del_elems_idx] == i ) {
503 assert( old_elems[i]->index() == i );
504 assert( new_elems.size() == i - del_elems_idx );
505 old_elems[i]->reset_index( i - del_elems_idx );
506 new_elems.emplace_back( std::move( old_elems[i] ));
507 assert( new_elems.back()->index() == new_elems.size() - 1 );
513 assert( new_elems.size() + del_elems.size() == old_elems.size() );
522 throw std::runtime_error(
523 "Cannot delete Subtree from a Tree that is not part of the Tree."
527 throw std::runtime_error(
528 "Cannot delete Subtree from Tree if this leads to a singluar Node."
536 std::vector<size_t> del_nodes;
537 std::vector<size_t> del_edges;
538 std::vector<size_t> del_links;
539 bool contains_root =
false;
540 for(
auto it :
preorder( subtree )) {
541 del_nodes.push_back( it.node().index() );
542 del_edges.push_back( it.edge().index() );
543 del_links.push_back( it.link().index() );
544 del_links.push_back( it.link().outer().index() );
547 contains_root =
true;
566 auto& attach_link = subtree.
link().
outer();
567 assert( &attach_link.edge() == &subtree.
link().
edge() );
568 assert( &attach_link.outer() == &subtree.
link() );
569 auto link_ptr = &( attach_link.next() );
570 while( &link_ptr->next() != &attach_link ) {
571 link_ptr = &link_ptr->next();
573 assert( &link_ptr->next() == &attach_link );
574 assert( &link_ptr->next().next() == &attach_link.next() );
575 auto& link_nc = tree.
link_at( link_ptr->index() );
578 if( &link_nc.node().primary_link() == &link_nc.next() ) {
579 assert( &attach_link.node().primary_link() == &attach_link );
580 link_nc.node().reset_primary_link( &link_nc.next().next() );
585 link_nc.reset_next( &link_nc.next().next() );
600 std::function<
void(
TreeNode& remaining_node,
TreeNode& deleted_node )> adjust_nodes
604 throw std::runtime_error(
605 "Cannot delete edge from a tree that is not part of the tree."
612 throw std::runtime_error(
613 "Cannot delete edge from minimal tree that only consists of two nodes."
669 sec_lnk = &sec_lnk->
next();
677 while( &prm_lnk->next() != &target_edge.
primary_link() ) {
678 prm_lnk = &prm_lnk->
next();
680 assert( &prm_lnk->next() == &target_edge.
primary_link() );
691 prm_lnk->node().reset_primary_link( &prm_lnk->next() );
696 std::vector<size_t> del_edges = { target_edge.
index() };
697 std::vector<size_t> del_links = {
712 for(
auto const& edge : tree.
edges() ) {
713 if(
is_leaf(edge) && ! include_leaf_edges ) {
720 del_idx = edge.index();
732 del_node.data_is_derived_from<CommonNodeData>() &&
733 rem_node.data_is_derived_from<CommonNodeData>() &&
734 rem_node.data<CommonNodeData>().name.empty()
736 rem_node.data<CommonNodeData>().name = del_node.data<CommonNodeData>().name;
750 std::function<
void(
TreeEdge& target_edge,
TreeEdge& new_edge )> adjust_edges
753 throw std::runtime_error(
"Cannot make a Tree rooted if it is already rooted." );
756 auto& mid_node =
add_new_node( tree, target_edge, adjust_edges );
763 std::function<
void(
TreeEdge& target_edge,
TreeEdge& new_edge )> adjust_edges
770 std::function<
void(
TreeEdge& remaining_edge,
TreeEdge& deleted_edge )> adjust_edges
773 throw std::runtime_error(
"Cannot make a Tree unrooted if it is already unrooted." );
782 throw std::runtime_error(
"Cannot reroot Tree on a Link that is not part of the Tree." );
799 while( &cur_link->
node() != old_root ) {
824 cur_link = to_root_link;
831 throw std::runtime_error(
"Cannot reroot Tree on a Node that is not part of the Tree." );
847 for(
auto& node : tree.
nodes() ) {
855 std::vector<size_t> child_sizes;
856 std::vector<TreeLink*> child_links;
861 if( link_it.is_first_iteration() ) {
862 assert( &link_it.link() == &node.primary_link() );
866 child_sizes.push_back( sub_sizes[ link_it.link().outer().node().index() ] );
867 child_links.push_back( &link_it.link() );
871 auto child_order = ( order == LadderizeOrder::kSmallFirst
877 assert( child_order.size() == child_sizes.size() );
878 assert( child_order.size() == child_links.size() );
879 assert( child_order.size() ==
degree( node ) - 1 );
882 auto cur_link = &node.primary_link();
883 for(
auto child_order_i : child_order ) {
887 assert( child_links[ child_order_i ] );
890 cur_link->reset_next( child_links[ child_order_i ] );
891 cur_link = child_links[ child_order_i ];
895 child_links[ child_order_i ] =
nullptr;
900 cur_link->reset_next( &node.primary_link() );
903 for(
auto const& cl : child_links ) {