TPIE

v1.1rc1-6-g0c97303
pair_factory.h
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2011, 2012, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
20 #ifndef __TPIE_PIPELINING_PAIR_FACTORY_H__
21 #define __TPIE_PIPELINING_PAIR_FACTORY_H__
22 
23 #include <tpie/types.h>
24 #include <tpie/pipelining/priority_type.h>
25 #include <tpie/pipelining/factory_base.h>
26 
27 namespace tpie {
28 
29 namespace pipelining {
30 
31 namespace bits {
32 
33 template <typename child_t>
35 public:
37  : m_maps(new node_map::ptr[2])
38  , m_final(false)
39  {
40  }
41 
43  : m_maps(new node_map::ptr[2])
44  , m_final(other.m_final)
45  {
46  m_maps[0] = other.m_maps[0];
47  m_maps[1] = other.m_maps[1];
48  }
49 
50  inline double memory() const {
51  return self().fact1.memory() + self().fact2.memory();
52  }
53 
54  inline void name(const std::string & n, priority_type) {
55  push_breadcrumb(n);
56  }
57 
58  void push_breadcrumb(const std::string & n) {
59  self().fact1.push_breadcrumb(n);
60  self().fact2.push_breadcrumb(n);
61  }
62 
67  self().hook_initialization_impl(hook);
68  }
69 
74  template <typename pipe_t>
75  pipe_t record(size_t idx, const pipe_t & pipe) const {
76  m_maps[idx] = pipe.get_node_map();
77  if (idx == 0 && m_final) {
78  // Now is the opportunity to check that the constructed pipeline is
79  // connected.
80  assert_connected();
81  self().recursive_connected_check();
82  }
83  return pipe;
84  }
85 
86  void assert_connected() const {
87  if (m_maps[0]->find_authority() != m_maps[1]->find_authority()) {
88  log_error() << "Segment map disconnected - more information in debug log." << std::endl;
89  log_debug()
90  << "Note about node implementations.\n\n"
91  "In a node constructor that accepts a destination node,\n"
92  "a relation should always be established between the current node\n"
93  "and the destination using one of the member functions add_push_destination,\n"
94  "add_pull_source and add_dependency.\n\n"
95  "If this relational graph is not connected, some nodes will not\n"
96  "be initialized: prepare(), begin(), end() and other methods will never\n"
97  "be called, and memory will not be assigned.\n"
98  "---------------------------------------------------------------------------" << std::endl;
99  throw tpie::exception("Segment map disconnected - did you forget to add_push_destination?");
100  }
101  }
102 
107  child_t & final() {
108  m_final = true;
109  return self();
110  }
111 
112 private:
113  inline child_t & self() {return *static_cast<child_t*>(this);}
114  inline const child_t & self() const {return *static_cast<const child_t*>(this);}
115 
116  boost::scoped_array<node_map::ptr> m_maps;
117  bool m_final;
118 };
119 
124 template <typename fact_t>
126 
127 template <typename fact1_t, typename fact2_t>
128 class pair_factory : public pair_factory_base<pair_factory<fact1_t, fact2_t> > {
129 public:
130  template <typename dest_t>
131  struct constructed {
132  typedef typename fact1_t::template constructed<typename fact2_t::template constructed<dest_t>::type>::type type;
133  };
134 
135  inline pair_factory(const fact1_t & fact1, const fact2_t & fact2)
136  : fact1(fact1), fact2(fact2) {
137  }
138 
139  template <typename dest_t>
140  typename constructed<dest_t>::type
141  construct(const dest_t & dest) const {
142  return this->record(0, fact1.construct(this->record(1, fact2.construct(dest))));
143  }
144 
145  void recursive_connected_check() const {
146  maybe_check_connected<fact1_t>::check(fact1);
147  maybe_check_connected<fact2_t>::check(fact2);
148  }
149 
150  void hook_initialization_impl(factory_init_hook * hook) {
151  fact1.hook_initialization(hook);
152  fact2.hook_initialization(hook);
153  }
154 
155  fact1_t fact1;
156  fact2_t fact2;
157 };
158 
159 template <typename fact1_t, typename termfact2_t>
160 class termpair_factory : public pair_factory_base<termpair_factory<fact1_t, termfact2_t> > {
161 public:
162  typedef typename fact1_t::template constructed<typename termfact2_t::constructed_type>::type constructed_type;
163 
164  inline termpair_factory(const fact1_t & fact1, const termfact2_t & fact2)
165  : fact1(fact1)
166  , fact2(fact2)
167  {
168  }
169 
170  fact1_t fact1;
171  termfact2_t fact2;
172 
173  constructed_type construct() const {
174  return this->record(0, fact1.construct(this->record(1, fact2.construct())));
175  }
176 
177  void recursive_connected_check() const {
180  }
181 
182  void hook_initialization_impl(factory_init_hook * hook) {
183  fact1.hook_initialization(hook);
184  fact2.hook_initialization(hook);
185  }
186 };
187 
192 template <typename fact1_t, typename fact2_t>
193 struct maybe_check_connected<pair_factory<fact1_t, fact2_t> > {
194  static void check(const pair_factory<fact1_t, fact2_t> & fact) {
195  fact.assert_connected();
196  }
197 };
198 
202 template <typename fact1_t, typename termfact2_t>
203 struct maybe_check_connected<termpair_factory<fact1_t, termfact2_t> > {
204  static void check(const termpair_factory<fact1_t, termfact2_t> & fact) {
205  fact.assert_connected();
206  }
207 };
208 
213 template <typename fact_t>
214 struct maybe_check_connected {
215  static void check(const fact_t & /*fact*/) {
216  }
217 };
218 
219 } // namespace bits
220 
221 } // namespace pipelining
222 
223 } // namespace tpie
224 
225 #endif // __TPIE_PIPELINING_PAIR_FACTORY_H__
void hook_initialization(factory_init_hook *hook)
See factory_base::hook_initialization.
Definition: pair_factory.h:66
Standard types.
Contains a method check that calls recursive_connected_check when fact_t is a pair factory...
Definition: pair_factory.h:125
pipe_t record(size_t idx, const pipe_t &pipe) const
Internal - used by subclasses to record references to node_maps for a later connectivity check...
Definition: pair_factory.h:75
logstream & log_debug()
Return logstream for writing debug log messages.
Definition: tpie_log.h:124
logstream & log_error()
Return logstream for writing error log messages.
Definition: tpie_log.h:104