From 750b124f88cfe461822599ddd5fdb6cec6cf66aa Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 29 Oct 2017 15:31:34 +0100 Subject: [PATCH] Library: complement the pseudo-iterator by a IterSource front-end --- src/lib/iter-source.hpp | 24 ++++++++-- tests/library/iter-source-test.cpp | 70 +++++++++++++++++++++++------- wiki/thinkPad.ichthyo.mm | 19 +++++--- 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/lib/iter-source.hpp b/src/lib/iter-source.hpp index d25beb0a9..13083d7e9 100644 --- a/src/lib/iter-source.hpp +++ b/src/lib/iter-source.hpp @@ -364,6 +364,22 @@ namespace lib { } + /** an IterSource frontend to return just a single value once. + * @warning behind the scenes, a heap allocation is managed by shared_ptr, + * to maintain a copy of the wrapped element. When passing a reference, + * only a reference will be wrapped, but a heap allocation happens nontheless + */ + template + auto + singleVal (VAL&& something) + { + using Src = decltype(singleValIterator (forward(something))); + using Val = typename _IterT::Val; + + return IterSource::build (new WrappedLumieraIter{singleValIterator (forward(something))}); + } + + /** pipes a given Lumiera Forward Iterator through * a transformation function and wraps the resulting * transforming Iterator, exposing just an IterSource. @@ -461,11 +477,11 @@ namespace lib { using Range = RangeIter; Range contents (container.begin(), container.end()); - return IterSource::build (new WrappedLumieraIter(contents)); + return IterSource::build (new WrappedLumieraIter(contents)); } - - /** @return a Lumiera Forward Iterator yielding all values + + /** @return a Lumiera Forward Iterator to yield all values * defined by a classical Iterator range. */ template @@ -478,9 +494,9 @@ namespace lib { Range contents (begin, end); return IterSource::build (new WrappedLumieraIter(contents)); } - } using iter_source::wrapIter; + using iter_source::singleVal; using iter_source::transform; using iter_source::eachMapKey; using iter_source::eachDistinctKey; diff --git a/tests/library/iter-source-test.cpp b/tests/library/iter-source-test.cpp index a5740a199..daeb09150 100644 --- a/tests/library/iter-source-test.cpp +++ b/tests/library/iter-source-test.cpp @@ -59,6 +59,8 @@ namespace test{ using std::list; using std::rand; + using lumiera::error::LUMIERA_ERROR_ITER_EXHAUST; + namespace { // Subject of test @@ -132,6 +134,16 @@ namespace test{ }; + + /** diagnostics helper */ + template + inline void + pullOut (IT& iter) + { + for ( ; iter; ++iter ) + cout << "::" << *iter; + cout << endl; + } } // (END) impl test dummy containers @@ -207,11 +219,25 @@ namespace test{ } + /** @test verify transforming an embedded iterator + * This test not only wraps a source iterator and packages it behind the + * abstracting interface IterSource, but in addition also applies a function + * to each element yielded by the source iterator. As demo transformation + * we use the values from our custom container (\ref WrappedList) to build + * a time value in quarter seconds + * + */ void verify_transformIter() { WrappedList customList(NUM_ELMS); - WrappedList::iterator sourceValues = customList.begin(); + WrappedList::iterator sourceValues = customList.begin(); + + // transformation function + auto makeTime = [](int input_sec) -> TimeVar + { + return time::Time (time::FSecs (input_sec, 4)); + }; TimeIter tIt (transform (sourceValues, makeTime)); CHECK (!isnil (tIt)); @@ -219,27 +245,39 @@ namespace test{ CHECK (!tIt); } - /** transformation function, to be applied for each element: - * just build a time value, using the input as 1/4 seconds - */ - static TimeVar - makeTime (int input_sec) - { - return time::Time (time::FSecs (input_sec, 4)); - } - - - template + /** @test an IterSouce which returns just a single value once */ void - pullOut (IT& iter) + verify_singleValIter() { - for ( ; iter; ++iter ) - cout << "::" << *iter; - cout << endl; + int i{-9}; + + IntIter ii = singleVal(12); + CHECK (not isnil(ii)); + CHECK (12 == *ii); + + ++ii; + CHECK (isnil (ii)); + VERIFY_ERROR (ITER_EXHAUST, *ii ); + + // IterSource is an abstracting interface, + // thus we're able to reassign an embedded iterator + // with a different value type (int& instead of int) + ii = singleVal(i); + + CHECK (not isnil(ii)); + CHECK (-9 == *ii); + + // NOTE: since we passed a reference, a reference got wrapped + i = 23; + CHECK (23 == *ii); + ++ii; + CHECK (isnil (ii)); } + + template void verify_MapWrappers() diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a74c46729..9904b8d12 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -4685,11 +4685,15 @@ - - - + + + + + - + + + @@ -4707,8 +4711,11 @@ - - + + + + +