From f7402ef89da5298a917222a71f972d2960ac1be4 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 13 Aug 2017 01:31:08 +0200 Subject: [PATCH] Library: allow to consume an iterator while taking the snapshot --- src/lib/iter-adapter-stl.hpp | 68 ++++++++++++++++--------- tests/library/iter-adapter-stl-test.cpp | 12 ++--- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/lib/iter-adapter-stl.hpp b/src/lib/iter-adapter-stl.hpp index 8eacf2b9d..ed04ca37c 100644 --- a/src/lib/iter-adapter-stl.hpp +++ b/src/lib/iter-adapter-stl.hpp @@ -421,39 +421,49 @@ namespace iter_stl { mutable Sequence buffer_; - size_t pos_; + size_t pos_ = 0; public: /** create empty snapshot */ - IterSnapshot() - : buffer_() - , pos_(0) - { } + IterSnapshot() { } - /** take snapshot by discharging a copy - * of the given Lumiera Forward iterator - * @warning depending on the implementation - * backing the source iterator, this - * might or might not yield side-effects. + /** take snapshot by discharging the given Lumiera Forward iterator + * @warning depending on the implementation backing the source iterator, + * this might or might not yield side-effects. + */ + template + IterSnapshot (IT& src) + { + for ( ; src; ++src) + buffer_.push_back(*src); + } + + /** build snapshot from a copy of the Lumiera Iterator + * @warning depending on the implementation backing the source iterator, + * this might or might not yield side-effects. */ template IterSnapshot (IT const& src) - : buffer_() - , pos_(0) { - for (IT copy(src); copy; ++copy) + for (IT copy{src}; copy; ++copy) buffer_.push_back(*copy); } + /** take snapshot by consuming a STL iterator */ + template + IterSnapshot (IT& pos, IT const& end) + { + for ( ; pos!=end; ++pos) + buffer_.push_back(*pos); + } + /** take snapshot from STL iterator */ template IterSnapshot (IT const& begin, IT const& end) - : buffer_() - , pos_(0) { - for (IT p(begin); p!=end; ++p) - buffer_.push_back(*p); + for (IT pos{begin}; pos!=end; ++pos) + buffer_.push_back(*pos); } IterSnapshot(IterSnapshot &&) = default; @@ -552,9 +562,19 @@ namespace iter_stl { template inline ContentSnapshot snapshot(CON const& con) - { - return ContentSnapshot(begin(con), end(con)); - } + { + return ContentSnapshot{begin(con), end(con)}; + } + + /** Take a snapshot of the given LumieraIterator, which is thereby consumed + * @return Lumiera Forward Iterator to yield each Element from this snapshot + */ + template + inline ContentSnapshot + dischargeToSnapshot(IT& ii) + { + return ContentSnapshot{ii}; + } /** Take a snapshot of the given \c std::initializer_list * @return Lumiera Forward Iterator to yield each Element from this snapshot @@ -568,10 +588,10 @@ namespace iter_stl { template inline iter_stl::IterSnapshot snapshot(std::initializer_list const&& ili) - { - using OnceIter = iter_stl::IterSnapshot; - return OnceIter(begin(ili), end(ili)); - } + { + using OnceIter = iter_stl::IterSnapshot; + return OnceIter(begin(ili), end(ili)); + } }} // namespace lib::iter_stl diff --git a/tests/library/iter-adapter-stl-test.cpp b/tests/library/iter-adapter-stl-test.cpp index f4783da82..ad6715043 100644 --- a/tests/library/iter-adapter-stl-test.cpp +++ b/tests/library/iter-adapter-stl-test.cpp @@ -177,9 +177,9 @@ namespace test{ Snapshot capture1 (vec.begin(), vec.end()); Range range_of_all (vec.begin(), vec.end()); - Snapshot capture2 (range_of_all); - CHECK (range_of_all); // snapshot doesn't affect given source iterator pos - CHECK (capture2); + Snapshot capture2 = iter::snapshot(range_of_all); // NOTE: when specifically taken this way, + CHECK (range_of_all); // snapshot doesn't affect given source iterator pos + CHECK (capture2); // (but WARNING, the IterSnapshot ctor itself is destructive) CHECK (vec.begin() == range_of_all.getPos()); CHECK (vec.end() == range_of_all.getEnd()); @@ -220,9 +220,9 @@ namespace test{ CHECK (!capture1); CHECK (!capture2); CHECK (!capture3); - CHECK (capture1 == capture2); - CHECK (capture3 != capture1); // all exhausted, but the difference in contents remains - CHECK (capture3 != capture2); + CHECK (capture1 == capture2); // all exhausted iterators count as "equal" + CHECK (capture3 == capture1); // this ensures the idiom while(pos != end) works + CHECK (capture3 == capture2); } template