Stxxl  1.3.2
stream.h
1 /***************************************************************************
2  * include/stxxl/bits/stream/stream.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2003-2005 Roman Dementiev <[email protected]>
7  * Copyright (C) 2009, 2010 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2010 Johannes Singler <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_STREAM_HEADER
16 #define STXXL_STREAM_HEADER
17 
18 #include <stxxl/bits/namespace.h>
19 #include <stxxl/bits/mng/buf_istream.h>
20 #include <stxxl/bits/mng/buf_ostream.h>
21 #include <stxxl/bits/common/tuple.h>
22 #include <stxxl/vector>
23 #include <stxxl/bits/compat_unique_ptr.h>
24 
25 
26 #ifndef STXXL_VERBOSE_MATERIALIZE
27 #define STXXL_VERBOSE_MATERIALIZE STXXL_VERBOSE3
28 #endif
29 
30 
31 __STXXL_BEGIN_NAMESPACE
32 
34 namespace stream
35 {
60 
61 
63  // STREAMIFY //
65 
69  template <class InputIterator_>
71  {
72  InputIterator_ current_, end_;
73 
74  public:
76  typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
77 
78  iterator2stream(InputIterator_ begin, InputIterator_ end) :
79  current_(begin), end_(end) { }
80 
81  iterator2stream(const iterator2stream & a) : current_(a.current_), end_(a.end_) { }
82 
84  const value_type & operator * () const
85  {
86  return *current_;
87  }
88 
89  const value_type * operator -> () const
90  {
91  return &(*current_);
92  }
93 
96  {
97  assert(end_ != current_);
98  ++current_;
99  return *this;
100  }
101 
103  bool empty() const
104  {
105  return (current_ == end_);
106  }
107  };
108 
109 
114  template <class InputIterator_>
115  iterator2stream<InputIterator_> streamify(InputIterator_ begin, InputIterator_ end)
116  {
117  return iterator2stream<InputIterator_>(begin, end);
118  }
119 
121  template <class InputIterator_>
123  {
126  };
127 
132  template <class InputIterator_>
134  {
135  InputIterator_ current_, end_;
136  typedef buf_istream<typename InputIterator_::block_type,
137  typename InputIterator_::bids_container_iterator> buf_istream_type;
138 
139  typedef typename stxxl::compat_unique_ptr<buf_istream_type>::result buf_istream_unique_ptr_type;
140  mutable buf_istream_unique_ptr_type in;
141 
142  void delete_stream()
143  {
144  in.reset(); // delete object
145  }
146 
147  public:
149 
151  typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
152 
153  vector_iterator2stream(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0) :
154  current_(begin), end_(end), in(static_cast<buf_istream_type *>(NULL))
155  {
156  begin.flush(); // flush container
157  typename InputIterator_::bids_container_iterator end_iter = end.bid() + ((end.block_offset()) ? 1 : 0);
158 
159  if (end_iter - begin.bid() > 0)
160  {
161  in.reset(new buf_istream_type(begin.bid(), end_iter, nbuffers ? nbuffers :
162  (2 * config::get_instance()->disks_number())));
163 
164  InputIterator_ cur = begin - begin.block_offset();
165 
166  // skip the beginning of the block
167  for ( ; cur != begin; ++cur)
168  ++(*in);
169  }
170  }
171 
172  vector_iterator2stream(const Self_ & a) :
173  current_(a.current_), end_(a.end_), in(a.in.release()) { }
174 
176  const value_type & operator * () const
177  {
178  return **in;
179  }
180 
181  const value_type * operator -> () const
182  {
183  return &(**in);
184  }
185 
188  {
189  assert(end_ != current_);
190  ++current_;
191  ++(*in);
192  if (empty())
193  delete_stream();
194 
195  return *this;
196  }
197 
199  bool empty() const
200  {
201  return (current_ == end_);
202  }
203  virtual ~vector_iterator2stream()
204  {
205  delete_stream(); // not needed actually
206  }
207  };
208 
216 
217  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
218  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
219  vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
221  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
222  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
223  unsigned_type nbuffers = 0)
224  {
225  STXXL_VERBOSE1("streamify for vector_iterator range is called");
227  (begin, end, nbuffers);
228  }
229 
230  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
231  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
232  struct streamify_traits<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
233  {
234  typedef vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
235  };
236 
244 
245  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
246  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
247  vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
249  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
250  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
251  unsigned_type nbuffers = 0)
252  {
253  STXXL_VERBOSE1("streamify for const_vector_iterator range is called");
255  (begin, end, nbuffers);
256  }
257 
258  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
259  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
260  struct streamify_traits<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
261  {
262  typedef vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
263  };
264 
265 
272  template <class InputIterator_>
274  {
277 
278  typedef typename InputIterator_::block_type block_type;
279 
280  public:
282 
284  typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
285 
286  vector_iterator2stream_sr(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0)
287  {
288  if (end - begin < block_type::size)
289  {
290  STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing iterator2stream<InputIterator_>");
291  it_stream = new iterator2stream<InputIterator_>(begin, end);
292  vec_it_stream = NULL;
293  }
294  else
295  {
296  STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing vector_iterator2stream<InputIterator_>");
297  it_stream = NULL;
298  vec_it_stream = new vector_iterator2stream<InputIterator_>(begin, end, nbuffers);
299  }
300  }
301 
302  vector_iterator2stream_sr(const Self_ & a) : vec_it_stream(a.vec_it_stream), it_stream(a.it_stream) { }
303 
305  const value_type & operator * () const
306  {
307  if (it_stream)
308  return **it_stream;
309 
310  return **vec_it_stream;
311  }
312 
313  const value_type * operator -> () const
314  {
315  if (it_stream)
316  return &(**it_stream);
317 
318  return &(**vec_it_stream);
319  }
320 
323  {
324  if (it_stream)
325  ++(*it_stream);
326 
327  else
328  ++(*vec_it_stream);
329 
330 
331  return *this;
332  }
333 
335  bool empty() const
336  {
337  if (it_stream)
338  return it_stream->empty();
339 
340  return vec_it_stream->empty();
341  }
342  virtual ~vector_iterator2stream_sr()
343  {
344  if (it_stream)
345  delete it_stream;
346 
347  else
348  delete vec_it_stream;
349  }
350  };
351 
353  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
354  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
355  vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
357  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
358  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
359  unsigned_type nbuffers = 0)
360  {
361  STXXL_VERBOSE1("streamify_sr for vector_iterator range is called");
363  (begin, end, nbuffers);
364  }
365 
367  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
368  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
369  vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
371  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
372  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
373  unsigned_type nbuffers = 0)
374  {
375  STXXL_VERBOSE1("streamify_sr for const_vector_iterator range is called");
377  (begin, end, nbuffers);
378  }
379 
380 
382  // MATERIALIZE //
384 
391  template <class OutputIterator_, class StreamAlgorithm_>
392  OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ out)
393  {
394  STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
395  while (!in.empty())
396  {
397  *out = *in;
398  ++out;
399  ++in;
400  }
401  return out;
402  }
403 
404 
414  template <class OutputIterator_, class StreamAlgorithm_>
415  OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ outbegin, OutputIterator_ outend)
416  {
417  STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
418  while ((!in.empty()) && outend != outbegin)
419  {
420  *outbegin = *in;
421  ++outbegin;
422  ++in;
423  }
424  return outbegin;
425  }
426 
427 
439  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
440  unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
441  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
442  materialize(StreamAlgorithm_ & in,
443  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outbegin,
444  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outend,
445  unsigned_type nbuffers = 0)
446  {
447  STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
448  typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
449  typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
451 
452 
453  while (outbegin.block_offset()) // go to the beginning of the block
454  // of the external vector
455  {
456  if (in.empty() || outbegin == outend)
457  return outbegin;
458 
459  *outbegin = *in;
460  ++outbegin;
461  ++in;
462  }
463 
464  if (nbuffers == 0)
465  nbuffers = 2 * config::get_instance()->disks_number();
466 
467  outbegin.flush(); // flush container
468 
469  // create buffered write stream for blocks
470  buf_ostream_type outstream(outbegin.bid(), nbuffers);
471 
472  assert(outbegin.block_offset() == 0);
473 
474  // delay calling block_externally_updated() until the block is
475  // completely filled (and written out) in outstream
476  ConstExtIterator prev_block = outbegin;
477 
478  while (!in.empty() && outend != outbegin)
479  {
480  if (outbegin.block_offset() == 0) {
481  if (prev_block != outbegin) {
482  prev_block.block_externally_updated();
483  prev_block = outbegin;
484  }
485  }
486 
487  *outstream = *in;
488  ++outbegin;
489  ++outstream;
490  ++in;
491  }
492 
493  ConstExtIterator const_out = outbegin;
494 
495  while (const_out.block_offset()) // filling the rest of the block
496  {
497  *outstream = *const_out;
498  ++const_out;
499  ++outstream;
500  }
501 
502  if (prev_block != outbegin)
503  prev_block.block_externally_updated();
504 
505  outbegin.flush();
506 
507  return outbegin;
508  }
509 
510 
519  template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
520  unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
521  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
522  materialize(StreamAlgorithm_ & in,
523  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> out,
524  unsigned_type nbuffers = 0)
525  {
526  STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
527  typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
528  typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
530 
531  // on the I/O complexity of "materialize":
532  // crossing block boundary causes O(1) I/Os
533  // if you stay in a block, then materialize function accesses only the cache of the
534  // vector (only one block indeed), amortized complexity should apply here
535 
536  while (out.block_offset()) // go to the beginning of the block
537  // of the external vector
538  {
539  if (in.empty())
540  return out;
541 
542  *out = *in;
543  ++out;
544  ++in;
545  }
546 
547  if (nbuffers == 0)
548  nbuffers = 2 * config::get_instance()->disks_number();
549 
550 
551  out.flush(); // flush container
552 
553  // create buffered write stream for blocks
554  buf_ostream_type outstream(out.bid(), nbuffers);
555 
556  assert(out.block_offset() == 0);
557 
558  // delay calling block_externally_updated() until the block is
559  // completely filled (and written out) in outstream
560  ConstExtIterator prev_block = out;
561 
562  while (!in.empty())
563  {
564  if (out.block_offset() == 0) {
565  if (prev_block != out) {
566  prev_block.block_externally_updated();
567  prev_block = out;
568  }
569  }
570 
571  // tells the vector that the block was modified
572  *outstream = *in;
573  ++out;
574  ++outstream;
575  ++in;
576  }
577 
578  ConstExtIterator const_out = out;
579 
580  while (const_out.block_offset())
581  {
582  *outstream = *const_out; // might cause I/Os for loading the page that
583  ++const_out; // contains data beyond out
584  ++outstream;
585  }
586 
587  if (prev_block != out)
588  prev_block.block_externally_updated();
589 
590  out.flush();
591 
592  return out;
593  }
594 
595 
600  template <class StreamAlgorithm_>
601  void discard(StreamAlgorithm_ & in)
602  {
603  while (!in.empty())
604  {
605  *in;
606  ++in;
607  }
608  }
609 
610 
612  // GENERATE //
614 
618  template <class Generator_, typename T = typename Generator_::value_type>
620  {
621  public:
623  typedef T value_type;
624 
625  private:
626  Generator_ gen_;
627  value_type current_;
628 
629  public:
630  generator2stream(Generator_ g) :
631  gen_(g), current_(gen_()) { }
632 
633  generator2stream(const generator2stream & a) : gen_(a.gen_), current_(a.current_) { }
634 
636  const value_type & operator * () const
637  {
638  return current_;
639  }
640 
641  const value_type * operator -> () const
642  {
643  return &current_;
644  }
645 
648  {
649  current_ = gen_();
650  return *this;
651  }
652 
654  bool empty() const
655  {
656  return false;
657  }
658  };
659 
663  template <class Generator_>
665  {
666  return generator2stream<Generator_>(gen_);
667  }
668 
669 
671  // TRANSFORM //
673 
674  struct Stopper { };
675 
686  template <class Operation_,
687  class Input1_,
688  class Input2_ = Stopper,
689  class Input3_ = Stopper,
690  class Input4_ = Stopper,
691  class Input5_ = Stopper,
692  class Input6_ = Stopper
693  >
694  class transform
695  {
696  Operation_ & op;
697  Input1_ & i1;
698  Input2_ & i2;
699  Input3_ & i3;
700  Input4_ & i4;
701  Input5_ & i5;
702  Input6_ & i6;
703 
704  public:
706  typedef typename Operation_::value_type value_type;
707 
708  private:
709  value_type current;
710 
711  public:
713  transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
714  Input5_ & i5_, Input5_ & i6_) :
715  op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_)
716  {
717  if (!empty())
718  current = op(*i1, *i2, *i3, *i4, *i5, *i6);
719  }
720 
722  const value_type & operator * () const
723  {
724  return current;
725  }
726 
727  const value_type * operator -> () const
728  {
729  return &current;
730  }
731 
734  {
735  ++i1;
736  ++i2;
737  ++i3;
738  ++i4;
739  ++i5;
740  ++i6;
741  if (!empty())
742  current = op(*i1, *i2, *i3, *i4, *i5, *i6);
743 
744  return *this;
745  }
746 
748  bool empty() const
749  {
750  return i1.empty() || i2.empty() || i3.empty() ||
751  i4.empty() || i5.empty() || i6.empty();
752  }
753  };
754 
755  // Specializations
756 
758  // TRANSFORM (1 input stream) //
760 
767  template <class Operation_,
768  class Input1_
769  >
770  class transform<Operation_, Input1_, Stopper, Stopper, Stopper, Stopper, Stopper>
771  {
772  Operation_ & op;
773  Input1_ & i1;
774 
775  public:
777  typedef typename Operation_::value_type value_type;
778 
779  private:
780  value_type current;
781 
782  public:
784  transform(Operation_ & o, Input1_ & i1_) : op(o), i1(i1_)
785  {
786  if (!empty())
787  current = op(*i1);
788  }
789 
791  const value_type & operator * () const
792  {
793  return current;
794  }
795 
796  const value_type * operator -> () const
797  {
798  return &current;
799  }
800 
803  {
804  ++i1;
805  if (!empty())
806  current = op(*i1);
807 
808  return *this;
809  }
810 
812  bool empty() const
813  {
814  return i1.empty();
815  }
816  };
817 
818 
820  // TRANSFORM (2 input streams) //
822 
830  template <class Operation_,
831  class Input1_,
832  class Input2_
833  >
834  class transform<Operation_, Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
835  {
836  Operation_ & op;
837  Input1_ & i1;
838  Input2_ & i2;
839 
840  public:
842  typedef typename Operation_::value_type value_type;
843 
844  private:
845  value_type current;
846 
847  public:
849  transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_) : op(o), i1(i1_), i2(i2_)
850  {
851  if (!empty())
852  current = op(*i1, *i2);
853  }
854 
856  const value_type & operator * () const
857  {
858  return current;
859  }
860 
861  const value_type * operator -> () const
862  {
863  return &current;
864  }
865 
868  {
869  ++i1;
870  ++i2;
871  if (!empty())
872  current = op(*i1, *i2);
873 
874  return *this;
875  }
876 
878  bool empty() const
879  {
880  return i1.empty() || i2.empty();
881  }
882  };
883 
884 
886  // TRANSFORM (3 input streams) //
888 
897  template <class Operation_,
898  class Input1_,
899  class Input2_,
900  class Input3_
901  >
902  class transform<Operation_, Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
903  {
904  Operation_ & op;
905  Input1_ & i1;
906  Input2_ & i2;
907  Input3_ & i3;
908 
909  public:
911  typedef typename Operation_::value_type value_type;
912 
913  private:
914  value_type current;
915 
916  public:
918  transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_) :
919  op(o), i1(i1_), i2(i2_), i3(i3_)
920  {
921  if (!empty())
922  current = op(*i1, *i2, *i3);
923  }
924 
926  const value_type & operator * () const
927  {
928  return current;
929  }
930 
931  const value_type * operator -> () const
932  {
933  return &current;
934  }
935 
938  {
939  ++i1;
940  ++i2;
941  ++i3;
942  if (!empty())
943  current = op(*i1, *i2, *i3);
944 
945  return *this;
946  }
947 
949  bool empty() const
950  {
951  return i1.empty() || i2.empty() || i3.empty();
952  }
953  };
954 
955 
957  // TRANSFORM (4 input streams) //
959 
969  template <class Operation_,
970  class Input1_,
971  class Input2_,
972  class Input3_,
973  class Input4_
974  >
975  class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
976  {
977  Operation_ & op;
978  Input1_ & i1;
979  Input2_ & i2;
980  Input3_ & i3;
981  Input4_ & i4;
982 
983  public:
985  typedef typename Operation_::value_type value_type;
986 
987  private:
988  value_type current;
989 
990  public:
992  transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_) :
993  op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_)
994  {
995  if (!empty())
996  current = op(*i1, *i2, *i3, *i4);
997  }
998 
1000  const value_type & operator * () const
1001  {
1002  return current;
1003  }
1004 
1005  const value_type * operator -> () const
1006  {
1007  return &current;
1008  }
1009 
1012  {
1013  ++i1;
1014  ++i2;
1015  ++i3;
1016  ++i4;
1017  if (!empty())
1018  current = op(*i1, *i2, *i3, *i4);
1019 
1020  return *this;
1021  }
1022 
1024  bool empty() const
1025  {
1026  return i1.empty() || i2.empty() || i3.empty() || i4.empty();
1027  }
1028  };
1029 
1030 
1032  // TRANSFORM (5 input streams) //
1034 
1045  template <class Operation_,
1046  class Input1_,
1047  class Input2_,
1048  class Input3_,
1049  class Input4_,
1050  class Input5_
1051  >
1052  class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
1053  {
1054  Operation_ & op;
1055  Input1_ & i1;
1056  Input2_ & i2;
1057  Input3_ & i3;
1058  Input4_ & i4;
1059  Input5_ & i5;
1060 
1061  public:
1063  typedef typename Operation_::value_type value_type;
1064 
1065  private:
1066  value_type current;
1067 
1068  public:
1070  transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
1071  Input5_ & i5_) :
1072  op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_)
1073  {
1074  if (!empty())
1075  current = op(*i1, *i2, *i3, *i4, *i5);
1076  }
1077 
1079  const value_type & operator * () const
1080  {
1081  return current;
1082  }
1083 
1084  const value_type * operator -> () const
1085  {
1086  return &current;
1087  }
1088 
1091  {
1092  ++i1;
1093  ++i2;
1094  ++i3;
1095  ++i4;
1096  ++i5;
1097  if (!empty())
1098  current = op(*i1, *i2, *i3, *i4, *i5);
1099 
1100  return *this;
1101  }
1102 
1104  bool empty() const
1105  {
1106  return i1.empty() || i2.empty() || i3.empty() || i4.empty() || i5.empty();
1107  }
1108  };
1109 
1110 
1112  // MAKE TUPLE //
1114 
1123  template <class Input1_,
1124  class Input2_,
1125  class Input3_ = Stopper,
1126  class Input4_ = Stopper,
1127  class Input5_ = Stopper,
1128  class Input6_ = Stopper
1129  >
1131  {
1132  Input1_ & i1;
1133  Input2_ & i2;
1134  Input3_ & i3;
1135  Input4_ & i4;
1136  Input5_ & i5;
1137  Input6_ & i6;
1138 
1139  public:
1141  typedef typename stxxl::tuple<
1142  typename Input1_::value_type,
1143  typename Input2_::value_type,
1144  typename Input3_::value_type,
1145  typename Input4_::value_type,
1146  typename Input5_::value_type,
1147  typename Input6_::value_type
1149 
1150  private:
1151  value_type current;
1152 
1153  public:
1156  Input1_ & i1_,
1157  Input2_ & i2_,
1158  Input3_ & i3_,
1159  Input4_ & i4_,
1160  Input5_ & i5_,
1161  Input6_ & i6_
1162  ) :
1163  i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_),
1164  current(value_type(*i1, *i2, *i3, *i4, *i5, *i6)) { }
1165 
1167  const value_type & operator * () const
1168  {
1169  return current;
1170  }
1171 
1172  const value_type * operator -> () const
1173  {
1174  return &current;
1175  }
1176 
1179  {
1180  ++i1;
1181  ++i2;
1182  ++i3;
1183  ++i4;
1184  ++i5;
1185  ++i6;
1186 
1187  if (!empty())
1188  current = value_type(*i1, *i2, *i3, *i4, *i5, *i6);
1189 
1190  return *this;
1191  }
1192 
1194  bool empty() const
1195  {
1196  return i1.empty() || i2.empty() || i3.empty() ||
1197  i4.empty() || i5.empty() || i6.empty();
1198  }
1199  };
1200 
1201 
1207  template <class Input1_,
1208  class Input2_
1209  >
1210  class make_tuple<Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
1211  {
1212  Input1_ & i1;
1213  Input2_ & i2;
1214 
1215  public:
1217  typedef typename stxxl::tuple<
1218  typename Input1_::value_type,
1219  typename Input2_::value_type
1221 
1222  private:
1223  value_type current;
1224 
1225  public:
1228  Input1_ & i1_,
1229  Input2_ & i2_
1230  ) :
1231  i1(i1_), i2(i2_)
1232  {
1233  if (!empty())
1234  {
1235  current = value_type(*i1, *i2);
1236  }
1237  }
1238 
1240  const value_type & operator * () const
1241  {
1242  return current;
1243  }
1244 
1245  const value_type * operator -> () const
1246  {
1247  return &current;
1248  }
1249 
1252  {
1253  ++i1;
1254  ++i2;
1255 
1256  if (!empty())
1257  current = value_type(*i1, *i2);
1258 
1259  return *this;
1260  }
1261 
1263  bool empty() const
1264  {
1265  return i1.empty() || i2.empty();
1266  }
1267  };
1268 
1275  template <class Input1_,
1276  class Input2_,
1277  class Input3_
1278  >
1279  class make_tuple<Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
1280  {
1281  Input1_ & i1;
1282  Input2_ & i2;
1283  Input3_ & i3;
1284 
1285  public:
1287  typedef typename stxxl::tuple<
1288  typename Input1_::value_type,
1289  typename Input2_::value_type,
1290  typename Input3_::value_type
1292 
1293  private:
1294  value_type current;
1295 
1296  public:
1299  Input1_ & i1_,
1300  Input2_ & i2_,
1301  Input3_ & i3_
1302  ) :
1303  i1(i1_), i2(i2_), i3(i3_),
1304  current(value_type(*i1, *i2, *i3)) { }
1305 
1307  const value_type & operator * () const
1308  {
1309  return current;
1310  }
1311 
1312  const value_type * operator -> () const
1313  {
1314  return &current;
1315  }
1316 
1319  {
1320  ++i1;
1321  ++i2;
1322  ++i3;
1323 
1324  if (!empty())
1325  current = value_type(*i1, *i2, *i3);
1326 
1327  return *this;
1328  }
1329 
1331  bool empty() const
1332  {
1333  return i1.empty() || i2.empty() || i3.empty();
1334  }
1335  };
1336 
1344  template <class Input1_,
1345  class Input2_,
1346  class Input3_,
1347  class Input4_
1348  >
1349  class make_tuple<Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
1350  {
1351  Input1_ & i1;
1352  Input2_ & i2;
1353  Input3_ & i3;
1354  Input4_ & i4;
1355 
1356  public:
1358  typedef typename stxxl::tuple<
1359  typename Input1_::value_type,
1360  typename Input2_::value_type,
1361  typename Input3_::value_type,
1362  typename Input4_::value_type
1364 
1365  private:
1366  value_type current;
1367 
1368  public:
1371  Input1_ & i1_,
1372  Input2_ & i2_,
1373  Input3_ & i3_,
1374  Input4_ & i4_
1375  ) :
1376  i1(i1_), i2(i2_), i3(i3_), i4(i4_),
1377  current(value_type(*i1, *i2, *i3, *i4)) { }
1378 
1380  const value_type & operator * () const
1381  {
1382  return current;
1383  }
1384 
1385  const value_type * operator -> () const
1386  {
1387  return &current;
1388  }
1389 
1392  {
1393  ++i1;
1394  ++i2;
1395  ++i3;
1396  ++i4;
1397 
1398  if (!empty())
1399  current = value_type(*i1, *i2, *i3, *i4);
1400 
1401  return *this;
1402  }
1403 
1405  bool empty() const
1406  {
1407  return i1.empty() || i2.empty() || i3.empty() ||
1408  i4.empty();
1409  }
1410  };
1411 
1420  template <
1421  class Input1_,
1422  class Input2_,
1423  class Input3_,
1424  class Input4_,
1425  class Input5_
1426  >
1427  class make_tuple<Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
1428  {
1429  Input1_ & i1;
1430  Input2_ & i2;
1431  Input3_ & i3;
1432  Input4_ & i4;
1433  Input5_ & i5;
1434 
1435  public:
1437  typedef typename stxxl::tuple<
1438  typename Input1_::value_type,
1439  typename Input2_::value_type,
1440  typename Input3_::value_type,
1441  typename Input4_::value_type,
1442  typename Input5_::value_type
1444 
1445  private:
1446  value_type current;
1447 
1448  public:
1451  Input1_ & i1_,
1452  Input2_ & i2_,
1453  Input3_ & i3_,
1454  Input4_ & i4_,
1455  Input5_ & i5_
1456  ) :
1457  i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_),
1458  current(value_type(*i1, *i2, *i3, *i4, *i5)) { }
1459 
1461  const value_type & operator * () const
1462  {
1463  return current;
1464  }
1465 
1466  const value_type * operator -> () const
1467  {
1468  return &current;
1469  }
1470 
1473  {
1474  ++i1;
1475  ++i2;
1476  ++i3;
1477  ++i4;
1478  ++i5;
1479 
1480  if (!empty())
1481  current = value_type(*i1, *i2, *i3, *i4, *i5);
1482 
1483  return *this;
1484  }
1485 
1487  bool empty() const
1488  {
1489  return i1.empty() || i2.empty() || i3.empty() ||
1490  i4.empty() || i5.empty();
1491  }
1492  };
1493 
1494 
1496 }
1497 
1498 __STXXL_END_NAMESPACE
1499 
1500 
1501 #include <stxxl/bits/stream/choose.h>
1502 #include <stxxl/bits/stream/unique.h>
1503 
1504 
1505 #endif // !STXXL_STREAM_HEADER
1506 // vim: et:ts=4:sw=4
bool empty() const
Standard stream method.
Definition: stream.h:1104
generator2stream & operator++()
Standard stream method.
Definition: stream.h:647
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:985
stxxl::tuple< typename Input1_::value_type, typename Input2_::value_type > value_type
Standard stream typedef.
Definition: stream.h:1220
Creates stream of 6-tuples from 6 input streams.
Definition: stream.h:1130
Buffered input stream.
Definition: buf_istream.h:36
bool empty() const
Standard stream method.
Definition: stream.h:1024
const value_type & operator*() const
Standard stream method.
Definition: stream.h:722
std::iterator_traits< InputIterator_ >::value_type value_type
Standard stream typedef.
Definition: stream.h:284
make_tuple(Input1_ &i1_, Input2_ &i2_)
Construction.
Definition: stream.h:1227
const value_type & operator*() const
Standard stream method.
Definition: stream.h:84
bool empty() const
Standard stream method.
Definition: stream.h:1331
bool empty() const
Standard stream method.
Definition: stream.h:1487
std::iterator_traits< InputIterator_ >::value_type value_type
Standard stream typedef.
Definition: stream.h:151
transform(Operation_ &o, Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_, Input5_ &i5_)
Construction.
Definition: stream.h:1070
bool empty() const
Standard stream method.
Definition: stream.h:812
transform(Operation_ &o, Input1_ &i1_, Input2_ &i2_, Input3_ &i3_)
Construction.
Definition: stream.h:918
A model of stream that outputs data from an adaptable generator functor For convenience use streamify...
Definition: stream.h:619
iterator2stream< InputIterator_ > stream_type
return type (stream type) of streamify for InputIterator_
Definition: stream.h:125
bool empty() const
Standard stream method.
Definition: stream.h:199
void discard(StreamAlgorithm_ &in)
Reads stream content and discards it. Useful where you do not need the processed stream anymore...
Definition: stream.h:601
const value_type & operator*() const
Standard stream method.
Definition: stream.h:1167
bool empty() const
Standard stream method.
Definition: stream.h:1405
A model of stream that retrieves the data from an input iterator For convenience use streamify functi...
Definition: stream.h:70
stxxl::tuple< typename Input1_::value_type, typename Input2_::value_type, typename Input3_::value_type, typename Input4_::value_type, typename Input5_::value_type > value_type
Standard stream typedef.
Definition: stream.h:1443
make_tuple(Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_)
Construction.
Definition: stream.h:1370
iterator2stream< InputIterator_ > streamify(InputIterator_ begin, InputIterator_ end)
Input iterator range to stream converter.
Definition: stream.h:115
Traits class of streamify function.
Definition: stream.h:122
transform(Operation_ &o, Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_, Input5_ &i5_, Input5_ &i6_)
Construction.
Definition: stream.h:713
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:777
transform & operator++()
Standard stream method.
Definition: stream.h:733
iterator2stream & operator++()
Standard stream method.
Definition: stream.h:95
bool empty() const
Standard stream method.
Definition: stream.h:1263
transform(Operation_ &o, Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_)
Construction.
Definition: stream.h:992
T value_type
Standard stream typedef.
Definition: stream.h:623
bool empty() const
Standard stream method.
Definition: stream.h:748
make_tuple & operator++()
Standard stream method.
Definition: stream.h:1178
bool empty() const
Standard stream method.
Definition: stream.h:878
A model of stream that retrieves data from an external stxxl::vector iterator. It is more efficient t...
Definition: stream.h:133
Version of iterator2stream. Switches between vector_iterator2stream and iterator2stream ...
Definition: stream.h:273
Self_ & operator++()
Standard stream method.
Definition: stream.h:187
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:706
stxxl::tuple< typename Input1_::value_type, typename Input2_::value_type, typename Input3_::value_type, typename Input4_::value_type, typename Input5_::value_type, typename Input6_::value_type > value_type
Standard stream typedef.
Definition: stream.h:1148
make_tuple(Input1_ &i1_, Input2_ &i2_, Input3_ &i3_)
Construction.
Definition: stream.h:1298
Buffered output stream.
Definition: buf_ostream.h:30
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:842
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:911
bool empty() const
Standard stream method.
Definition: stream.h:654
OutputIterator_ materialize(StreamAlgorithm_ &in, OutputIterator_ out)
Stores consecutively stream content to an output iterator.
Definition: stream.h:392
bool empty() const
Standard stream method.
Definition: stream.h:103
Processes (up to) 6 input streams using given operation functor.
Definition: stream.h:694
Operation_::value_type value_type
Standard stream typedef.
Definition: stream.h:1063
const value_type & operator*() const
Standard stream method.
Definition: stream.h:176
vector_iterator2stream_sr< stxxl::vector_iterator< Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_ > > streamify_sr(stxxl::vector_iterator< Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_ > begin, stxxl::vector_iterator< Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_ > end, unsigned_type nbuffers=0)
Version of streamify. Switches from vector_iterator2stream to iterator2stream for small ranges...
Definition: stream.h:356
Const external vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:264
make_tuple(Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_, Input5_ &i5_, Input6_ &i6_)
Construction.
Definition: stream.h:1155
bool empty() const
Standard stream method.
Definition: stream.h:949
const value_type & operator*() const
Standard stream method.
Definition: stream.h:636
bool empty() const
Standard stream method.
Definition: stream.h:335
transform(Operation_ &o, Input1_ &i1_, Input2_ &i2_)
Construction.
Definition: stream.h:849
std::iterator_traits< InputIterator_ >::value_type value_type
Standard stream typedef.
Definition: stream.h:76
stxxl::tuple< typename Input1_::value_type, typename Input2_::value_type, typename Input3_::value_type, typename Input4_::value_type > value_type
Standard stream typedef.
Definition: stream.h:1363
bool empty() const
Standard stream method.
Definition: stream.h:1194
make_tuple(Input1_ &i1_, Input2_ &i2_, Input3_ &i3_, Input4_ &i4_, Input5_ &i5_)
Construction.
Definition: stream.h:1450
transform(Operation_ &o, Input1_ &i1_)
Construction.
Definition: stream.h:784
External vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:270
Self_ & operator++()
Standard stream method.
Definition: stream.h:322
stxxl::tuple< typename Input1_::value_type, typename Input2_::value_type, typename Input3_::value_type > value_type
Standard stream typedef.
Definition: stream.h:1291
const value_type & operator*() const
Standard stream method.
Definition: stream.h:305