TPIE

v1.1rc1-6-g0c97303
helpers.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_HELPERS_H__
21 #define __TPIE_PIPELINING_HELPERS_H__
22 
23 #include <iostream>
24 #include <tpie/pipelining/node.h>
25 #include <tpie/pipelining/factory_helpers.h>
26 #include <tpie/memory.h>
27 
28 namespace tpie {
29 
30 namespace pipelining {
31 
32 namespace bits {
33 
34 template <typename dest_t>
35 class ostream_logger_t : public node {
36 public:
37  typedef typename dest_t::item_type item_type;
38 
39  inline ostream_logger_t(const dest_t & dest, std::ostream & log) : dest(dest), log(log), begun(false), ended(false) {
41  set_name("Log", PRIORITY_INSIGNIFICANT);
42  }
43  virtual void begin() override {
44  node::begin();
45  begun = true;
46  }
47  virtual void end() override {
48  node::end();
49  ended = true;
50  }
51  inline void push(const item_type & item) {
52  if (!begun) {
53  log << "WARNING: push() called before begin(). Calling begin on rest of pipeline." << std::endl;
54  begin();
55  }
56  if (ended) {
57  log << "WARNING: push() called after end()." << std::endl;
58  ended = false;
59  }
60  log << "pushing " << item << std::endl;
61  dest.push(item);
62  }
63 private:
64  dest_t dest;
65  std::ostream & log;
66  bool begun;
67  bool ended;
68 };
69 
70 template <typename dest_t>
71 class identity_t : public node {
72 public:
73  typedef typename dest_t::item_type item_type;
74 
75  inline identity_t(const dest_t & dest) : dest(dest) {
77  set_name("Identity", PRIORITY_INSIGNIFICANT);
78  }
79 
80  inline void push(const item_type & item) {
81  dest.push(item);
82  }
83 private:
84  dest_t dest;
85 };
86 
87 template <typename source_t>
88 class pull_identity_t : public node {
89 public:
90  typedef typename source_t::item_type item_type;
91 
92  inline pull_identity_t(const source_t & source) : source(source) {
93  add_pull_source(source);
94  set_name("Identity", PRIORITY_INSIGNIFICANT);
95  }
96 
97  inline item_type pull() {
98  return source.pull();
99  }
100 
101  inline bool can_pull() {
102  return source.can_pull();
103  }
104 
105 private:
106  source_t source;
107 };
108 
109 template <typename T>
110 class dummydest_t : public node {
111 public:
112  dummydest_t() : buffer(new T()) {}
113 
114  typedef T item_type;
115  boost::shared_ptr<T> buffer;
116  inline void push(const T & el) {
117  *buffer = el;
118  }
119  inline T pull() {
120  return *buffer;
121  }
122 };
123 
124 template <typename pushfact_t>
126 public:
127 
128  template <typename source_t>
129  class puller_t : public node {
130  public:
131 
132  typedef typename source_t::item_type item_type;
133  typedef typename pushfact_t::template constructed<dummydest_t<item_type> >::type pusher_t;
134 
135  source_t source;
136  dummydest_t<item_type> dummydest;
137  pusher_t pusher;
138 
139  inline puller_t(const source_t & source, const pushfact_t & pushfact)
140  : source(source)
141  , pusher(pushfact.construct(dummydest))
142  {
143  add_pull_source(source);
144  add_push_destination(pusher);
145  }
146 
147  inline item_type pull() {
148  pusher.push(source.pull());
149  return dummydest.pull();
150  }
151 
152  inline bool can_pull() {
153  return source.can_pull();
154  }
155 
156  };
157 };
158 
159 template <typename pullfact_t>
161 public:
162 
163  template <typename dest_t>
164  class pusher_t : public node {
165  public:
166  typedef typename dest_t::item_type item_type;
167  typedef typename pullfact_t::template constructed<dummydest_t<item_type> >::type puller_t;
168 
169  dest_t dest;
170  dummydest_t<item_type> dummydest;
171  puller_t puller;
172 
173  inline pusher_t(const dest_t & dest, const pullfact_t & pullfact)
174  : dest(dest)
175  , puller(pullfact.construct(dummydest))
176  {
177  add_push_destination(dest);
178  add_pull_source(puller);
179  }
180 
181  inline void push(const item_type & item) {
182  dummydest.push(item);
183  dest.push(puller.pull());
184  }
185 
186  };
187 };
188 
189 template <typename T>
190 class bitbucket_t : public node {
191 public:
192  typedef T item_type;
193 
194  inline void push(const T &) {
195  }
196 };
197 
198 template <typename fact2_t>
199 class fork_t {
200 public:
201  typedef typename fact2_t::constructed_type dest2_t;
202 
203  template <typename dest_t>
204  class type : public node {
205  public:
206  typedef typename dest_t::item_type item_type;
207 
208  inline type(const dest_t & dest, const fact2_t & fact2) : dest(dest), dest2(fact2.construct()) {
209  add_push_destination(dest);
210  add_push_destination(dest2);
211  set_name("Fork", PRIORITY_INSIGNIFICANT);
212  }
213 
214  inline void push(const item_type & item) {
215  dest.push(item);
216  dest2.push(item);
217  }
218 
219  private:
220  dest_t dest;
221  dest2_t dest2;
222  };
223 };
224 
225 template <typename T>
226 class null_sink_t: public node {
227 public:
228  typedef T item_type;
229  void push(const T &) {}
230 };
231 
232 template <typename IT>
234  IT i;
235  IT till;
236 public:
237  typedef typename IT::value_type item_type;
238  pull_input_iterator_t(IT from, IT to)
239  : i(from)
240  , till(to)
241  {
242  set_name("Input iterator", PRIORITY_INSIGNIFICANT);
243  }
244 
245  bool can_pull() {
246  return i != till;
247  }
248 
249  item_type pull() {
250  return *i++;
251  }
252 };
253 
254 template <typename IT>
256 public:
257  template <typename dest_t>
258  class type : public node {
259  IT i;
260  IT till;
261  dest_t dest;
262  public:
263  type(dest_t dest, IT from, IT to)
264  : i(from)
265  , till(to)
266  , dest(dest)
267  {
268  set_name("Input iterator", PRIORITY_INSIGNIFICANT);
269  add_push_destination(dest);
270  }
271 
272  virtual void go() override {
273  while (i != till) {
274  dest.push(*i);
275  ++i;
276  }
277  }
278  };
279 };
280 
281 template <typename Iterator, typename Item = void>
283 
284 template <typename Iterator>
285 class push_output_iterator_t<Iterator, void> : public node {
286  Iterator i;
287 public:
288  typedef typename Iterator::value_type item_type;
289  push_output_iterator_t(Iterator to)
290  : i(to)
291  {
292  set_name("Output iterator", PRIORITY_INSIGNIFICANT);
293  }
294 
295  void push(const item_type & item) {
296  *i = item;
297  ++i;
298  }
299 };
300 
301 template <typename Iterator, typename Item>
302 class push_output_iterator_t : public node {
303  Iterator i;
304 public:
305  typedef Item item_type;
306  push_output_iterator_t(Iterator to)
307  : i(to)
308  {
309  set_name("Output iterator", PRIORITY_INSIGNIFICANT);
310  }
311 
312  void push(const item_type & item) {
313  *i = item;
314  ++i;
315  }
316 };
317 
318 template <typename IT>
320 public:
321  template <typename dest_t>
322  class type : public node {
323  IT i;
324  dest_t dest;
325  public:
326  type(dest_t dest, IT to)
327  : i(to)
328  , dest(dest)
329  {
330  set_name("Output iterator", PRIORITY_INSIGNIFICANT);
331  add_pull_source(dest);
332  }
333 
334  virtual void go() override {
335  while (dest.can_pull()) {
336  *i = dest.pull();
337  ++i;
338  }
339  }
340  };
341 };
342 
343 } // namespace bits
344 
345 inline pipe_middle<factory_1<bits::ostream_logger_t, std::ostream &> >
346 cout_logger() {
347  return factory_1<bits::ostream_logger_t, std::ostream &>(std::cout);
348 }
349 
350 inline pipe_middle<factory_0<bits::identity_t> > identity() {
351  return pipe_middle<factory_0<bits::identity_t> >();
352 }
353 
354 inline pullpipe_middle<factory_1<bits::push_to_pull<factory_0<bits::identity_t> >::puller_t, factory_0<bits::identity_t> > > pull_identity() {
355  return factory_1<bits::push_to_pull<factory_0<bits::identity_t> >::puller_t, factory_0<bits::identity_t> >(factory_0<bits::identity_t>());
356 }
357 
358 inline
359 pipe_middle<factory_1<
360  bits::pull_to_push<factory_0<bits::pull_identity_t> >::pusher_t,
361  factory_0<bits::pull_identity_t>
362 > >
363 alt_identity() {
364  return factory_1<
365  bits::pull_to_push<factory_0<bits::pull_identity_t> >::pusher_t,
366  factory_0<bits::pull_identity_t>
367  >(factory_0<bits::pull_identity_t>());
368 }
369 
370 template <typename T>
371 inline pipe_end<termfactory_0<bits::bitbucket_t<T> > >
372 bitbucket(T) {
373  return termfactory_0<bits::bitbucket_t<T> >();
374 }
375 
376 template <typename fact_t>
377 inline pipe_middle<tempfactory_1<bits::fork_t<fact_t>, const fact_t &> >
378 fork(const pipe_end<fact_t> & to) {
379  return tempfactory_1<bits::fork_t<fact_t>, const fact_t &>(to.factory);
380 }
381 
382 template <typename T>
383 inline pipe_end<termfactory_0<bits::null_sink_t<T> > >
384 null_sink() {return termfactory_0<bits::null_sink_t<T> >();}
385 
386 template <template <typename dest_t> class Fact>
387 pipe_begin<factory_0<Fact> > make_pipe_begin_0() {
388  return pipe_begin<factory_0<Fact> >(factory_0<Fact>());
389 }
390 
391 template <template <typename dest_t> class Fact>
392 pipe_middle<factory_0<Fact> > make_pipe_middle_0() {
393  return pipe_middle<factory_0<Fact> >(factory_0<Fact>());
394 }
395 
396 template <typename Fact>
397 pipe_end<termfactory_0<Fact> > make_pipe_end_0() {
398  return pipe_end<termfactory_0<Fact> >(termfactory_0<Fact>());
399 }
400 
401 template <template <typename dest_t> class Fact, typename T1>
402 pipe_begin<factory_1<Fact, T1> > make_pipe_begin_1(T1 e1) {
403  return pipe_begin<factory_1<Fact, T1> >(factory_1<Fact, T1>(e1));
404 }
405 
406 template <template <typename dest_t> class Fact, typename T1>
407 pipe_middle<factory_1<Fact, T1> > make_pipe_middle_1(T1 e1) {
408  return pipe_middle<factory_1<Fact, T1> >(factory_1<Fact, T1>(e1));
409 }
410 
411 template <typename Fact, typename T1>
412 pipe_end<termfactory_1<Fact, T1> > make_pipe_end_1(T1 e1) {
413  return pipe_end<termfactory_1<Fact, T1> >(termfactory_1<Fact, T1>(e1));
414 }
415 
416 template <template <typename dest_t> class Fact, typename T1, typename T2>
417 pipe_begin<factory_2<Fact, T1, T2> > make_pipe_begin_2(T1 e1, T2 e2) {
418  return pipe_begin<factory_2<Fact, T1, T2> >(factory_2<Fact, T1, T2>(e1, e2));
419 }
420 
421 template <template <typename dest_t> class Fact, typename T1, typename T2>
422 pipe_middle<factory_2<Fact, T1, T2> > make_pipe_middle_2(T1 e1, T2 e2) {
423  return pipe_middle<factory_2<Fact, T1, T2> >(factory_2<Fact, T1, T2>(e1, e2));
424 }
425 
426 template <typename Fact, typename T1, typename T2>
427 pipe_end<termfactory_2<Fact, T1, T2> > make_pipe_end_2(T1 e1, T2 e2) {
428  return pipe_end<termfactory_2<Fact, T1, T2> >(termfactory_2<Fact, T1, T2>(e1, e2));
429 }
430 
431 template <typename IT>
432 pullpipe_begin<termfactory_2<bits::pull_input_iterator_t<IT>, IT, IT> > pull_input_iterator(IT begin, IT end) {
433  return termfactory_2<bits::pull_input_iterator_t<IT>, IT, IT>(begin, end);
434 }
435 
436 template <typename IT>
437 pipe_begin<tempfactory_2<bits::push_input_iterator_t<IT>, IT, IT> > push_input_iterator(IT begin, IT end) {
438  return tempfactory_2<bits::push_input_iterator_t<IT>, IT, IT>(begin, end);
439 }
440 
441 template <typename IT>
442 pipe_end<termfactory_1<bits::push_output_iterator_t<IT>, IT> > push_output_iterator(IT to) {
443  return termfactory_1<bits::push_output_iterator_t<IT>, IT>(to);
444 }
445 
446 template <typename Item, typename IT>
447 pipe_end<termfactory_1<bits::push_output_iterator_t<IT, Item>, IT> > typed_push_output_iterator(IT to) {
448  return termfactory_1<bits::push_output_iterator_t<IT, Item>, IT>(to);
449 }
450 
451 template <typename IT>
452 pullpipe_end<tempfactory_1<bits::pull_output_iterator_t<IT>, IT> > pull_output_iterator(IT to) {
453  return tempfactory_1<bits::pull_output_iterator_t<IT>, IT>(to);
454 }
455 
456 }
457 
458 }
459 
460 #endif
virtual void begin()
Begin pipeline processing phase.
Definition: node.h:167
Memory management subsystem.
void add_pull_source(const node_token &dest)
Called by implementers to declare a pull source.
Definition: node.h:370
Base class of all nodes.
Definition: node.h:58
void add_push_destination(const node_token &dest)
Called by implementers to declare a push destination.
Definition: node.h:352
virtual void end() override
End pipeline processing phase.
Definition: helpers.h:47
virtual void begin() override
Begin pipeline processing phase.
Definition: helpers.h:43
void set_name(const std::string &name, priority_type priority=PRIORITY_USER)
Set this node's name.
Definition: node.h:241
virtual void end()
End pipeline processing phase.
Definition: node.h:205
virtual void go() override
For initiator nodes, execute this phase by pushing all items to be pushed.
Definition: helpers.h:334
virtual void go() override
For initiator nodes, execute this phase by pushing all items to be pushed.
Definition: helpers.h:272