00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef STXXL_STREAM_HEADER
00016 #define STXXL_STREAM_HEADER
00017
00018 #include <stxxl/bits/namespace.h>
00019 #include <stxxl/bits/mng/buf_istream.h>
00020 #include <stxxl/bits/mng/buf_ostream.h>
00021 #include <stxxl/bits/common/tuple.h>
00022 #include <stxxl/vector>
00023 #include <stxxl/bits/compat_unique_ptr.h>
00024
00025
00026 #ifndef STXXL_VERBOSE_MATERIALIZE
00027 #define STXXL_VERBOSE_MATERIALIZE STXXL_VERBOSE3
00028 #endif
00029
00030
00031 __STXXL_BEGIN_NAMESPACE
00032
00034 namespace stream
00035 {
00060
00061
00063
00065
00069 template <class InputIterator_>
00070 class iterator2stream
00071 {
00072 InputIterator_ current_, end_;
00073
00074 public:
00076 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00077
00078 iterator2stream(InputIterator_ begin, InputIterator_ end) :
00079 current_(begin), end_(end) { }
00080
00081 iterator2stream(const iterator2stream & a) : current_(a.current_), end_(a.end_) { }
00082
00084 const value_type & operator * () const
00085 {
00086 return *current_;
00087 }
00088
00089 const value_type * operator -> () const
00090 {
00091 return &(*current_);
00092 }
00093
00095 iterator2stream & operator ++ ()
00096 {
00097 assert(end_ != current_);
00098 ++current_;
00099 return *this;
00100 }
00101
00103 bool empty() const
00104 {
00105 return (current_ == end_);
00106 }
00107 };
00108
00109
00114 template <class InputIterator_>
00115 iterator2stream<InputIterator_> streamify(InputIterator_ begin, InputIterator_ end)
00116 {
00117 return iterator2stream<InputIterator_>(begin, end);
00118 }
00119
00121 template <class InputIterator_>
00122 struct streamify_traits
00123 {
00125 typedef iterator2stream<InputIterator_> stream_type;
00126 };
00127
00132 template <class InputIterator_>
00133 class vector_iterator2stream
00134 {
00135 InputIterator_ current_, end_;
00136 typedef buf_istream<typename InputIterator_::block_type,
00137 typename InputIterator_::bids_container_iterator> buf_istream_type;
00138
00139 typedef typename stxxl::compat_unique_ptr<buf_istream_type>::result buf_istream_unique_ptr_type;
00140 mutable buf_istream_unique_ptr_type in;
00141
00142 void delete_stream()
00143 {
00144 in.reset();
00145 }
00146
00147 public:
00148 typedef vector_iterator2stream<InputIterator_> Self_;
00149
00151 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00152
00153 vector_iterator2stream(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0) :
00154 current_(begin), end_(end), in(static_cast<buf_istream_type *>(NULL))
00155 {
00156 if (empty())
00157 return;
00158
00159 begin.flush();
00160 typename InputIterator_::bids_container_iterator end_iter = end.bid() + ((end.block_offset()) ? 1 : 0);
00161
00162 if (end_iter - begin.bid() > 0)
00163 {
00164 in.reset(new buf_istream_type(begin.bid(), end_iter, nbuffers ? nbuffers :
00165 (2 * config::get_instance()->disks_number())));
00166
00167 InputIterator_ cur = begin - begin.block_offset();
00168
00169
00170 for ( ; cur != begin; ++cur)
00171 ++(*in);
00172 }
00173 }
00174
00175 vector_iterator2stream(const Self_ & a) :
00176 current_(a.current_), end_(a.end_), in(a.in.release()) { }
00177
00179 const value_type & operator * () const
00180 {
00181 return **in;
00182 }
00183
00184 const value_type * operator -> () const
00185 {
00186 return &(**in);
00187 }
00188
00190 Self_ & operator ++ ()
00191 {
00192 assert(end_ != current_);
00193 ++current_;
00194 ++(*in);
00195 if (UNLIKELY(empty()))
00196 delete_stream();
00197
00198 return *this;
00199 }
00200
00202 bool empty() const
00203 {
00204 return (current_ == end_);
00205 }
00206 virtual ~vector_iterator2stream()
00207 {
00208 delete_stream();
00209 }
00210 };
00211
00219
00220 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00221 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00222 vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00223 streamify(
00224 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00225 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00226 unsigned_type nbuffers = 0)
00227 {
00228 STXXL_VERBOSE1("streamify for vector_iterator range is called");
00229 return vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00230 (begin, end, nbuffers);
00231 }
00232
00233 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00234 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00235 struct streamify_traits<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00236 {
00237 typedef vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00238 };
00239
00247
00248 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00249 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00250 vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00251 streamify(
00252 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00253 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00254 unsigned_type nbuffers = 0)
00255 {
00256 STXXL_VERBOSE1("streamify for const_vector_iterator range is called");
00257 return vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00258 (begin, end, nbuffers);
00259 }
00260
00261 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00262 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00263 struct streamify_traits<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00264 {
00265 typedef vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00266 };
00267
00268
00275 template <class InputIterator_>
00276 class vector_iterator2stream_sr
00277 {
00278 vector_iterator2stream<InputIterator_> * vec_it_stream;
00279 iterator2stream<InputIterator_> * it_stream;
00280
00281 typedef typename InputIterator_::block_type block_type;
00282
00283 public:
00284 typedef vector_iterator2stream_sr<InputIterator_> Self_;
00285
00287 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00288
00289 vector_iterator2stream_sr(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0)
00290 {
00291 if (end - begin < block_type::size)
00292 {
00293 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing iterator2stream<InputIterator_>");
00294 it_stream = new iterator2stream<InputIterator_>(begin, end);
00295 vec_it_stream = NULL;
00296 }
00297 else
00298 {
00299 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing vector_iterator2stream<InputIterator_>");
00300 it_stream = NULL;
00301 vec_it_stream = new vector_iterator2stream<InputIterator_>(begin, end, nbuffers);
00302 }
00303 }
00304
00305 vector_iterator2stream_sr(const Self_ & a) : vec_it_stream(a.vec_it_stream), it_stream(a.it_stream) { }
00306
00308 const value_type & operator * () const
00309 {
00310 if (it_stream)
00311 return **it_stream;
00312
00313 return **vec_it_stream;
00314 }
00315
00316 const value_type * operator -> () const
00317 {
00318 if (it_stream)
00319 return &(**it_stream);
00320
00321 return &(**vec_it_stream);
00322 }
00323
00325 Self_ & operator ++ ()
00326 {
00327 if (it_stream)
00328 ++(*it_stream);
00329
00330 else
00331 ++(*vec_it_stream);
00332
00333
00334 return *this;
00335 }
00336
00338 bool empty() const
00339 {
00340 if (it_stream)
00341 return it_stream->empty();
00342
00343 return vec_it_stream->empty();
00344 }
00345 virtual ~vector_iterator2stream_sr()
00346 {
00347 if (it_stream)
00348 delete it_stream;
00349
00350 else
00351 delete vec_it_stream;
00352 }
00353 };
00354
00356 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00357 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00358 vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00359 streamify_sr(
00360 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00361 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00362 unsigned_type nbuffers = 0)
00363 {
00364 STXXL_VERBOSE1("streamify_sr for vector_iterator range is called");
00365 return vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00366 (begin, end, nbuffers);
00367 }
00368
00370 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00371 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00372 vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00373 streamify_sr(
00374 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00375 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00376 unsigned_type nbuffers = 0)
00377 {
00378 STXXL_VERBOSE1("streamify_sr for const_vector_iterator range is called");
00379 return vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00380 (begin, end, nbuffers);
00381 }
00382
00383
00385
00387
00394 template <class OutputIterator_, class StreamAlgorithm_>
00395 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ out)
00396 {
00397 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00398 while (!in.empty())
00399 {
00400 *out = *in;
00401 ++out;
00402 ++in;
00403 }
00404 return out;
00405 }
00406
00407
00417 template <class OutputIterator_, class StreamAlgorithm_>
00418 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ outbegin, OutputIterator_ outend)
00419 {
00420 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00421 while ((!in.empty()) && outend != outbegin)
00422 {
00423 *outbegin = *in;
00424 ++outbegin;
00425 ++in;
00426 }
00427 return outbegin;
00428 }
00429
00430
00442 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00443 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00444 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00445 materialize(StreamAlgorithm_ & in,
00446 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outbegin,
00447 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outend,
00448 unsigned_type nbuffers = 0)
00449 {
00450 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00451 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00452 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00453 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00454
00455
00456 while (outbegin.block_offset())
00457
00458 {
00459 if (in.empty() || outbegin == outend)
00460 return outbegin;
00461
00462 *outbegin = *in;
00463 ++outbegin;
00464 ++in;
00465 }
00466
00467 if (nbuffers == 0)
00468 nbuffers = 2 * config::get_instance()->disks_number();
00469
00470 outbegin.flush();
00471
00472
00473 buf_ostream_type outstream(outbegin.bid(), nbuffers);
00474
00475 assert(outbegin.block_offset() == 0);
00476
00477
00478
00479 ConstExtIterator prev_block = outbegin;
00480
00481 while (!in.empty() && outend != outbegin)
00482 {
00483 if (outbegin.block_offset() == 0) {
00484 if (prev_block != outbegin) {
00485 prev_block.block_externally_updated();
00486 prev_block = outbegin;
00487 }
00488 }
00489
00490 *outstream = *in;
00491 ++outbegin;
00492 ++outstream;
00493 ++in;
00494 }
00495
00496 ConstExtIterator const_out = outbegin;
00497
00498 while (const_out.block_offset())
00499 {
00500 *outstream = *const_out;
00501 ++const_out;
00502 ++outstream;
00503 }
00504
00505 if (prev_block != outbegin)
00506 prev_block.block_externally_updated();
00507
00508 outbegin.flush();
00509
00510 return outbegin;
00511 }
00512
00513
00522 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00523 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00524 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00525 materialize(StreamAlgorithm_ & in,
00526 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> out,
00527 unsigned_type nbuffers = 0)
00528 {
00529 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00530 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00531 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00532 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00533
00534
00535
00536
00537
00538
00539 while (out.block_offset())
00540
00541 {
00542 if (in.empty())
00543 return out;
00544
00545 *out = *in;
00546 ++out;
00547 ++in;
00548 }
00549
00550 if (nbuffers == 0)
00551 nbuffers = 2 * config::get_instance()->disks_number();
00552
00553
00554 out.flush();
00555
00556
00557 buf_ostream_type outstream(out.bid(), nbuffers);
00558
00559 assert(out.block_offset() == 0);
00560
00561
00562
00563 ConstExtIterator prev_block = out;
00564
00565 while (!in.empty())
00566 {
00567 if (out.block_offset() == 0) {
00568 if (prev_block != out) {
00569 prev_block.block_externally_updated();
00570 prev_block = out;
00571 }
00572 }
00573
00574
00575 *outstream = *in;
00576 ++out;
00577 ++outstream;
00578 ++in;
00579 }
00580
00581 ConstExtIterator const_out = out;
00582
00583 while (const_out.block_offset())
00584 {
00585 *outstream = *const_out;
00586 ++const_out;
00587 ++outstream;
00588 }
00589
00590 if (prev_block != out)
00591 prev_block.block_externally_updated();
00592
00593 out.flush();
00594
00595 return out;
00596 }
00597
00598
00603 template <class StreamAlgorithm_>
00604 void discard(StreamAlgorithm_ & in)
00605 {
00606 while (!in.empty())
00607 {
00608 *in;
00609 ++in;
00610 }
00611 }
00612
00613
00615
00617
00621 template <class Generator_, typename T = typename Generator_::value_type>
00622 class generator2stream
00623 {
00624 public:
00626 typedef T value_type;
00627
00628 private:
00629 Generator_ gen_;
00630 value_type current_;
00631
00632 public:
00633 generator2stream(Generator_ g) :
00634 gen_(g), current_(gen_()) { }
00635
00636 generator2stream(const generator2stream & a) : gen_(a.gen_), current_(a.current_) { }
00637
00639 const value_type & operator * () const
00640 {
00641 return current_;
00642 }
00643
00644 const value_type * operator -> () const
00645 {
00646 return ¤t_;
00647 }
00648
00650 generator2stream & operator ++ ()
00651 {
00652 current_ = gen_();
00653 return *this;
00654 }
00655
00657 bool empty() const
00658 {
00659 return false;
00660 }
00661 };
00662
00666 template <class Generator_>
00667 generator2stream<Generator_> streamify(Generator_ gen_)
00668 {
00669 return generator2stream<Generator_>(gen_);
00670 }
00671
00672
00674
00676
00677 struct Stopper { };
00678
00689 template <class Operation_,
00690 class Input1_,
00691 class Input2_ = Stopper,
00692 class Input3_ = Stopper,
00693 class Input4_ = Stopper,
00694 class Input5_ = Stopper,
00695 class Input6_ = Stopper
00696 >
00697 class transform
00698 {
00699 Operation_ & op;
00700 Input1_ & i1;
00701 Input2_ & i2;
00702 Input3_ & i3;
00703 Input4_ & i4;
00704 Input5_ & i5;
00705 Input6_ & i6;
00706
00707 public:
00709 typedef typename Operation_::value_type value_type;
00710
00711 private:
00712 value_type current;
00713
00714 public:
00716 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
00717 Input5_ & i5_, Input5_ & i6_) :
00718 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_)
00719 {
00720 if (!empty())
00721 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00722 }
00723
00725 const value_type & operator * () const
00726 {
00727 return current;
00728 }
00729
00730 const value_type * operator -> () const
00731 {
00732 return ¤t;
00733 }
00734
00736 transform & operator ++ ()
00737 {
00738 ++i1;
00739 ++i2;
00740 ++i3;
00741 ++i4;
00742 ++i5;
00743 ++i6;
00744 if (!empty())
00745 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00746
00747 return *this;
00748 }
00749
00751 bool empty() const
00752 {
00753 return i1.empty() || i2.empty() || i3.empty() ||
00754 i4.empty() || i5.empty() || i6.empty();
00755 }
00756 };
00757
00758
00759
00761
00763
00770 template <class Operation_,
00771 class Input1_
00772 >
00773 class transform<Operation_, Input1_, Stopper, Stopper, Stopper, Stopper, Stopper>
00774 {
00775 Operation_ & op;
00776 Input1_ & i1;
00777
00778 public:
00780 typedef typename Operation_::value_type value_type;
00781
00782 private:
00783 value_type current;
00784
00785 public:
00787 transform(Operation_ & o, Input1_ & i1_) : op(o), i1(i1_)
00788 {
00789 if (!empty())
00790 current = op(*i1);
00791 }
00792
00794 const value_type & operator * () const
00795 {
00796 return current;
00797 }
00798
00799 const value_type * operator -> () const
00800 {
00801 return ¤t;
00802 }
00803
00805 transform & operator ++ ()
00806 {
00807 ++i1;
00808 if (!empty())
00809 current = op(*i1);
00810
00811 return *this;
00812 }
00813
00815 bool empty() const
00816 {
00817 return i1.empty();
00818 }
00819 };
00820
00821
00823
00825
00833 template <class Operation_,
00834 class Input1_,
00835 class Input2_
00836 >
00837 class transform<Operation_, Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
00838 {
00839 Operation_ & op;
00840 Input1_ & i1;
00841 Input2_ & i2;
00842
00843 public:
00845 typedef typename Operation_::value_type value_type;
00846
00847 private:
00848 value_type current;
00849
00850 public:
00852 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_) : op(o), i1(i1_), i2(i2_)
00853 {
00854 if (!empty())
00855 current = op(*i1, *i2);
00856 }
00857
00859 const value_type & operator * () const
00860 {
00861 return current;
00862 }
00863
00864 const value_type * operator -> () const
00865 {
00866 return ¤t;
00867 }
00868
00870 transform & operator ++ ()
00871 {
00872 ++i1;
00873 ++i2;
00874 if (!empty())
00875 current = op(*i1, *i2);
00876
00877 return *this;
00878 }
00879
00881 bool empty() const
00882 {
00883 return i1.empty() || i2.empty();
00884 }
00885 };
00886
00887
00889
00891
00900 template <class Operation_,
00901 class Input1_,
00902 class Input2_,
00903 class Input3_
00904 >
00905 class transform<Operation_, Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
00906 {
00907 Operation_ & op;
00908 Input1_ & i1;
00909 Input2_ & i2;
00910 Input3_ & i3;
00911
00912 public:
00914 typedef typename Operation_::value_type value_type;
00915
00916 private:
00917 value_type current;
00918
00919 public:
00921 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_) :
00922 op(o), i1(i1_), i2(i2_), i3(i3_)
00923 {
00924 if (!empty())
00925 current = op(*i1, *i2, *i3);
00926 }
00927
00929 const value_type & operator * () const
00930 {
00931 return current;
00932 }
00933
00934 const value_type * operator -> () const
00935 {
00936 return ¤t;
00937 }
00938
00940 transform & operator ++ ()
00941 {
00942 ++i1;
00943 ++i2;
00944 ++i3;
00945 if (!empty())
00946 current = op(*i1, *i2, *i3);
00947
00948 return *this;
00949 }
00950
00952 bool empty() const
00953 {
00954 return i1.empty() || i2.empty() || i3.empty();
00955 }
00956 };
00957
00958
00960
00962
00972 template <class Operation_,
00973 class Input1_,
00974 class Input2_,
00975 class Input3_,
00976 class Input4_
00977 >
00978 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
00979 {
00980 Operation_ & op;
00981 Input1_ & i1;
00982 Input2_ & i2;
00983 Input3_ & i3;
00984 Input4_ & i4;
00985
00986 public:
00988 typedef typename Operation_::value_type value_type;
00989
00990 private:
00991 value_type current;
00992
00993 public:
00995 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_) :
00996 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_)
00997 {
00998 if (!empty())
00999 current = op(*i1, *i2, *i3, *i4);
01000 }
01001
01003 const value_type & operator * () const
01004 {
01005 return current;
01006 }
01007
01008 const value_type * operator -> () const
01009 {
01010 return ¤t;
01011 }
01012
01014 transform & operator ++ ()
01015 {
01016 ++i1;
01017 ++i2;
01018 ++i3;
01019 ++i4;
01020 if (!empty())
01021 current = op(*i1, *i2, *i3, *i4);
01022
01023 return *this;
01024 }
01025
01027 bool empty() const
01028 {
01029 return i1.empty() || i2.empty() || i3.empty() || i4.empty();
01030 }
01031 };
01032
01033
01035
01037
01048 template <class Operation_,
01049 class Input1_,
01050 class Input2_,
01051 class Input3_,
01052 class Input4_,
01053 class Input5_
01054 >
01055 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01056 {
01057 Operation_ & op;
01058 Input1_ & i1;
01059 Input2_ & i2;
01060 Input3_ & i3;
01061 Input4_ & i4;
01062 Input5_ & i5;
01063
01064 public:
01066 typedef typename Operation_::value_type value_type;
01067
01068 private:
01069 value_type current;
01070
01071 public:
01073 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
01074 Input5_ & i5_) :
01075 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_)
01076 {
01077 if (!empty())
01078 current = op(*i1, *i2, *i3, *i4, *i5);
01079 }
01080
01082 const value_type & operator * () const
01083 {
01084 return current;
01085 }
01086
01087 const value_type * operator -> () const
01088 {
01089 return ¤t;
01090 }
01091
01093 transform & operator ++ ()
01094 {
01095 ++i1;
01096 ++i2;
01097 ++i3;
01098 ++i4;
01099 ++i5;
01100 if (!empty())
01101 current = op(*i1, *i2, *i3, *i4, *i5);
01102
01103 return *this;
01104 }
01105
01107 bool empty() const
01108 {
01109 return i1.empty() || i2.empty() || i3.empty() || i4.empty() || i5.empty();
01110 }
01111 };
01112
01113
01115
01117
01126 template <class Input1_,
01127 class Input2_,
01128 class Input3_ = Stopper,
01129 class Input4_ = Stopper,
01130 class Input5_ = Stopper,
01131 class Input6_ = Stopper
01132 >
01133 class make_tuple
01134 {
01135 Input1_ & i1;
01136 Input2_ & i2;
01137 Input3_ & i3;
01138 Input4_ & i4;
01139 Input5_ & i5;
01140 Input6_ & i6;
01141
01142 public:
01144 typedef typename stxxl::tuple<
01145 typename Input1_::value_type,
01146 typename Input2_::value_type,
01147 typename Input3_::value_type,
01148 typename Input4_::value_type,
01149 typename Input5_::value_type,
01150 typename Input6_::value_type
01151 > value_type;
01152
01153 private:
01154 value_type current;
01155
01156 public:
01158 make_tuple(
01159 Input1_ & i1_,
01160 Input2_ & i2_,
01161 Input3_ & i3_,
01162 Input4_ & i4_,
01163 Input5_ & i5_,
01164 Input6_ & i6_
01165 ) :
01166 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_)
01167 {
01168 if (!empty())
01169 current = value_type(*i1, *i2, *i3, *i4, *i5, *i6);
01170 }
01171
01173 const value_type & operator * () const
01174 {
01175 return current;
01176 }
01177
01178 const value_type * operator -> () const
01179 {
01180 return ¤t;
01181 }
01182
01184 make_tuple & operator ++ ()
01185 {
01186 ++i1;
01187 ++i2;
01188 ++i3;
01189 ++i4;
01190 ++i5;
01191 ++i6;
01192
01193 if (!empty())
01194 current = value_type(*i1, *i2, *i3, *i4, *i5, *i6);
01195
01196 return *this;
01197 }
01198
01200 bool empty() const
01201 {
01202 return i1.empty() || i2.empty() || i3.empty() ||
01203 i4.empty() || i5.empty() || i6.empty();
01204 }
01205 };
01206
01207
01213 template <class Input1_,
01214 class Input2_
01215 >
01216 class make_tuple<Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
01217 {
01218 Input1_ & i1;
01219 Input2_ & i2;
01220
01221 public:
01223 typedef typename stxxl::tuple<
01224 typename Input1_::value_type,
01225 typename Input2_::value_type
01226 > value_type;
01227
01228 private:
01229 value_type current;
01230
01231 public:
01233 make_tuple(
01234 Input1_ & i1_,
01235 Input2_ & i2_
01236 ) :
01237 i1(i1_), i2(i2_)
01238 {
01239 if (!empty())
01240 {
01241 current = value_type(*i1, *i2);
01242 }
01243 }
01244
01246 const value_type & operator * () const
01247 {
01248 return current;
01249 }
01250
01251 const value_type * operator -> () const
01252 {
01253 return ¤t;
01254 }
01255
01257 make_tuple & operator ++ ()
01258 {
01259 ++i1;
01260 ++i2;
01261
01262 if (!empty())
01263 current = value_type(*i1, *i2);
01264
01265 return *this;
01266 }
01267
01269 bool empty() const
01270 {
01271 return i1.empty() || i2.empty();
01272 }
01273 };
01274
01281 template <class Input1_,
01282 class Input2_,
01283 class Input3_
01284 >
01285 class make_tuple<Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
01286 {
01287 Input1_ & i1;
01288 Input2_ & i2;
01289 Input3_ & i3;
01290
01291 public:
01293 typedef typename stxxl::tuple<
01294 typename Input1_::value_type,
01295 typename Input2_::value_type,
01296 typename Input3_::value_type
01297 > value_type;
01298
01299 private:
01300 value_type current;
01301
01302 public:
01304 make_tuple(
01305 Input1_ & i1_,
01306 Input2_ & i2_,
01307 Input3_ & i3_
01308 ) :
01309 i1(i1_), i2(i2_), i3(i3_)
01310 {
01311 if (!empty())
01312 current = value_type(*i1, *i2, *i3);
01313 }
01314
01316 const value_type & operator * () const
01317 {
01318 return current;
01319 }
01320
01321 const value_type * operator -> () const
01322 {
01323 return ¤t;
01324 }
01325
01327 make_tuple & operator ++ ()
01328 {
01329 ++i1;
01330 ++i2;
01331 ++i3;
01332
01333 if (!empty())
01334 current = value_type(*i1, *i2, *i3);
01335
01336 return *this;
01337 }
01338
01340 bool empty() const
01341 {
01342 return i1.empty() || i2.empty() || i3.empty();
01343 }
01344 };
01345
01353 template <class Input1_,
01354 class Input2_,
01355 class Input3_,
01356 class Input4_
01357 >
01358 class make_tuple<Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
01359 {
01360 Input1_ & i1;
01361 Input2_ & i2;
01362 Input3_ & i3;
01363 Input4_ & i4;
01364
01365 public:
01367 typedef typename stxxl::tuple<
01368 typename Input1_::value_type,
01369 typename Input2_::value_type,
01370 typename Input3_::value_type,
01371 typename Input4_::value_type
01372 > value_type;
01373
01374 private:
01375 value_type current;
01376
01377 public:
01379 make_tuple(
01380 Input1_ & i1_,
01381 Input2_ & i2_,
01382 Input3_ & i3_,
01383 Input4_ & i4_
01384 ) :
01385 i1(i1_), i2(i2_), i3(i3_), i4(i4_)
01386 {
01387 if (!empty())
01388 current = value_type(*i1, *i2, *i3, *i4);
01389 }
01390
01392 const value_type & operator * () const
01393 {
01394 return current;
01395 }
01396
01397 const value_type * operator -> () const
01398 {
01399 return ¤t;
01400 }
01401
01403 make_tuple & operator ++ ()
01404 {
01405 ++i1;
01406 ++i2;
01407 ++i3;
01408 ++i4;
01409
01410 if (!empty())
01411 current = value_type(*i1, *i2, *i3, *i4);
01412
01413 return *this;
01414 }
01415
01417 bool empty() const
01418 {
01419 return i1.empty() || i2.empty() || i3.empty() ||
01420 i4.empty();
01421 }
01422 };
01423
01432 template <
01433 class Input1_,
01434 class Input2_,
01435 class Input3_,
01436 class Input4_,
01437 class Input5_
01438 >
01439 class make_tuple<Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01440 {
01441 Input1_ & i1;
01442 Input2_ & i2;
01443 Input3_ & i3;
01444 Input4_ & i4;
01445 Input5_ & i5;
01446
01447 public:
01449 typedef typename stxxl::tuple<
01450 typename Input1_::value_type,
01451 typename Input2_::value_type,
01452 typename Input3_::value_type,
01453 typename Input4_::value_type,
01454 typename Input5_::value_type
01455 > value_type;
01456
01457 private:
01458 value_type current;
01459
01460 public:
01462 make_tuple(
01463 Input1_ & i1_,
01464 Input2_ & i2_,
01465 Input3_ & i3_,
01466 Input4_ & i4_,
01467 Input5_ & i5_
01468 ) :
01469 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_)
01470 {
01471 if (!empty())
01472 current = value_type(*i1, *i2, *i3, *i4, *i5);
01473 }
01474
01476 const value_type & operator * () const
01477 {
01478 return current;
01479 }
01480
01481 const value_type * operator -> () const
01482 {
01483 return ¤t;
01484 }
01485
01487 make_tuple & operator ++ ()
01488 {
01489 ++i1;
01490 ++i2;
01491 ++i3;
01492 ++i4;
01493 ++i5;
01494
01495 if (!empty())
01496 current = value_type(*i1, *i2, *i3, *i4, *i5);
01497
01498 return *this;
01499 }
01500
01502 bool empty() const
01503 {
01504 return i1.empty() || i2.empty() || i3.empty() ||
01505 i4.empty() || i5.empty();
01506 }
01507 };
01508
01509
01511 }
01512
01513 __STXXL_END_NAMESPACE
01514
01515
01516 #include <stxxl/bits/stream/choose.h>
01517 #include <stxxl/bits/stream/unique.h>
01518
01519
01520 #endif // !STXXL_STREAM_HEADER
01521