20 #ifndef __TPIE_PIPELINING_PAIR_FACTORY_H__
21 #define __TPIE_PIPELINING_PAIR_FACTORY_H__
25 #include <tpie/pipelining/priority_type.h>
26 #include <tpie/pipelining/factory_base.h>
27 #include <boost/scoped_array.hpp>
29 namespace tpie::pipelining::bits {
31 template <
typename child_t>
35 : m_maps(
new node_map::ptr[2])
43 m_final = other.m_final;
44 swap(m_maps, other.m_maps);
50 m_final = other.m_final;
51 swap(m_maps, other.m_maps);
54 double memory()
const noexcept {
55 return self().fact1.memory() +
self().fact2.memory();
58 void name(
const std::string & n, priority_type) {
62 void push_breadcrumb(
const std::string & n) {
63 self().fact1.push_breadcrumb(n);
64 self().fact2.push_breadcrumb(n);
71 self().hook_initialization_impl(hook);
78 template <
typename pipe_t>
79 pipe_t
record(
size_t idx, pipe_t && pipe)
const {
80 m_maps[idx] = pipe.get_node_map();
81 if (idx == 0 && m_final) {
85 self().recursive_connected_check();
87 return std::move(pipe);
90 void assert_connected()
const {
91 if (m_maps[0]->find_authority() != m_maps[1]->find_authority()) {
92 log_error() <<
"Node map disconnected - more information in debug log"
93 <<
" (" <<
typeid(child_t).name() <<
")" << std::endl;
95 <<
"Note about node implementations.\n\n"
96 "In a node constructor that accepts a destination node,\n"
97 "a relation should always be established between the current node\n"
98 "and the destination using one of the member functions add_push_destination,\n"
99 "add_pull_source and add_dependency.\n\n"
100 "If this relational graph is not connected, some nodes will not\n"
101 "be initialized: prepare(), begin(), end() and other methods will never\n"
102 "be called, and memory will not be assigned.\n"
103 "---------------------------------------------------------------------------" << std::endl;
104 throw tpie::exception(
"Node map disconnected - did you forget to add_push_destination?");
120 void set_destination_kind_push() {
121 self().fact2.set_destination_kind_push();
127 void set_destination_kind_pull() {
128 self().fact1.set_destination_kind_pull();
132 child_t &
self() {
return *
static_cast<child_t*
>(
this);}
133 const child_t &
self()
const {
return *
static_cast<const child_t*
>(
this);}
135 boost::scoped_array<node_map::ptr> m_maps;
143 template <
typename fact_t>
146 template <
typename fact1_t,
typename fact2_t>
149 template <
typename dest_t>
150 using constructed_type =
typename fact1_t::template constructed_type<typename fact2_t::template constructed_type<dest_t>>;
158 : fact1(std::move(fact1)), fact2(std::move(fact2)) {
161 template <
typename dest_t>
162 constructed_type<dest_t> construct(dest_t && dest) {
163 return this->
record(0, fact1.construct(this->record(1, fact2.construct(std::forward<dest_t>(dest)))));
166 template <
typename dest_t>
167 constructed_type<dest_t> construct_copy(dest_t && dest) {
168 return this->
record(0, fact1.construct_copy(this->record(1, fact2.construct_copy(std::forward<dest_t>(dest)))));
171 void recursive_connected_check()
const {
177 fact1.hook_initialization(hook);
178 fact2.hook_initialization(hook);
185 template <
typename fact1_t,
typename termfact2_t>
188 using constructed_type =
typename fact1_t::template constructed_type<typename termfact2_t::constructed_type>;
196 : fact1(std::move(fact1))
197 , fact2(std::move(fact2))
204 constructed_type construct() {
205 return this->
record(0, fact1.construct(this->record(1, fact2.construct())));
208 constructed_type construct_copy() {
209 return this->
record(0, fact1.construct_copy(this->record(1, fact2.construct_copy())));
212 void recursive_connected_check()
const {
218 fact1.hook_initialization(hook);
219 fact2.hook_initialization(hook);
227 template <
typename fact1_t,
typename fact2_t>
230 fact.assert_connected();
237 template <
typename fact1_t,
typename termfact2_t>
240 fact.assert_connected();
248 template <
typename fact_t>
250 static void check(
const fact_t & ) {
256 #endif // __TPIE_PIPELINING_PAIR_FACTORY_H__