1 #ifndef SUPERTREE_VARIANTS_MULTITREE_HPP
2 #define SUPERTREE_VARIANTS_MULTITREE_HPP
3 
4 #include "multitree_impl.hpp"
5 #include "supertree_variants.hpp"
6 
7 #include <memory>
8 #include <stack>
9 
10 namespace terraces {
11 namespace variants {
12 
13 class multitree_callback : public abstract_callback<multitree_node*> {
14 private:
15 	multitree_impl::storage_blocks<multitree_node> m_nodes;
16 	multitree_impl::storage_blocks<index> m_leaves;
17 
alloc_node()18 	multitree_node* alloc_node() { return m_nodes.get(); }
19 
alloc_nodes(index num)20 	multitree_node* alloc_nodes(index num) { return m_nodes.get_range(num); }
21 
alloc_leaves(const ranked_bitvector & leaves)22 	std::pair<index*, index*> alloc_leaves(const ranked_bitvector& leaves) {
23 		auto size = leaves.count();
24 		auto a_leaves = m_leaves.get_range(size);
25 		index i = 0;
26 		for (auto el : leaves) {
27 			a_leaves[i++] = el;
28 		}
29 		return {a_leaves, a_leaves + size};
30 	}
31 
32 public:
33 	using return_type = multitree_node*;
34 
base_one_leaf(index i)35 	return_type base_one_leaf(index i) {
36 		return multitree_impl::make_single_leaf(alloc_node(), i);
37 	}
base_two_leaves(index i,index j)38 	return_type base_two_leaves(index i, index j) {
39 		return multitree_impl::make_two_leaves(alloc_node(), i, j);
40 	}
base_unconstrained(const ranked_bitvector & leaves)41 	return_type base_unconstrained(const ranked_bitvector& leaves) {
42 		return multitree_impl::make_unconstrained(alloc_node(), alloc_leaves(leaves));
43 	}
null_result() const44 	return_type null_result() const { return nullptr; }
45 
fast_return_value(const bipartitions & bip_it)46 	return_type fast_return_value(const bipartitions& bip_it) {
47 		return multitree_impl::make_unexplored(alloc_node(), alloc_leaves(bip_it.leaves()));
48 	}
49 
begin_iteration(const bipartitions & bip_it,const bitvector &,const constraints &)50 	return_type begin_iteration(const bipartitions& bip_it, const bitvector&,
51 	                            const constraints&) {
52 		return multitree_impl::make_alternative_array(
53 		        alloc_node(), alloc_nodes(bip_it.num_bip()), bip_it.leaves().count());
54 	}
55 
accumulate(multitree_node * acc,multitree_node * node)56 	return_type accumulate(multitree_node* acc, multitree_node* node) {
57 		assert(acc->num_leaves == node->num_leaves);
58 		acc->num_trees += node->num_trees;
59 		*(acc->alternative_array.end) = *node;
60 		++(acc->alternative_array.end);
61 		return acc;
62 	}
63 
combine(multitree_node * left,multitree_node * right)64 	return_type combine(multitree_node* left, multitree_node* right) {
65 		return multitree_impl::make_inner_node(alloc_node(), left, right);
66 	}
67 };
68 
69 } // namespace variants
70 } // namespace terraces
71 
72 #endif // SUPERTREE_VARIANTS_MULTITREE_HPP
73