00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef STXXL_STREAM_HEADER
00014 #define STXXL_STREAM_HEADER
00015
00016 #include <stxxl/bits/namespace.h>
00017 #include <stxxl/bits/mng/buf_istream.h>
00018 #include <stxxl/bits/mng/buf_ostream.h>
00019 #include <stxxl/bits/common/tuple.h>
00020 #include <stxxl/vector>
00021 #include <stxxl/bits/compat_unique_ptr.h>
00022
00023
00024 #ifndef STXXL_VERBOSE_MATERIALIZE
00025 #define STXXL_VERBOSE_MATERIALIZE STXXL_VERBOSE3
00026 #endif
00027
00028
00029 __STXXL_BEGIN_NAMESPACE
00030
00032 namespace stream
00033 {
00058
00059
00061
00063
00067 template <class InputIterator_>
00068 class iterator2stream
00069 {
00070 InputIterator_ current_, end_;
00071
00072 public:
00074 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00075
00076 iterator2stream(InputIterator_ begin, InputIterator_ end) :
00077 current_(begin), end_(end) { }
00078
00079 iterator2stream(const iterator2stream & a) : current_(a.current_), end_(a.end_) { }
00080
00082 const value_type & operator * () const
00083 {
00084 return *current_;
00085 }
00086
00087 const value_type * operator -> () const
00088 {
00089 return &(*current_);
00090 }
00091
00093 iterator2stream & operator ++ ()
00094 {
00095 assert(end_ != current_);
00096 ++current_;
00097 return *this;
00098 }
00099
00101 bool empty() const
00102 {
00103 return (current_ == end_);
00104 }
00105 };
00106
00107
00112 template <class InputIterator_>
00113 iterator2stream<InputIterator_> streamify(InputIterator_ begin, InputIterator_ end)
00114 {
00115 return iterator2stream<InputIterator_>(begin, end);
00116 }
00117
00119 template <class InputIterator_>
00120 struct streamify_traits
00121 {
00123 typedef iterator2stream<InputIterator_> stream_type;
00124 };
00125
00130 template <class InputIterator_>
00131 class vector_iterator2stream
00132 {
00133 InputIterator_ current_, end_;
00134 typedef buf_istream<typename InputIterator_::block_type,
00135 typename InputIterator_::bids_container_iterator> buf_istream_type;
00136
00137 typedef typename stxxl::compat_unique_ptr<buf_istream_type>::result buf_istream_unique_ptr_type;
00138 mutable buf_istream_unique_ptr_type in;
00139
00140 void delete_stream()
00141 {
00142 in.reset();
00143 }
00144
00145 public:
00146 typedef vector_iterator2stream<InputIterator_> Self_;
00147
00149 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00150
00151 vector_iterator2stream(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0) :
00152 current_(begin), end_(end), in(static_cast<buf_istream_type *>(NULL))
00153 {
00154 begin.flush();
00155 typename InputIterator_::bids_container_iterator end_iter = end.bid() + ((end.block_offset()) ? 1 : 0);
00156
00157 if (end_iter - begin.bid() > 0)
00158 {
00159 in.reset(new buf_istream_type(begin.bid(), end_iter, nbuffers ? nbuffers :
00160 (2 * config::get_instance()->disks_number())));
00161
00162 InputIterator_ cur = begin - begin.block_offset();
00163
00164
00165 for ( ; cur != begin; ++cur)
00166 ++(*in);
00167 }
00168 }
00169
00170 vector_iterator2stream(const Self_ & a) :
00171 current_(a.current_), end_(a.end_), in(a.in.release()) { }
00172
00174 const value_type & operator * () const
00175 {
00176 return **in;
00177 }
00178
00179 const value_type * operator -> () const
00180 {
00181 return &(**in);
00182 }
00183
00185 Self_ & operator ++ ()
00186 {
00187 assert(end_ != current_);
00188 ++current_;
00189 ++(*in);
00190 if (empty())
00191 delete_stream();
00192
00193 return *this;
00194 }
00195
00197 bool empty() const
00198 {
00199 return (current_ == end_);
00200 }
00201 virtual ~vector_iterator2stream()
00202 {
00203 delete_stream();
00204 }
00205 };
00206
00214
00215 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00216 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00217 vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00218 streamify(
00219 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00220 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00221 unsigned_type nbuffers = 0)
00222 {
00223 STXXL_VERBOSE1("streamify for vector_iterator range is called");
00224 return vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00225 (begin, end, nbuffers);
00226 }
00227
00228 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00229 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00230 struct streamify_traits<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00231 {
00232 typedef vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00233 };
00234
00242
00243 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00244 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00245 vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00246 streamify(
00247 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00248 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00249 unsigned_type nbuffers = 0)
00250 {
00251 STXXL_VERBOSE1("streamify for const_vector_iterator range is called");
00252 return vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00253 (begin, end, nbuffers);
00254 }
00255
00256 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00257 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00258 struct streamify_traits<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00259 {
00260 typedef vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00261 };
00262
00263
00270 template <class InputIterator_>
00271 class vector_iterator2stream_sr
00272 {
00273 vector_iterator2stream<InputIterator_> * vec_it_stream;
00274 iterator2stream<InputIterator_> * it_stream;
00275
00276 typedef typename InputIterator_::block_type block_type;
00277
00278 public:
00279 typedef vector_iterator2stream_sr<InputIterator_> Self_;
00280
00282 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00283
00284 vector_iterator2stream_sr(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0)
00285 {
00286 if (end - begin < block_type::size)
00287 {
00288 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing iterator2stream<InputIterator_>");
00289 it_stream = new iterator2stream<InputIterator_>(begin, end);
00290 vec_it_stream = NULL;
00291 }
00292 else
00293 {
00294 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing vector_iterator2stream<InputIterator_>");
00295 it_stream = NULL;
00296 vec_it_stream = new vector_iterator2stream<InputIterator_>(begin, end, nbuffers);
00297 }
00298 }
00299
00300 vector_iterator2stream_sr(const Self_ & a) : vec_it_stream(a.vec_it_stream), it_stream(a.it_stream) { }
00301
00303 const value_type & operator * () const
00304 {
00305 if (it_stream)
00306 return **it_stream;
00307
00308 return **vec_it_stream;
00309 }
00310
00311 const value_type * operator -> () const
00312 {
00313 if (it_stream)
00314 return &(**it_stream);
00315
00316 return &(**vec_it_stream);
00317 }
00318
00320 Self_ & operator ++ ()
00321 {
00322 if (it_stream)
00323 ++(*it_stream);
00324
00325 else
00326 ++(*vec_it_stream);
00327
00328
00329 return *this;
00330 }
00331
00333 bool empty() const
00334 {
00335 if (it_stream)
00336 return it_stream->empty();
00337
00338 return vec_it_stream->empty();
00339 }
00340 virtual ~vector_iterator2stream_sr()
00341 {
00342 if (it_stream)
00343 delete it_stream;
00344
00345 else
00346 delete vec_it_stream;
00347 }
00348 };
00349
00351 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00352 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00353 vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00354 streamify_sr(
00355 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00356 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00357 unsigned_type nbuffers = 0)
00358 {
00359 STXXL_VERBOSE1("streamify_sr for vector_iterator range is called");
00360 return vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00361 (begin, end, nbuffers);
00362 }
00363
00365 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00366 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00367 vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00368 streamify_sr(
00369 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00370 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00371 unsigned_type nbuffers = 0)
00372 {
00373 STXXL_VERBOSE1("streamify_sr for const_vector_iterator range is called");
00374 return vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00375 (begin, end, nbuffers);
00376 }
00377
00378
00380
00382
00389 template <class OutputIterator_, class StreamAlgorithm_>
00390 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ out)
00391 {
00392 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00393 while (!in.empty())
00394 {
00395 *out = *in;
00396 ++out;
00397 ++in;
00398 }
00399 return out;
00400 }
00401
00402
00412 template <class OutputIterator_, class StreamAlgorithm_>
00413 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ outbegin, OutputIterator_ outend)
00414 {
00415 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00416 while ((!in.empty()) && outend != outbegin)
00417 {
00418 *outbegin = *in;
00419 ++outbegin;
00420 ++in;
00421 }
00422 return outbegin;
00423 }
00424
00425
00437 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00438 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00439 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00440 materialize(StreamAlgorithm_ & in,
00441 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outbegin,
00442 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outend,
00443 unsigned_type nbuffers = 0)
00444 {
00445 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00446 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00447 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00448 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00449
00450
00451 while (outbegin.block_offset())
00452
00453 {
00454 if (in.empty() || outbegin == outend)
00455 return outbegin;
00456
00457 *outbegin = *in;
00458 ++outbegin;
00459 ++in;
00460 }
00461
00462 if (nbuffers == 0)
00463 nbuffers = 2 * config::get_instance()->disks_number();
00464
00465 outbegin.flush();
00466
00467
00468 buf_ostream_type outstream(outbegin.bid(), nbuffers);
00469
00470 assert(outbegin.block_offset() == 0);
00471
00472
00473
00474 ConstExtIterator prev_block = outbegin;
00475
00476 while (!in.empty() && outend != outbegin)
00477 {
00478 if (outbegin.block_offset() == 0) {
00479 if (prev_block != outbegin) {
00480 prev_block.block_externally_updated();
00481 prev_block = outbegin;
00482 }
00483 }
00484
00485 *outstream = *in;
00486 ++outbegin;
00487 ++outstream;
00488 ++in;
00489 }
00490
00491 ConstExtIterator const_out = outbegin;
00492
00493 while (const_out.block_offset())
00494 {
00495 *outstream = *const_out;
00496 ++const_out;
00497 ++outstream;
00498 }
00499
00500 if (prev_block != outbegin)
00501 prev_block.block_externally_updated();
00502
00503 outbegin.flush();
00504
00505 return outbegin;
00506 }
00507
00508
00517 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00518 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00519 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00520 materialize(StreamAlgorithm_ & in,
00521 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> out,
00522 unsigned_type nbuffers = 0)
00523 {
00524 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00525 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00526 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00527 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00528
00529
00530
00531
00532
00533
00534 while (out.block_offset())
00535
00536 {
00537 if (in.empty())
00538 return out;
00539
00540 *out = *in;
00541 ++out;
00542 ++in;
00543 }
00544
00545 if (nbuffers == 0)
00546 nbuffers = 2 * config::get_instance()->disks_number();
00547
00548
00549 out.flush();
00550
00551
00552 buf_ostream_type outstream(out.bid(), nbuffers);
00553
00554 assert(out.block_offset() == 0);
00555
00556
00557
00558 ConstExtIterator prev_block = out;
00559
00560 while (!in.empty())
00561 {
00562 if (out.block_offset() == 0) {
00563 if (prev_block != out) {
00564 prev_block.block_externally_updated();
00565 prev_block = out;
00566 }
00567 }
00568
00569
00570 *outstream = *in;
00571 ++out;
00572 ++outstream;
00573 ++in;
00574 }
00575
00576 ConstExtIterator const_out = out;
00577
00578 while (const_out.block_offset())
00579 {
00580 *outstream = *const_out;
00581 ++const_out;
00582 ++outstream;
00583 }
00584
00585 if (prev_block != out)
00586 prev_block.block_externally_updated();
00587
00588 out.flush();
00589
00590 return out;
00591 }
00592
00593
00595
00597
00601 template <class Generator_, typename T = typename Generator_::value_type>
00602 class generator2stream
00603 {
00604 public:
00606 typedef T value_type;
00607
00608 private:
00609 Generator_ gen_;
00610 value_type current_;
00611
00612 public:
00613 generator2stream(Generator_ g) :
00614 gen_(g), current_(gen_()) { }
00615
00616 generator2stream(const generator2stream & a) : gen_(a.gen_), current_(a.current_) { }
00617
00619 const value_type & operator * () const
00620 {
00621 return current_;
00622 }
00623
00624 const value_type * operator -> () const
00625 {
00626 return ¤t_;
00627 }
00628
00630 generator2stream & operator ++ ()
00631 {
00632 current_ = gen_();
00633 return *this;
00634 }
00635
00637 bool empty() const
00638 {
00639 return false;
00640 }
00641 };
00642
00646 template <class Generator_>
00647 generator2stream<Generator_> streamify(Generator_ gen_)
00648 {
00649 return generator2stream<Generator_>(gen_);
00650 }
00651
00652
00654
00656
00657 struct Stopper { };
00658
00670 template <class Operation_,
00671 class Input1_,
00672 class Input2_ = Stopper,
00673 class Input3_ = Stopper,
00674 class Input4_ = Stopper,
00675 class Input5_ = Stopper,
00676 class Input6_ = Stopper
00677 >
00678 class transform
00679 {
00680 Operation_ & op;
00681 Input1_ & i1;
00682 Input2_ & i2;
00683 Input3_ & i3;
00684 Input4_ & i4;
00685 Input5_ & i5;
00686 Input6_ & i6;
00687
00688 public:
00690 typedef typename Operation_::value_type value_type;
00691
00692 private:
00693 value_type current;
00694
00695 public:
00697 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
00698 Input5_ & i5_, Input5_ & i6_) :
00699 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_)
00700 {
00701 if (!empty())
00702 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00703 }
00704
00706 const value_type & operator * () const
00707 {
00708 return current;
00709 }
00710
00711 const value_type * operator -> () const
00712 {
00713 return ¤t;
00714 }
00715
00717 transform & operator ++ ()
00718 {
00719 ++i1;
00720 ++i2;
00721 ++i3;
00722 ++i4;
00723 ++i5;
00724 ++i6;
00725 if (!empty())
00726 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00727
00728 return *this;
00729 }
00730
00732 bool empty() const
00733 {
00734 return i1.empty() || i2.empty() || i3.empty() ||
00735 i4.empty() || i5.empty() || i6.empty();
00736 }
00737 };
00738
00739
00740
00742
00744
00752 template <class Operation_,
00753 class Input1_
00754 >
00755 class transform<Operation_, Input1_, Stopper, Stopper, Stopper, Stopper, Stopper>
00756 {
00757 Operation_ & op;
00758 Input1_ & i1;
00759
00760 public:
00762 typedef typename Operation_::value_type value_type;
00763
00764 private:
00765 value_type current;
00766
00767 public:
00769 transform(Operation_ & o, Input1_ & i1_) : op(o), i1(i1_)
00770 {
00771 if (!empty())
00772 current = op(*i1);
00773 }
00774
00776 const value_type & operator * () const
00777 {
00778 return current;
00779 }
00780
00781 const value_type * operator -> () const
00782 {
00783 return ¤t;
00784 }
00785
00787 transform & operator ++ ()
00788 {
00789 ++i1;
00790 if (!empty())
00791 current = op(*i1);
00792
00793 return *this;
00794 }
00795
00797 bool empty() const
00798 {
00799 return i1.empty();
00800 }
00801 };
00802
00803
00805
00807
00816 template <class Operation_,
00817 class Input1_,
00818 class Input2_
00819 >
00820 class transform<Operation_, Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
00821 {
00822 Operation_ & op;
00823 Input1_ & i1;
00824 Input2_ & i2;
00825
00826 public:
00828 typedef typename Operation_::value_type value_type;
00829
00830 private:
00831 value_type current;
00832
00833 public:
00835 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_) : op(o), i1(i1_), i2(i2_)
00836 {
00837 if (!empty())
00838 current = op(*i1, *i2);
00839 }
00840
00842 const value_type & operator * () const
00843 {
00844 return current;
00845 }
00846
00847 const value_type * operator -> () const
00848 {
00849 return ¤t;
00850 }
00851
00853 transform & operator ++ ()
00854 {
00855 ++i1;
00856 ++i2;
00857 if (!empty())
00858 current = op(*i1, *i2);
00859
00860 return *this;
00861 }
00862
00864 bool empty() const
00865 {
00866 return i1.empty() || i2.empty();
00867 }
00868 };
00869
00870
00872
00874
00884 template <class Operation_,
00885 class Input1_,
00886 class Input2_,
00887 class Input3_
00888 >
00889 class transform<Operation_, Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
00890 {
00891 Operation_ & op;
00892 Input1_ & i1;
00893 Input2_ & i2;
00894 Input3_ & i3;
00895
00896 public:
00898 typedef typename Operation_::value_type value_type;
00899
00900 private:
00901 value_type current;
00902
00903 public:
00905 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_) :
00906 op(o), i1(i1_), i2(i2_), i3(i3_)
00907 {
00908 if (!empty())
00909 current = op(*i1, *i2, *i3);
00910 }
00911
00913 const value_type & operator * () const
00914 {
00915 return current;
00916 }
00917
00918 const value_type * operator -> () const
00919 {
00920 return ¤t;
00921 }
00922
00924 transform & operator ++ ()
00925 {
00926 ++i1;
00927 ++i2;
00928 ++i3;
00929 if (!empty())
00930 current = op(*i1, *i2, *i3);
00931
00932 return *this;
00933 }
00934
00936 bool empty() const
00937 {
00938 return i1.empty() || i2.empty() || i3.empty();
00939 }
00940 };
00941
00942
00944
00946
00957 template <class Operation_,
00958 class Input1_,
00959 class Input2_,
00960 class Input3_,
00961 class Input4_
00962 >
00963 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
00964 {
00965 Operation_ & op;
00966 Input1_ & i1;
00967 Input2_ & i2;
00968 Input3_ & i3;
00969 Input4_ & i4;
00970
00971 public:
00973 typedef typename Operation_::value_type value_type;
00974
00975 private:
00976 value_type current;
00977
00978 public:
00980 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_) :
00981 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_)
00982 {
00983 if (!empty())
00984 current = op(*i1, *i2, *i3, *i4);
00985 }
00986
00988 const value_type & operator * () const
00989 {
00990 return current;
00991 }
00992
00993 const value_type * operator -> () const
00994 {
00995 return ¤t;
00996 }
00997
00999 transform & operator ++ ()
01000 {
01001 ++i1;
01002 ++i2;
01003 ++i3;
01004 ++i4;
01005 if (!empty())
01006 current = op(*i1, *i2, *i3, *i4);
01007
01008 return *this;
01009 }
01010
01012 bool empty() const
01013 {
01014 return i1.empty() || i2.empty() || i3.empty() || i4.empty();
01015 }
01016 };
01017
01018
01020
01022
01034 template <class Operation_,
01035 class Input1_,
01036 class Input2_,
01037 class Input3_,
01038 class Input4_,
01039 class Input5_
01040 >
01041 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01042 {
01043 Operation_ & op;
01044 Input1_ & i1;
01045 Input2_ & i2;
01046 Input3_ & i3;
01047 Input4_ & i4;
01048 Input5_ & i5;
01049
01050 public:
01052 typedef typename Operation_::value_type value_type;
01053
01054 private:
01055 value_type current;
01056
01057 public:
01059 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
01060 Input5_ & i5_) :
01061 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_)
01062 {
01063 if (!empty())
01064 current = op(*i1, *i2, *i3, *i4, *i5);
01065 }
01066
01068 const value_type & operator * () const
01069 {
01070 return current;
01071 }
01072
01073 const value_type * operator -> () const
01074 {
01075 return ¤t;
01076 }
01077
01079 transform & operator ++ ()
01080 {
01081 ++i1;
01082 ++i2;
01083 ++i3;
01084 ++i4;
01085 ++i5;
01086 if (!empty())
01087 current = op(*i1, *i2, *i3, *i4, *i5);
01088
01089 return *this;
01090 }
01091
01093 bool empty() const
01094 {
01095 return i1.empty() || i2.empty() || i3.empty() || i4.empty() || i5.empty();
01096 }
01097 };
01098
01099
01101
01103
01113 template <class Input1_,
01114 class Input2_,
01115 class Input3_ = Stopper,
01116 class Input4_ = Stopper,
01117 class Input5_ = Stopper,
01118 class Input6_ = Stopper
01119 >
01120 class make_tuple
01121 {
01122 Input1_ & i1;
01123 Input2_ & i2;
01124 Input3_ & i3;
01125 Input4_ & i4;
01126 Input5_ & i5;
01127 Input6_ & i6;
01128
01129 public:
01131 typedef typename stxxl::tuple<
01132 typename Input1_::value_type,
01133 typename Input2_::value_type,
01134 typename Input3_::value_type,
01135 typename Input4_::value_type,
01136 typename Input5_::value_type,
01137 typename Input6_::value_type
01138 > value_type;
01139
01140 private:
01141 value_type current;
01142
01143 public:
01145 make_tuple(
01146 Input1_ & i1_,
01147 Input2_ & i2_,
01148 Input3_ & i3_,
01149 Input4_ & i4_,
01150 Input5_ & i5_,
01151 Input6_ & i6_
01152 ) :
01153 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_),
01154 current(value_type(*i1, *i2, *i3, *i4, *i5, *i6)) { }
01155
01157 const value_type & operator * () const
01158 {
01159 return current;
01160 }
01161
01162 const value_type * operator -> () const
01163 {
01164 return ¤t;
01165 }
01166
01168 make_tuple & operator ++ ()
01169 {
01170 ++i1;
01171 ++i2;
01172 ++i3;
01173 ++i4;
01174 ++i5;
01175 ++i6;
01176
01177 if (!empty())
01178 current = value_type(*i1, *i2, *i3, *i4, *i5, *i6);
01179
01180 return *this;
01181 }
01182
01184 bool empty() const
01185 {
01186 return i1.empty() || i2.empty() || i3.empty() ||
01187 i4.empty() || i5.empty() || i6.empty();
01188 }
01189 };
01190
01191
01198 template <class Input1_,
01199 class Input2_
01200 >
01201 class make_tuple<Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
01202 {
01203 Input1_ & i1;
01204 Input2_ & i2;
01205
01206 public:
01208 typedef typename stxxl::tuple<
01209 typename Input1_::value_type,
01210 typename Input2_::value_type
01211 > value_type;
01212
01213 private:
01214 value_type current;
01215
01216 public:
01218 make_tuple(
01219 Input1_ & i1_,
01220 Input2_ & i2_
01221 ) :
01222 i1(i1_), i2(i2_)
01223 {
01224 if (!empty())
01225 {
01226 current = value_type(*i1, *i2);
01227 }
01228 }
01229
01231 const value_type & operator * () const
01232 {
01233 return current;
01234 }
01235
01236 const value_type * operator -> () const
01237 {
01238 return ¤t;
01239 }
01240
01242 make_tuple & operator ++ ()
01243 {
01244 ++i1;
01245 ++i2;
01246
01247 if (!empty())
01248 current = value_type(*i1, *i2);
01249
01250 return *this;
01251 }
01252
01254 bool empty() const
01255 {
01256 return i1.empty() || i2.empty();
01257 }
01258 };
01259
01267 template <class Input1_,
01268 class Input2_,
01269 class Input3_
01270 >
01271 class make_tuple<Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
01272 {
01273 Input1_ & i1;
01274 Input2_ & i2;
01275 Input3_ & i3;
01276
01277 public:
01279 typedef typename stxxl::tuple<
01280 typename Input1_::value_type,
01281 typename Input2_::value_type,
01282 typename Input3_::value_type
01283 > value_type;
01284
01285 private:
01286 value_type current;
01287
01288 public:
01290 make_tuple(
01291 Input1_ & i1_,
01292 Input2_ & i2_,
01293 Input3_ & i3_
01294 ) :
01295 i1(i1_), i2(i2_), i3(i3_),
01296 current(value_type(*i1, *i2, *i3)) { }
01297
01299 const value_type & operator * () const
01300 {
01301 return current;
01302 }
01303
01304 const value_type * operator -> () const
01305 {
01306 return ¤t;
01307 }
01308
01310 make_tuple & operator ++ ()
01311 {
01312 ++i1;
01313 ++i2;
01314 ++i3;
01315
01316 if (!empty())
01317 current = value_type(*i1, *i2, *i3);
01318
01319 return *this;
01320 }
01321
01323 bool empty() const
01324 {
01325 return i1.empty() || i2.empty() || i3.empty();
01326 }
01327 };
01328
01337 template <class Input1_,
01338 class Input2_,
01339 class Input3_,
01340 class Input4_
01341 >
01342 class make_tuple<Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
01343 {
01344 Input1_ & i1;
01345 Input2_ & i2;
01346 Input3_ & i3;
01347 Input4_ & i4;
01348
01349 public:
01351 typedef typename stxxl::tuple<
01352 typename Input1_::value_type,
01353 typename Input2_::value_type,
01354 typename Input3_::value_type,
01355 typename Input4_::value_type
01356 > value_type;
01357
01358 private:
01359 value_type current;
01360
01361 public:
01363 make_tuple(
01364 Input1_ & i1_,
01365 Input2_ & i2_,
01366 Input3_ & i3_,
01367 Input4_ & i4_
01368 ) :
01369 i1(i1_), i2(i2_), i3(i3_), i4(i4_),
01370 current(value_type(*i1, *i2, *i3, *i4)) { }
01371
01373 const value_type & operator * () const
01374 {
01375 return current;
01376 }
01377
01378 const value_type * operator -> () const
01379 {
01380 return ¤t;
01381 }
01382
01384 make_tuple & operator ++ ()
01385 {
01386 ++i1;
01387 ++i2;
01388 ++i3;
01389 ++i4;
01390
01391 if (!empty())
01392 current = value_type(*i1, *i2, *i3, *i4);
01393
01394 return *this;
01395 }
01396
01398 bool empty() const
01399 {
01400 return i1.empty() || i2.empty() || i3.empty() ||
01401 i4.empty();
01402 }
01403 };
01404
01414 template <
01415 class Input1_,
01416 class Input2_,
01417 class Input3_,
01418 class Input4_,
01419 class Input5_
01420 >
01421 class make_tuple<Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01422 {
01423 Input1_ & i1;
01424 Input2_ & i2;
01425 Input3_ & i3;
01426 Input4_ & i4;
01427 Input5_ & i5;
01428
01429 public:
01431 typedef typename stxxl::tuple<
01432 typename Input1_::value_type,
01433 typename Input2_::value_type,
01434 typename Input3_::value_type,
01435 typename Input4_::value_type,
01436 typename Input5_::value_type
01437 > value_type;
01438
01439 private:
01440 value_type current;
01441
01442 public:
01444 make_tuple(
01445 Input1_ & i1_,
01446 Input2_ & i2_,
01447 Input3_ & i3_,
01448 Input4_ & i4_,
01449 Input5_ & i5_
01450 ) :
01451 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_),
01452 current(value_type(*i1, *i2, *i3, *i4, *i5)) { }
01453
01455 const value_type & operator * () const
01456 {
01457 return current;
01458 }
01459
01460 const value_type * operator -> () const
01461 {
01462 return ¤t;
01463 }
01464
01466 make_tuple & operator ++ ()
01467 {
01468 ++i1;
01469 ++i2;
01470 ++i3;
01471 ++i4;
01472 ++i5;
01473
01474 if (!empty())
01475 current = value_type(*i1, *i2, *i3, *i4, *i5);
01476
01477 return *this;
01478 }
01479
01481 bool empty() const
01482 {
01483 return i1.empty() || i2.empty() || i3.empty() ||
01484 i4.empty() || i5.empty();
01485 }
01486 };
01487
01488
01490 }
01491
01492 __STXXL_END_NAMESPACE
01493
01494
01495 #include <stxxl/bits/stream/choose.h>
01496 #include <stxxl/bits/stream/unique.h>
01497
01498
01499 #endif // !STXXL_STREAM_HEADER
01500