From eb208ea14517016235f3b081a89cc44239a47a21 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 6 Dec 2015 02:28:47 +0100 Subject: [PATCH] direction switching iterator unit test PASS --- src/lib/iter-adapter.hpp | 15 +++++++-- src/lib/iter-cursor.hpp | 51 ++++++++++++++++++++++-------- tests/12metaprogramming.tests | 5 +++ tests/library/iter-cursor-test.cpp | 12 +++---- 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index ed1adaf66..d397150d1 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -286,7 +286,12 @@ namespace lib { * -# \c checkPoint establishes if the given state element represents a valid state * -# \c iterNext evolves this state by one step (sideeffect) * -# \c yield realises the given state, yielding an element of result type T - * + * @param T nominal result type (maybe const, but without reference). + * The resulting iterator will yield a reference to this type T + * @param ST type of the "state core", defaults to T. + * The resulting iterator will hold an instance of ST, which thus + * needs to be copyable and default constructible to the extent + * this is required for the iterator as such. * @see IterExplorer an iterator monad built on top of IterStateWrapper * @see iter-explorer-test.hpp * @see iter-adaptor-test.cpp @@ -302,9 +307,15 @@ namespace lib { typedef T& reference; typedef T value_type; + IterStateWrapper (ST&& initialState) + : core_(std::forward(initialState)) + { + checkPoint (core_); // extension point: checkPoint + } + IterStateWrapper (ST const& initialState) : core_(initialState) - { + { checkPoint (core_); // extension point: checkPoint } diff --git a/src/lib/iter-cursor.hpp b/src/lib/iter-cursor.hpp index 938753ddd..4c455cbd1 100644 --- a/src/lib/iter-cursor.hpp +++ b/src/lib/iter-cursor.hpp @@ -29,8 +29,6 @@ ** ["Lumiera Forward Iterator"][iter-adapter.hpp] concept. But it has ** the additional ability to [switch the working direction][IterCursor::switchDir]. ** - ** @note as of 12/2015 this is complete bs - ** ** @see IterCursor_test ** @see iter-adapter.hpp ** @see [usage example][event-log.hpp] @@ -44,11 +42,8 @@ #include "lib/error.hpp" #include "lib/iter-adapter.hpp" -//#include "lib/symbol.hpp" -//#include "lib/util.hpp" -//#include -//#include +#include #include @@ -72,7 +67,7 @@ namespace lib { public: typedef typename iter::TypeBinding::pointer pointer; typedef typename iter::TypeBinding::reference reference; - typedef typename iter::TypeBinding::value_type value_type; + typedef typename std::remove_reference::type value_type; ///< @note will be const for const iterators CursorGear() @@ -94,8 +89,16 @@ namespace lib { toggle() { if (start_ == end_) return; - backwards_ = not backwards_; - ++pos_; + if (backwards_) + { + if (pos_ != start_) --pos_; + backwards_ = false; + } + else + { + if (pos_ != end_) ++pos_; + backwards_ = true; + } } /* === Iteration control API for IterStateWrapper == */ @@ -122,6 +125,18 @@ namespace lib { else ++gear.pos_; } + + + friend bool + operator== (CursorGear const& g1, CursorGear const& g2) + { + return (not checkPoint(g1) and not checkPoint(g2)) // note: all exhausted iters are equal + or ( g1.pos_ == g2.pos_ + and g1.backwards_ == g2.backwards_ + and g1.start_ == g2.start_ + and g1.end_ == g2.end_ + ); + } }; @@ -132,13 +147,21 @@ namespace lib { /** * A cursor-like iterator with the ability to switch iteration direction. - * + * It can be built on top of any bidirectional STL iterator or similar entity, + * which has an `--` operator. Initially, IterCursor will operate in forward + * direction; irrespective of the current direction, it always fulfils the + * ["Lumiera Forward Iterator"][iter-adapter.hpp] concept, i.e. it can be + * iterated until exhaustion, in which case it will evaluate to bool(false). + * @note IterCursor instances can be equality compared, also taking the + * current direction into account. As a special case, all + * exhausted iterators are treated as equal. */ template class IterCursor - : public IterStateWrapper::reference, iter::CursorGear> + : public IterStateWrapper::value_type, iter::CursorGear> { - using _Core = IterStateWrapper::reference, iter::CursorGear>; + using _Core = iter::CursorGear; + using _Parent = IterStateWrapper; public: IterCursor() { } @@ -146,11 +169,11 @@ namespace lib { template explicit IterCursor (CON& container) - : _Core(container.begin(), container.end()) + : _Parent(_Core(container.begin(), container.end())) { } IterCursor (IT&& begin, IT&& end) - : _Core(std::forward(begin), std::forward(end)) + : _Parent(_Core(std::forward(begin), std::forward(end))) { } diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index ca708eb61..1e405b381 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -221,6 +221,11 @@ out-lit: ::22::21::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4: END +TEST "forward/backward iterator" IterCursor_test 20 <