TPIE

v1.1rc1-6-g0c97303
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, 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/types.h>
24 #include <tpie/pipelining/priority_type.h>
25 #include <tpie/pipelining/graph.h>
26 #include <tpie/pipelining/pair_factory.h>
27 #include <tpie/pipelining/pipeline.h>
28 
29 namespace tpie {
30 
31 namespace pipelining {
32 
33 namespace bits {
34 
35 template <typename child_t>
36 class pipe_base {
37 public:
38  inline child_t & memory(double amount) {
39  self().factory.memory(amount);
40  return self();
41  }
42 
43  inline double memory() const {
44  return self().factory.memory();
45  }
46 
47  inline child_t & name(const std::string & n, priority_type p = PRIORITY_USER) {
48  self().factory.name(n, p);
49  return self();
50  }
51 
52  inline child_t & breadcrumb(const std::string & n) {
53  self().factory.push_breadcrumb(n);
54  return self();
55  }
56 
57 protected:
58  inline child_t & self() {return *static_cast<child_t*>(this);}
59  inline const child_t & self() const {return *static_cast<const child_t*>(this);}
60 };
61 
62 // The derived class has to pass its factory type to us as a template argument.
63 // See the following Stack Overflow question, dated Nov 13, 2011, for a discussion.
64 // http://stackoverflow.com/q/8113878
65 // At the time this class is instantiated, child_t is not yet complete.
66 // This means we cannot use child_t::factory_type as an existing type name.
67 template <typename child_t, typename fact_t>
68 class pipe_term_base : public pipe_base<child_t> {
69 public:
70  typedef typename fact_t::constructed_type constructed_type;
71 
72  constructed_type construct() const {
73  return this->self().factory.construct();
74  }
75 };
76 
77 // For this class, we only use child_t::factory_type inside
78 // a templated member type, so at the time of its instantiation,
79 // child_t is complete and child_t::factory_type is valid.
80 template <typename child_t>
81 class pipe_nonterm_base : public pipe_base<child_t> {
82 public:
83  template <typename dest_t>
84  struct constructed {
85  typedef typename child_t::factory_type::template constructed<dest_t>::type type;
86  };
87 
88  template <typename dest_t>
89  typename constructed<dest_t>::type construct(const dest_t & dest) const {
90  return this->self().factory.construct(dest);
91  }
92 };
93 
94 } // namespace bits
95 
96 template <typename fact_t>
97 class pipe_end : public bits::pipe_term_base<pipe_end<fact_t>, fact_t> {
98 public:
99  typedef fact_t factory_type;
100 
101  inline pipe_end() {
102  }
103 
104  inline pipe_end(const fact_t & factory) : factory(factory) {
105  }
106 
107  fact_t factory;
108 };
109 
118 template <typename fact_t>
119 class pipe_middle : public bits::pipe_nonterm_base<pipe_middle<fact_t> > {
120 public:
121  typedef fact_t factory_type;
122 
123  inline pipe_middle() {
124  }
125 
126  inline pipe_middle(const fact_t & factory) : factory(factory) {
127  }
128 
132  template <typename fact2_t>
135  return bits::pair_factory<fact_t, fact2_t>(factory, r.factory);
136  }
137 
142  template <typename fact2_t>
145  return bits::termpair_factory<fact_t, fact2_t>(factory, r.factory);
146  }
147 
148  fact_t factory;
149 };
150 
151 template <typename fact_t>
152 class pipe_begin : public bits::pipe_nonterm_base<pipe_begin<fact_t> > {
153 public:
154  typedef fact_t factory_type;
155 
156  inline pipe_begin() {
157  }
158 
159  inline pipe_begin(const fact_t & factory) : factory(factory) {
160  }
161 
162  template <typename fact2_t>
164  operator|(const pipe_middle<fact2_t> & r) {
165  return bits::pair_factory<fact_t, fact2_t>(factory, r.factory);
166  }
167 
168  template <typename fact2_t>
170  operator|(const pipe_end<fact2_t> & r) {
171  return bits::termpair_factory<fact_t, fact2_t>(factory, r.factory).final();
172  }
173 
174  fact_t factory;
175 };
176 
177 template <typename fact_t>
178 class pullpipe_end : public bits::pipe_nonterm_base<pullpipe_end<fact_t> > {
179 public:
180  typedef fact_t factory_type;
181 
182  inline pullpipe_end() {
183  }
184 
185  inline pullpipe_end(const fact_t & factory) : factory(factory) {
186  }
187 
188  fact_t factory;
189 };
190 
191 template <typename fact_t>
192 class pullpipe_middle : public bits::pipe_nonterm_base<pullpipe_middle<fact_t> > {
193 public:
194  typedef fact_t factory_type;
195 
196  inline pullpipe_middle() {
197  }
198 
199  inline pullpipe_middle(const fact_t & factory) : factory(factory) {
200  }
201 
202  template <typename fact2_t>
204  operator|(const pipe_middle<fact2_t> & r) {
205  return bits::pair_factory<fact2_t, fact_t>(r.factory, factory);
206  }
207 
208  template <typename fact2_t>
210  operator|(const pipe_end<fact2_t> & r) {
211  return bits::termpair_factory<fact2_t, fact_t>(r.factory, factory);
212  }
213 
214  fact_t factory;
215 };
216 
217 template <typename fact_t>
218 class pullpipe_begin : public bits::pipe_term_base<pullpipe_begin<fact_t>, fact_t> {
219 public:
220  typedef fact_t factory_type;
221 
222  inline pullpipe_begin() {
223  }
224 
225  inline pullpipe_begin(const fact_t & factory) : factory(factory) {
226  }
227 
228  template <typename fact2_t>
230  operator|(const pullpipe_middle<fact2_t> & r) {
231  return bits::termpair_factory<fact2_t, fact_t>(r.factory, factory);
232  }
233 
234  template <typename fact2_t>
236  operator|(const pullpipe_end<fact2_t> & r) {
237  return bits::termpair_factory<fact2_t, fact_t>(r.factory, factory).final();
238  }
239 
240  fact_t factory;
241 };
242 
243 } // namespace pipelining
244 
245 } // namespace tpie
246 
247 #endif // __TPIE_PIPELINING_PIPE_BASE_H__
Standard types.
pipe_end< bits::termpair_factory< fact_t, fact2_t > > operator|(const pipe_end< fact2_t > &r)
This pipe operator combines this generator/filter with a terminator to make a pipeline.
Definition: pipe_base.h:144
pipe_middle< bits::pair_factory< fact_t, fact2_t > > operator|(const pipe_middle< fact2_t > &r)
The pipe operator combines this generator/filter with another filter.
Definition: pipe_base.h:134
Traverse pipeline graphs.
A pipe_middle class pushes input down the pipeline.
Definition: pipe_base.h:119