TPIE

11a2c2d
pipe_base.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, 2013, 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_PIPE_BASE_H__
21 #define __TPIE_PIPELINING_PIPE_BASE_H__
22 
23 #include <tpie/tpie_export.h>
24 #include <tpie/types.h>
25 #include <tpie/pipelining/priority_type.h>
26 #include <tpie/pipelining/pair_factory.h>
27 #include <tpie/pipelining/pipeline.h>
28 #include <tpie/pipelining/node_set.h>
29 
30 #ifdef WIN32
31 // Silence warning C4521: multiple copy constructors specified.
32 // This warning is emitted since we declare both
33 // pipe_middle(const pipe_middle &) and
34 // pipe_middle(pipe_middle &).
35 // However, both of these are necessary to ensure that copying takes
36 // preference over the template <T> pipe_middle(T) constructor.
37 #pragma warning(push)
38 #pragma warning(disable: 4521)
39 #endif
40 
41 namespace tpie::pipelining {
42 namespace bits {
43 
44 template <typename child_t>
45 class pipe_base {
46 public:
47  pipe_base() = default;
48  pipe_base(pipe_base & other) = delete;
49  pipe_base(pipe_base && other) = default;
50  pipe_base & operator=(pipe_base & other) = delete;
51  pipe_base & operator=(pipe_base && other) = default;
52 
63  child_t memory(double amount) {
64  self().factory.memory(amount);
65  return std::move(self());
66  }
67 
74  double memory() const {
75  return self().factory.memory();
76  }
77 
90  child_t name(const std::string & n, priority_type p = PRIORITY_USER) {
91  self().factory.name(n, p);
92  return std::move(self());
93  }
94 
102  child_t phase_name(const std::string & n, priority_type p = PRIORITY_USER) {
103  self().factory.phase_name(n, p);
104  return std::move(self());
105  }
106 
107 
115  child_t add_to_set(node_set s) {
116  self().factory.add_to_set(s);
117  return std::move(self());
118  }
119 
125  child_t add_dependencies(node_set s) {
126  self().factory.add_dependencies(s);
127  return std::move(self());
128  }
129 
135  child_t add_forwarding_dependencies(node_set s) {
136  self().factory.add_forwarding_dependencies(s);
137  return std::move(self());
138  }
139 
147  child_t breadcrumb(const std::string & n) {
148  self().factory.push_breadcrumb(n);
149  return std::move(self());
150  }
151 
152  child_t forward_any(const std::string & key, any_noncopyable value) {
153  self().factory.forward(key, std::move(value));
154  return std::move(self());
155  }
156 
157  template <typename T>
158  child_t forward(const std::string & key, T value) {
159  return forward_any(key, any_noncopyable(value));
160  }
161 
162 protected:
163  child_t & self() {return *static_cast<child_t*>(this);}
164  const child_t & self() const {return *static_cast<const child_t*>(this);}
165 };
166 
167 // The derived class has to pass its factory type to us as a template argument.
168 // See the following Stack Overflow question, dated Nov 13, 2011, for a discussion.
169 // http://stackoverflow.com/q/8113878
170 // At the time this class is instantiated, child_t is not yet complete.
171 // This means we cannot use child_t::factory_type as an existing type name.
172 template <typename child_t, typename fact_t>
173 class pipe_term_base : public pipe_base<child_t> {
174 public:
175  typedef typename fact_t::constructed_type constructed_type;
176 
177  constructed_type construct() {
178  return this->self().factory.construct();
179  }
180 };
181 
182 // For this class, we only use child_t::factory_type inside
183 // a templated member type, so at the time of its instantiation,
184 // child_t is complete and child_t::factory_type is valid.
185 template <typename child_t>
186 class pipe_nonterm_base : public pipe_base<child_t> {
187 public:
188  pipe_nonterm_base() = default;
189  pipe_nonterm_base(const pipe_nonterm_base &) = delete;
190  pipe_nonterm_base(pipe_nonterm_base &&) = default;
191  pipe_nonterm_base & operator=(const pipe_nonterm_base &) = delete;
192  pipe_nonterm_base & operator=(pipe_nonterm_base &&) = default;
193 
194  template <typename dest_t>
195  class constructed {
196  public:
197  using type = typename child_t::factory_type::template constructed_type<dest_t>;
198  };
199 
200  template <typename dest_t>
201  using constructed_type = typename constructed<dest_t>::type;
202 
203  template <typename dest_t>
204  constructed_type<dest_t> construct(const dest_t & dest) {
205  return this->self().factory.construct(dest);
206  }
207 };
208 
209 } // namespace bits
210 
211 template <typename fact_t>
212 class pipe_end : public bits::pipe_term_base<pipe_end<fact_t>, fact_t> {
213 public:
214  typedef fact_t factory_type;
215 
225  template <typename ... T_ARGS>
226  pipe_end(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
227 
228  fact_t factory;
229 };
230 
231 
232 class empty_pipe_middle;
233 
242 template <typename fact_t>
243 class pipe_middle : public bits::pipe_nonterm_base<pipe_middle<fact_t> > {
244 public:
245  typedef fact_t factory_type;
246 
247  pipe_middle(const pipe_middle &) = delete;
248  pipe_middle(pipe_middle &&) = default;
249  pipe_middle & operator=(const pipe_middle &) = delete;
250  pipe_middle & operator=(pipe_middle &&) = default;
251 
252  pipe_middle(const fact_t && o) = delete;
253  pipe_middle(fact_t && o): factory(std::move(o)) {}
254  pipe_middle & operator=(const fact_t &) = delete;
255  pipe_middle & operator=(fact_t && o) {factory = std::move(o);}
256 
257 
258 
270  template <typename ... T_ARGS>
271  pipe_middle(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
272 
276  template <typename fact2_t>
280  return bits::pair_factory<fact_t, fact2_t>(std::move(factory), std::move(r.factory));
281  }
282 
287 
292  template <typename fact2_t>
296  return bits::termpair_factory<fact_t, fact2_t>(std::move(factory), std::move(r.factory));
297  }
298 
299  fact_t factory;
300 };
301 
307 class empty_pipe_middle : public bits::pipe_nonterm_base<empty_pipe_middle> {
308 public:
309  empty_pipe_middle() = default;
310  empty_pipe_middle(const empty_pipe_middle &) = delete;
311  empty_pipe_middle(empty_pipe_middle &&) = default;
312  empty_pipe_middle & operator=(const empty_pipe_middle &) = delete;
313  empty_pipe_middle & operator=(empty_pipe_middle &&) = default;
314 
318  template <typename fact_t>
319  pipe_middle<fact_t> operator|(pipe_middle<fact_t> && r) const {return std::move(r);}
320 
325  template <typename fact_t>
326  pipe_end<fact_t> operator|(pipe_end<fact_t> && r) const {return std::move(r);}
327 };
328 
329 
330 template <typename fact_t>
331 class pipe_begin : public bits::pipe_nonterm_base<pipe_begin<fact_t> > {
332 public:
333  pipe_begin(const pipe_begin<fact_t> &) = default;
334  pipe_begin(pipe_begin<fact_t> &&) = default;
335  pipe_begin & operator=(const pipe_begin<fact_t> &) = delete;
336  pipe_begin & operator=(pipe_begin<fact_t> &&) = default;
337 
338  pipe_begin(fact_t && f): factory(std::move(f)) {}
339 
340  typedef fact_t factory_type;
341 
342  //pipe_begin(fact_t && f) : factory(std::move(f)) {};
343 
355  // template <typename T1, typename ... T_ARGS, typename = typename std::enable_if<!std::is_same<pipe_begin, T1>::value, T1>::type>
356  // explicit inline pipe_begin(T1 && t1, T_ARGS && ... t) : factory(std::forward(t1), std::forward<T_ARGS>(t)...) {}
357 
358  template <typename ... T_ARGS>
359  pipe_begin(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
360 
361 
362  template <typename fact2_t>
364  operator|(pipe_middle<fact2_t> && r) {
366  return bits::pair_factory<fact_t, fact2_t>(std::move(factory), std::move(r.factory));
367  }
368 
369  pipe_begin operator|(empty_pipe_middle &&) {return pipe_begin(std::move(factory));}
370 
371  template <typename fact2_t>
372  bits::pipeline_impl<bits::termpair_factory<fact_t, fact2_t> >
373  operator|(pipe_end<fact2_t> && r) {
374  factory.set_destination_kind_push();
375  return bits::termpair_factory<fact_t, fact2_t>(std::move(factory), std::move(r.factory)).finalize();
376  }
377 
378  fact_t factory;
379 };
380 
381 template <typename fact_t>
382 class pullpipe_end : public bits::pipe_nonterm_base<pullpipe_end<fact_t> > {
383 public:
384  typedef fact_t factory_type;
385 
397  template <typename ... T_ARGS>
398  pullpipe_end(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
399 
400  fact_t factory;
401 };
402 
403 template <typename fact_t>
404 class pullpipe_middle : public bits::pipe_nonterm_base<pullpipe_middle<fact_t> > {
405 public:
406  typedef fact_t factory_type;
407 
419  template <typename ... T_ARGS>
420  pullpipe_middle(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
421 
422  template <typename fact2_t>
424  operator|(pipe_middle<fact2_t> && r) {
425  fact2_t f = std::move(r.factory);
426  f.set_destination_kind_pull();
427  return bits::pair_factory<fact2_t, fact_t>(std::move(f), std::move(factory));
428  }
429 
430  template <typename fact2_t>
431  pullpipe_end<bits::termpair_factory<fact2_t, fact_t> >
432  operator|(pipe_end<fact2_t> && r) {
433  fact2_t f = std::move(r.factory);
434  f.set_destination_kind_pull();
435  return bits::termpair_factory<fact2_t, fact_t>(std::move(f), std::move(factory));
436  }
437 
438  fact_t factory;
439 };
440 
441 template <typename fact_t>
442 class pullpipe_begin : public bits::pipe_term_base<pullpipe_begin<fact_t>, fact_t> {
443 public:
444  typedef fact_t factory_type;
445 
457  template <typename ... T_ARGS>
458  pullpipe_begin(T_ARGS && ... args) : factory(std::forward<T_ARGS>(args)...) {}
459 
460  template <typename fact2_t>
462  operator|(pullpipe_middle<fact2_t> && r) {
463  fact2_t f = std::move(r.factory);
464  f.set_destination_kind_pull();
465  return bits::termpair_factory<fact2_t, fact_t>(std::move(f), std::move(factory));
466  }
467 
468  template <typename fact2_t>
469  bits::pipeline_impl<bits::termpair_factory<fact2_t, fact_t> >
470  operator|(pullpipe_end<fact2_t> && r) {
471  fact2_t f = std::move(r.factory);
472  f.set_destination_kind_pull();
473  return bits::termpair_factory<fact2_t, fact_t>(std::move(f), std::move(factory)).finalize();
474  }
475 
476  fact_t factory;
477 };
478 
479 } // namespace tpie::pipelining
480 
481 #ifdef WIN32
482 #pragma warning(pop)
483 #endif
484 
485 #endif // __TPIE_PIPELINING_PIPE_BASE_H__
tpie::pipelining
pipelining/factory_base.h Base class of pipelining factories
Definition: ami_glue.h:23
tpie::pipelining::pipe_middle::operator|
pipe_middle< bits::pair_factory< fact_t, fact2_t > > operator|(pipe_middle< fact2_t > &&r)
The pipe operator combines this generator/filter with another filter.
Definition: pipe_base.h:278
tpie::pipelining::pipe_end::pipe_end
pipe_end(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:226
tpie::pipelining::factory
Definition: factory_helpers.h:35
tpie::pipelining::pipe_middle::pipe_middle
pipe_middle(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:271
tpie::pipelining::factory_base::push_breadcrumb
void push_breadcrumb(const std::string &n)
Set a prefix for the name of this node.
Definition: factory_base.h:183
tpie::pipelining::bits::termpair_factory
Definition: pair_factory.h:186
tpie::pipelining::pullpipe_begin
Definition: pipe_base.h:442
tpie::pipelining::bits::pipe_base::memory
child_t memory(double amount)
Set memory fraction for this node in the pipeline phase.
Definition: pipe_base.h:63
types.h
tpie::pipelining::pipe_begin
Definition: pipe_base.h:331
tpie::pipelining::bits::pipe_base::add_forwarding_dependencies
child_t add_forwarding_dependencies(node_set s)
Add a forwarding dependency to a referenced node.
Definition: pipe_base.h:135
tpie::pipelining::pipe_middle::operator|
pipe_middle operator|(empty_pipe_middle &&)
The pipe operator combines this generator/filter with another filter.
Definition: pipe_base.h:286
tpie::pipelining::pipe_end
Definition: pipe_base.h:212
tpie::pipelining::factory_base::phase_name
void phase_name(const std::string &n, priority_type p)
Set name for this phase.
Definition: factory_base.h:171
tpie::pipelining::bits::pipe_base::memory
double memory() const
Get memory fraction for this node in the pipeline phase.
Definition: pipe_base.h:74
tpie::pipelining::factory_base::memory
void memory(double amount) noexcept
Set memory fraction for this node in the pipeline phase.
Definition: factory_base.h:87
tpie::pipelining::pullpipe_middle::pullpipe_middle
pullpipe_middle(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:420
tpie::pipelining::pipe_begin::pipe_begin
pipe_begin(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:359
tpie::pipelining::bits::pipe_nonterm_base::constructed
Definition: pipe_base.h:195
tpie::pipelining::empty_pipe_middle::operator|
pipe_end< fact_t > operator|(pipe_end< fact_t > &&r) const
This pipe operator combines this generator/filter with a terminator to make a pipeline.
Definition: pipe_base.h:326
tpie::pipelining::factory_base::set_destination_kind_push
void set_destination_kind_push() noexcept
Used by pipe_base classes to indicate that the default actor edge is a push edge.
Definition: factory_base.h:192
tpie::pipelining::bits::pipe_base::name
child_t name(const std::string &n, priority_type p=PRIORITY_USER)
Set name for this node.
Definition: pipe_base.h:90
tpie::pipelining::bits::pipe_nonterm_base
Definition: pipe_base.h:186
tpie::pipelining::pullpipe_begin::pullpipe_begin
pullpipe_begin(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:458
tpie::pipelining::bits::pipe_base::phase_name
child_t phase_name(const std::string &n, priority_type p=PRIORITY_USER)
Set name for this phase.
Definition: pipe_base.h:102
tpie::pipelining::pullpipe_end
Definition: pipe_base.h:382
tpie::pipelining::pipe_middle
Definition: pipe_base.h:243
tpie::pipelining::empty_pipe_middle
Definition: pipe_base.h:307
tpie::pipelining::bits::pipe_base::breadcrumb
child_t breadcrumb(const std::string &n)
Set a prefix for the name of this node.
Definition: pipe_base.h:147
tpie::pipelining::empty_pipe_middle::operator|
pipe_middle< fact_t > operator|(pipe_middle< fact_t > &&r) const
The pipe operator combines this generator/filter with another filter.
Definition: pipe_base.h:319
tpie::pipelining::pullpipe_middle
Definition: pipe_base.h:404
tpie::pipelining::bits::pipe_base::add_dependencies
child_t add_dependencies(node_set s)
Add a depencency to a referenced node.
Definition: pipe_base.h:125
tpie::pipelining::pullpipe_end::pullpipe_end
pullpipe_end(T_ARGS &&... args)
Forwards the arguments given to the constructor of the factory.
Definition: pipe_base.h:398
tpie::pipelining::factory_base::name
void name(const std::string &n, priority_type p)
Set name for this node.
Definition: factory_base.h:160
tpie::pipelining::bits::pipe_base::add_to_set
child_t add_to_set(node_set s)
Get a refenerce to this node.
Definition: pipe_base.h:115
tpie::pipelining::pipe_middle::operator|
pipe_end< bits::termpair_factory< fact_t, fact2_t > > operator|(pipe_end< fact2_t > &&r)
This pipe operator combines this generator/filter with a terminator to make a pipeline.
Definition: pipe_base.h:294
tpie::pipelining::bits::pair_factory
Definition: pair_factory.h:147
tpie::pipelining::bits::pipe_base
Definition: pipe_base.h:45
tpie::pipelining::any_noncopyable
Definition: container.h:195
tpie::pipelining::bits::pipe_term_base
Definition: pipe_base.h:173