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 begin.flush();
00157 typename InputIterator_::bids_container_iterator end_iter = end.bid() + ((end.block_offset()) ? 1 : 0);
00158
00159 if (end_iter - begin.bid() > 0)
00160 {
00161 in.reset(new buf_istream_type(begin.bid(), end_iter, nbuffers ? nbuffers :
00162 (2 * config::get_instance()->disks_number())));
00163
00164 InputIterator_ cur = begin - begin.block_offset();
00165
00166
00167 for ( ; cur != begin; ++cur)
00168 ++(*in);
00169 }
00170 }
00171
00172 vector_iterator2stream(const Self_ & a) :
00173 current_(a.current_), end_(a.end_), in(a.in.release()) { }
00174
00176 const value_type & operator * () const
00177 {
00178 return **in;
00179 }
00180
00181 const value_type * operator -> () const
00182 {
00183 return &(**in);
00184 }
00185
00187 Self_ & operator ++ ()
00188 {
00189 assert(end_ != current_);
00190 ++current_;
00191 ++(*in);
00192 if (empty())
00193 delete_stream();
00194
00195 return *this;
00196 }
00197
00199 bool empty() const
00200 {
00201 return (current_ == end_);
00202 }
00203 virtual ~vector_iterator2stream()
00204 {
00205 delete_stream();
00206 }
00207 };
00208
00216
00217 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00218 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00219 vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00220 streamify(
00221 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00222 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00223 unsigned_type nbuffers = 0)
00224 {
00225 STXXL_VERBOSE1("streamify for vector_iterator range is called");
00226 return vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00227 (begin, end, nbuffers);
00228 }
00229
00230 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00231 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00232 struct streamify_traits<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00233 {
00234 typedef vector_iterator2stream<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00235 };
00236
00244
00245 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00246 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00247 vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00248 streamify(
00249 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00250 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00251 unsigned_type nbuffers = 0)
00252 {
00253 STXXL_VERBOSE1("streamify for const_vector_iterator range is called");
00254 return vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00255 (begin, end, nbuffers);
00256 }
00257
00258 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00259 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00260 struct streamify_traits<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00261 {
00262 typedef vector_iterator2stream<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> > stream_type;
00263 };
00264
00265
00272 template <class InputIterator_>
00273 class vector_iterator2stream_sr
00274 {
00275 vector_iterator2stream<InputIterator_> * vec_it_stream;
00276 iterator2stream<InputIterator_> * it_stream;
00277
00278 typedef typename InputIterator_::block_type block_type;
00279
00280 public:
00281 typedef vector_iterator2stream_sr<InputIterator_> Self_;
00282
00284 typedef typename std::iterator_traits<InputIterator_>::value_type value_type;
00285
00286 vector_iterator2stream_sr(InputIterator_ begin, InputIterator_ end, unsigned_type nbuffers = 0)
00287 {
00288 if (end - begin < block_type::size)
00289 {
00290 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing iterator2stream<InputIterator_>");
00291 it_stream = new iterator2stream<InputIterator_>(begin, end);
00292 vec_it_stream = NULL;
00293 }
00294 else
00295 {
00296 STXXL_VERBOSE1("vector_iterator2stream_sr::vector_iterator2stream_sr: Choosing vector_iterator2stream<InputIterator_>");
00297 it_stream = NULL;
00298 vec_it_stream = new vector_iterator2stream<InputIterator_>(begin, end, nbuffers);
00299 }
00300 }
00301
00302 vector_iterator2stream_sr(const Self_ & a) : vec_it_stream(a.vec_it_stream), it_stream(a.it_stream) { }
00303
00305 const value_type & operator * () const
00306 {
00307 if (it_stream)
00308 return **it_stream;
00309
00310 return **vec_it_stream;
00311 }
00312
00313 const value_type * operator -> () const
00314 {
00315 if (it_stream)
00316 return &(**it_stream);
00317
00318 return &(**vec_it_stream);
00319 }
00320
00322 Self_ & operator ++ ()
00323 {
00324 if (it_stream)
00325 ++(*it_stream);
00326
00327 else
00328 ++(*vec_it_stream);
00329
00330
00331 return *this;
00332 }
00333
00335 bool empty() const
00336 {
00337 if (it_stream)
00338 return it_stream->empty();
00339
00340 return vec_it_stream->empty();
00341 }
00342 virtual ~vector_iterator2stream_sr()
00343 {
00344 if (it_stream)
00345 delete it_stream;
00346
00347 else
00348 delete vec_it_stream;
00349 }
00350 };
00351
00353 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00354 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00355 vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00356 streamify_sr(
00357 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00358 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00359 unsigned_type nbuffers = 0)
00360 {
00361 STXXL_VERBOSE1("streamify_sr for vector_iterator range is called");
00362 return vector_iterator2stream_sr<stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00363 (begin, end, nbuffers);
00364 }
00365
00367 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00368 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00369 vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00370 streamify_sr(
00371 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> begin,
00372 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> end,
00373 unsigned_type nbuffers = 0)
00374 {
00375 STXXL_VERBOSE1("streamify_sr for const_vector_iterator range is called");
00376 return vector_iterator2stream_sr<stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> >
00377 (begin, end, nbuffers);
00378 }
00379
00380
00382
00384
00391 template <class OutputIterator_, class StreamAlgorithm_>
00392 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ out)
00393 {
00394 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00395 while (!in.empty())
00396 {
00397 *out = *in;
00398 ++out;
00399 ++in;
00400 }
00401 return out;
00402 }
00403
00404
00414 template <class OutputIterator_, class StreamAlgorithm_>
00415 OutputIterator_ materialize(StreamAlgorithm_ & in, OutputIterator_ outbegin, OutputIterator_ outend)
00416 {
00417 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00418 while ((!in.empty()) && outend != outbegin)
00419 {
00420 *outbegin = *in;
00421 ++outbegin;
00422 ++in;
00423 }
00424 return outbegin;
00425 }
00426
00427
00439 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00440 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00441 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00442 materialize(StreamAlgorithm_ & in,
00443 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outbegin,
00444 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> outend,
00445 unsigned_type nbuffers = 0)
00446 {
00447 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00448 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00449 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00450 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00451
00452
00453 while (outbegin.block_offset())
00454
00455 {
00456 if (in.empty() || outbegin == outend)
00457 return outbegin;
00458
00459 *outbegin = *in;
00460 ++outbegin;
00461 ++in;
00462 }
00463
00464 if (nbuffers == 0)
00465 nbuffers = 2 * config::get_instance()->disks_number();
00466
00467 outbegin.flush();
00468
00469
00470 buf_ostream_type outstream(outbegin.bid(), nbuffers);
00471
00472 assert(outbegin.block_offset() == 0);
00473
00474
00475
00476 ConstExtIterator prev_block = outbegin;
00477
00478 while (!in.empty() && outend != outbegin)
00479 {
00480 if (outbegin.block_offset() == 0) {
00481 if (prev_block != outbegin) {
00482 prev_block.block_externally_updated();
00483 prev_block = outbegin;
00484 }
00485 }
00486
00487 *outstream = *in;
00488 ++outbegin;
00489 ++outstream;
00490 ++in;
00491 }
00492
00493 ConstExtIterator const_out = outbegin;
00494
00495 while (const_out.block_offset())
00496 {
00497 *outstream = *const_out;
00498 ++const_out;
00499 ++outstream;
00500 }
00501
00502 if (prev_block != outbegin)
00503 prev_block.block_externally_updated();
00504
00505 outbegin.flush();
00506
00507 return outbegin;
00508 }
00509
00510
00519 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00520 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, class StreamAlgorithm_>
00521 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>
00522 materialize(StreamAlgorithm_ & in,
00523 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> out,
00524 unsigned_type nbuffers = 0)
00525 {
00526 STXXL_VERBOSE_MATERIALIZE(STXXL_PRETTY_FUNCTION_NAME);
00527 typedef stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ExtIterator;
00528 typedef stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> ConstExtIterator;
00529 typedef buf_ostream<typename ExtIterator::block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type;
00530
00531
00532
00533
00534
00535
00536 while (out.block_offset())
00537
00538 {
00539 if (in.empty())
00540 return out;
00541
00542 *out = *in;
00543 ++out;
00544 ++in;
00545 }
00546
00547 if (nbuffers == 0)
00548 nbuffers = 2 * config::get_instance()->disks_number();
00549
00550
00551 out.flush();
00552
00553
00554 buf_ostream_type outstream(out.bid(), nbuffers);
00555
00556 assert(out.block_offset() == 0);
00557
00558
00559
00560 ConstExtIterator prev_block = out;
00561
00562 while (!in.empty())
00563 {
00564 if (out.block_offset() == 0) {
00565 if (prev_block != out) {
00566 prev_block.block_externally_updated();
00567 prev_block = out;
00568 }
00569 }
00570
00571
00572 *outstream = *in;
00573 ++out;
00574 ++outstream;
00575 ++in;
00576 }
00577
00578 ConstExtIterator const_out = out;
00579
00580 while (const_out.block_offset())
00581 {
00582 *outstream = *const_out;
00583 ++const_out;
00584 ++outstream;
00585 }
00586
00587 if (prev_block != out)
00588 prev_block.block_externally_updated();
00589
00590 out.flush();
00591
00592 return out;
00593 }
00594
00595
00600 template <class StreamAlgorithm_>
00601 void discard(StreamAlgorithm_ & in)
00602 {
00603 while (!in.empty())
00604 {
00605 *in;
00606 ++in;
00607 }
00608 }
00609
00610
00612
00614
00618 template <class Generator_, typename T = typename Generator_::value_type>
00619 class generator2stream
00620 {
00621 public:
00623 typedef T value_type;
00624
00625 private:
00626 Generator_ gen_;
00627 value_type current_;
00628
00629 public:
00630 generator2stream(Generator_ g) :
00631 gen_(g), current_(gen_()) { }
00632
00633 generator2stream(const generator2stream & a) : gen_(a.gen_), current_(a.current_) { }
00634
00636 const value_type & operator * () const
00637 {
00638 return current_;
00639 }
00640
00641 const value_type * operator -> () const
00642 {
00643 return ¤t_;
00644 }
00645
00647 generator2stream & operator ++ ()
00648 {
00649 current_ = gen_();
00650 return *this;
00651 }
00652
00654 bool empty() const
00655 {
00656 return false;
00657 }
00658 };
00659
00663 template <class Generator_>
00664 generator2stream<Generator_> streamify(Generator_ gen_)
00665 {
00666 return generator2stream<Generator_>(gen_);
00667 }
00668
00669
00671
00673
00674 struct Stopper { };
00675
00686 template <class Operation_,
00687 class Input1_,
00688 class Input2_ = Stopper,
00689 class Input3_ = Stopper,
00690 class Input4_ = Stopper,
00691 class Input5_ = Stopper,
00692 class Input6_ = Stopper
00693 >
00694 class transform
00695 {
00696 Operation_ & op;
00697 Input1_ & i1;
00698 Input2_ & i2;
00699 Input3_ & i3;
00700 Input4_ & i4;
00701 Input5_ & i5;
00702 Input6_ & i6;
00703
00704 public:
00706 typedef typename Operation_::value_type value_type;
00707
00708 private:
00709 value_type current;
00710
00711 public:
00713 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
00714 Input5_ & i5_, Input5_ & i6_) :
00715 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_)
00716 {
00717 if (!empty())
00718 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00719 }
00720
00722 const value_type & operator * () const
00723 {
00724 return current;
00725 }
00726
00727 const value_type * operator -> () const
00728 {
00729 return ¤t;
00730 }
00731
00733 transform & operator ++ ()
00734 {
00735 ++i1;
00736 ++i2;
00737 ++i3;
00738 ++i4;
00739 ++i5;
00740 ++i6;
00741 if (!empty())
00742 current = op(*i1, *i2, *i3, *i4, *i5, *i6);
00743
00744 return *this;
00745 }
00746
00748 bool empty() const
00749 {
00750 return i1.empty() || i2.empty() || i3.empty() ||
00751 i4.empty() || i5.empty() || i6.empty();
00752 }
00753 };
00754
00755
00756
00758
00760
00767 template <class Operation_,
00768 class Input1_
00769 >
00770 class transform<Operation_, Input1_, Stopper, Stopper, Stopper, Stopper, Stopper>
00771 {
00772 Operation_ & op;
00773 Input1_ & i1;
00774
00775 public:
00777 typedef typename Operation_::value_type value_type;
00778
00779 private:
00780 value_type current;
00781
00782 public:
00784 transform(Operation_ & o, Input1_ & i1_) : op(o), i1(i1_)
00785 {
00786 if (!empty())
00787 current = op(*i1);
00788 }
00789
00791 const value_type & operator * () const
00792 {
00793 return current;
00794 }
00795
00796 const value_type * operator -> () const
00797 {
00798 return ¤t;
00799 }
00800
00802 transform & operator ++ ()
00803 {
00804 ++i1;
00805 if (!empty())
00806 current = op(*i1);
00807
00808 return *this;
00809 }
00810
00812 bool empty() const
00813 {
00814 return i1.empty();
00815 }
00816 };
00817
00818
00820
00822
00830 template <class Operation_,
00831 class Input1_,
00832 class Input2_
00833 >
00834 class transform<Operation_, Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
00835 {
00836 Operation_ & op;
00837 Input1_ & i1;
00838 Input2_ & i2;
00839
00840 public:
00842 typedef typename Operation_::value_type value_type;
00843
00844 private:
00845 value_type current;
00846
00847 public:
00849 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_) : op(o), i1(i1_), i2(i2_)
00850 {
00851 if (!empty())
00852 current = op(*i1, *i2);
00853 }
00854
00856 const value_type & operator * () const
00857 {
00858 return current;
00859 }
00860
00861 const value_type * operator -> () const
00862 {
00863 return ¤t;
00864 }
00865
00867 transform & operator ++ ()
00868 {
00869 ++i1;
00870 ++i2;
00871 if (!empty())
00872 current = op(*i1, *i2);
00873
00874 return *this;
00875 }
00876
00878 bool empty() const
00879 {
00880 return i1.empty() || i2.empty();
00881 }
00882 };
00883
00884
00886
00888
00897 template <class Operation_,
00898 class Input1_,
00899 class Input2_,
00900 class Input3_
00901 >
00902 class transform<Operation_, Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
00903 {
00904 Operation_ & op;
00905 Input1_ & i1;
00906 Input2_ & i2;
00907 Input3_ & i3;
00908
00909 public:
00911 typedef typename Operation_::value_type value_type;
00912
00913 private:
00914 value_type current;
00915
00916 public:
00918 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_) :
00919 op(o), i1(i1_), i2(i2_), i3(i3_)
00920 {
00921 if (!empty())
00922 current = op(*i1, *i2, *i3);
00923 }
00924
00926 const value_type & operator * () const
00927 {
00928 return current;
00929 }
00930
00931 const value_type * operator -> () const
00932 {
00933 return ¤t;
00934 }
00935
00937 transform & operator ++ ()
00938 {
00939 ++i1;
00940 ++i2;
00941 ++i3;
00942 if (!empty())
00943 current = op(*i1, *i2, *i3);
00944
00945 return *this;
00946 }
00947
00949 bool empty() const
00950 {
00951 return i1.empty() || i2.empty() || i3.empty();
00952 }
00953 };
00954
00955
00957
00959
00969 template <class Operation_,
00970 class Input1_,
00971 class Input2_,
00972 class Input3_,
00973 class Input4_
00974 >
00975 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
00976 {
00977 Operation_ & op;
00978 Input1_ & i1;
00979 Input2_ & i2;
00980 Input3_ & i3;
00981 Input4_ & i4;
00982
00983 public:
00985 typedef typename Operation_::value_type value_type;
00986
00987 private:
00988 value_type current;
00989
00990 public:
00992 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_) :
00993 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_)
00994 {
00995 if (!empty())
00996 current = op(*i1, *i2, *i3, *i4);
00997 }
00998
01000 const value_type & operator * () const
01001 {
01002 return current;
01003 }
01004
01005 const value_type * operator -> () const
01006 {
01007 return ¤t;
01008 }
01009
01011 transform & operator ++ ()
01012 {
01013 ++i1;
01014 ++i2;
01015 ++i3;
01016 ++i4;
01017 if (!empty())
01018 current = op(*i1, *i2, *i3, *i4);
01019
01020 return *this;
01021 }
01022
01024 bool empty() const
01025 {
01026 return i1.empty() || i2.empty() || i3.empty() || i4.empty();
01027 }
01028 };
01029
01030
01032
01034
01045 template <class Operation_,
01046 class Input1_,
01047 class Input2_,
01048 class Input3_,
01049 class Input4_,
01050 class Input5_
01051 >
01052 class transform<Operation_, Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01053 {
01054 Operation_ & op;
01055 Input1_ & i1;
01056 Input2_ & i2;
01057 Input3_ & i3;
01058 Input4_ & i4;
01059 Input5_ & i5;
01060
01061 public:
01063 typedef typename Operation_::value_type value_type;
01064
01065 private:
01066 value_type current;
01067
01068 public:
01070 transform(Operation_ & o, Input1_ & i1_, Input2_ & i2_, Input3_ & i3_, Input4_ & i4_,
01071 Input5_ & i5_) :
01072 op(o), i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_)
01073 {
01074 if (!empty())
01075 current = op(*i1, *i2, *i3, *i4, *i5);
01076 }
01077
01079 const value_type & operator * () const
01080 {
01081 return current;
01082 }
01083
01084 const value_type * operator -> () const
01085 {
01086 return ¤t;
01087 }
01088
01090 transform & operator ++ ()
01091 {
01092 ++i1;
01093 ++i2;
01094 ++i3;
01095 ++i4;
01096 ++i5;
01097 if (!empty())
01098 current = op(*i1, *i2, *i3, *i4, *i5);
01099
01100 return *this;
01101 }
01102
01104 bool empty() const
01105 {
01106 return i1.empty() || i2.empty() || i3.empty() || i4.empty() || i5.empty();
01107 }
01108 };
01109
01110
01112
01114
01123 template <class Input1_,
01124 class Input2_,
01125 class Input3_ = Stopper,
01126 class Input4_ = Stopper,
01127 class Input5_ = Stopper,
01128 class Input6_ = Stopper
01129 >
01130 class make_tuple
01131 {
01132 Input1_ & i1;
01133 Input2_ & i2;
01134 Input3_ & i3;
01135 Input4_ & i4;
01136 Input5_ & i5;
01137 Input6_ & i6;
01138
01139 public:
01141 typedef typename stxxl::tuple<
01142 typename Input1_::value_type,
01143 typename Input2_::value_type,
01144 typename Input3_::value_type,
01145 typename Input4_::value_type,
01146 typename Input5_::value_type,
01147 typename Input6_::value_type
01148 > value_type;
01149
01150 private:
01151 value_type current;
01152
01153 public:
01155 make_tuple(
01156 Input1_ & i1_,
01157 Input2_ & i2_,
01158 Input3_ & i3_,
01159 Input4_ & i4_,
01160 Input5_ & i5_,
01161 Input6_ & i6_
01162 ) :
01163 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_), i6(i6_),
01164 current(value_type(*i1, *i2, *i3, *i4, *i5, *i6)) { }
01165
01167 const value_type & operator * () const
01168 {
01169 return current;
01170 }
01171
01172 const value_type * operator -> () const
01173 {
01174 return ¤t;
01175 }
01176
01178 make_tuple & operator ++ ()
01179 {
01180 ++i1;
01181 ++i2;
01182 ++i3;
01183 ++i4;
01184 ++i5;
01185 ++i6;
01186
01187 if (!empty())
01188 current = value_type(*i1, *i2, *i3, *i4, *i5, *i6);
01189
01190 return *this;
01191 }
01192
01194 bool empty() const
01195 {
01196 return i1.empty() || i2.empty() || i3.empty() ||
01197 i4.empty() || i5.empty() || i6.empty();
01198 }
01199 };
01200
01201
01207 template <class Input1_,
01208 class Input2_
01209 >
01210 class make_tuple<Input1_, Input2_, Stopper, Stopper, Stopper, Stopper>
01211 {
01212 Input1_ & i1;
01213 Input2_ & i2;
01214
01215 public:
01217 typedef typename stxxl::tuple<
01218 typename Input1_::value_type,
01219 typename Input2_::value_type
01220 > value_type;
01221
01222 private:
01223 value_type current;
01224
01225 public:
01227 make_tuple(
01228 Input1_ & i1_,
01229 Input2_ & i2_
01230 ) :
01231 i1(i1_), i2(i2_)
01232 {
01233 if (!empty())
01234 {
01235 current = value_type(*i1, *i2);
01236 }
01237 }
01238
01240 const value_type & operator * () const
01241 {
01242 return current;
01243 }
01244
01245 const value_type * operator -> () const
01246 {
01247 return ¤t;
01248 }
01249
01251 make_tuple & operator ++ ()
01252 {
01253 ++i1;
01254 ++i2;
01255
01256 if (!empty())
01257 current = value_type(*i1, *i2);
01258
01259 return *this;
01260 }
01261
01263 bool empty() const
01264 {
01265 return i1.empty() || i2.empty();
01266 }
01267 };
01268
01275 template <class Input1_,
01276 class Input2_,
01277 class Input3_
01278 >
01279 class make_tuple<Input1_, Input2_, Input3_, Stopper, Stopper, Stopper>
01280 {
01281 Input1_ & i1;
01282 Input2_ & i2;
01283 Input3_ & i3;
01284
01285 public:
01287 typedef typename stxxl::tuple<
01288 typename Input1_::value_type,
01289 typename Input2_::value_type,
01290 typename Input3_::value_type
01291 > value_type;
01292
01293 private:
01294 value_type current;
01295
01296 public:
01298 make_tuple(
01299 Input1_ & i1_,
01300 Input2_ & i2_,
01301 Input3_ & i3_
01302 ) :
01303 i1(i1_), i2(i2_), i3(i3_),
01304 current(value_type(*i1, *i2, *i3)) { }
01305
01307 const value_type & operator * () const
01308 {
01309 return current;
01310 }
01311
01312 const value_type * operator -> () const
01313 {
01314 return ¤t;
01315 }
01316
01318 make_tuple & operator ++ ()
01319 {
01320 ++i1;
01321 ++i2;
01322 ++i3;
01323
01324 if (!empty())
01325 current = value_type(*i1, *i2, *i3);
01326
01327 return *this;
01328 }
01329
01331 bool empty() const
01332 {
01333 return i1.empty() || i2.empty() || i3.empty();
01334 }
01335 };
01336
01344 template <class Input1_,
01345 class Input2_,
01346 class Input3_,
01347 class Input4_
01348 >
01349 class make_tuple<Input1_, Input2_, Input3_, Input4_, Stopper, Stopper>
01350 {
01351 Input1_ & i1;
01352 Input2_ & i2;
01353 Input3_ & i3;
01354 Input4_ & i4;
01355
01356 public:
01358 typedef typename stxxl::tuple<
01359 typename Input1_::value_type,
01360 typename Input2_::value_type,
01361 typename Input3_::value_type,
01362 typename Input4_::value_type
01363 > value_type;
01364
01365 private:
01366 value_type current;
01367
01368 public:
01370 make_tuple(
01371 Input1_ & i1_,
01372 Input2_ & i2_,
01373 Input3_ & i3_,
01374 Input4_ & i4_
01375 ) :
01376 i1(i1_), i2(i2_), i3(i3_), i4(i4_),
01377 current(value_type(*i1, *i2, *i3, *i4)) { }
01378
01380 const value_type & operator * () const
01381 {
01382 return current;
01383 }
01384
01385 const value_type * operator -> () const
01386 {
01387 return ¤t;
01388 }
01389
01391 make_tuple & operator ++ ()
01392 {
01393 ++i1;
01394 ++i2;
01395 ++i3;
01396 ++i4;
01397
01398 if (!empty())
01399 current = value_type(*i1, *i2, *i3, *i4);
01400
01401 return *this;
01402 }
01403
01405 bool empty() const
01406 {
01407 return i1.empty() || i2.empty() || i3.empty() ||
01408 i4.empty();
01409 }
01410 };
01411
01420 template <
01421 class Input1_,
01422 class Input2_,
01423 class Input3_,
01424 class Input4_,
01425 class Input5_
01426 >
01427 class make_tuple<Input1_, Input2_, Input3_, Input4_, Input5_, Stopper>
01428 {
01429 Input1_ & i1;
01430 Input2_ & i2;
01431 Input3_ & i3;
01432 Input4_ & i4;
01433 Input5_ & i5;
01434
01435 public:
01437 typedef typename stxxl::tuple<
01438 typename Input1_::value_type,
01439 typename Input2_::value_type,
01440 typename Input3_::value_type,
01441 typename Input4_::value_type,
01442 typename Input5_::value_type
01443 > value_type;
01444
01445 private:
01446 value_type current;
01447
01448 public:
01450 make_tuple(
01451 Input1_ & i1_,
01452 Input2_ & i2_,
01453 Input3_ & i3_,
01454 Input4_ & i4_,
01455 Input5_ & i5_
01456 ) :
01457 i1(i1_), i2(i2_), i3(i3_), i4(i4_), i5(i5_),
01458 current(value_type(*i1, *i2, *i3, *i4, *i5)) { }
01459
01461 const value_type & operator * () const
01462 {
01463 return current;
01464 }
01465
01466 const value_type * operator -> () const
01467 {
01468 return ¤t;
01469 }
01470
01472 make_tuple & operator ++ ()
01473 {
01474 ++i1;
01475 ++i2;
01476 ++i3;
01477 ++i4;
01478 ++i5;
01479
01480 if (!empty())
01481 current = value_type(*i1, *i2, *i3, *i4, *i5);
01482
01483 return *this;
01484 }
01485
01487 bool empty() const
01488 {
01489 return i1.empty() || i2.empty() || i3.empty() ||
01490 i4.empty() || i5.empty();
01491 }
01492 };
01493
01494
01496 }
01497
01498 __STXXL_END_NAMESPACE
01499
01500
01501 #include <stxxl/bits/stream/choose.h>
01502 #include <stxxl/bits/stream/unique.h>
01503
01504
01505 #endif // !STXXL_STREAM_HEADER
01506