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