From 378ebe21f0f4d9eb8a509def5891e7fd5744d480 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 19 May 2012 02:13:18 +0200 Subject: [PATCH] Fix naming of Iteration control API functions (closes #410) comes in handy now, since IterStateWrapper uses a similar API --- src/lib/iter-adapter.hpp | 105 ++++++++++++-------- src/lib/iter-source.hpp | 2 +- src/lib/scoped-collection.hpp | 2 +- src/proc/mobject/session/query-resolver.hpp | 2 +- tests/lib/iter-adapter-test.cpp | 2 +- tests/lib/iter-explorer-test.cpp | 8 +- 6 files changed, 70 insertions(+), 51 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index ca69dec8d..cc95c1859 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -32,6 +32,9 @@ ** Depending on the concrete situation, several flavours are provided: ** - the IterAdapter retains an active callback connection to the ** controlling container, thus allowing arbitrary complex behaviour. + ** - the IterStateWrapper uses a variation of that approach, where the + ** representation of the current state is embedded as an state value + ** element right into the iterator instance. ** - the RangeIter allows just to expose a range of elements defined ** by a STL-like pair of "start" and "end" iterators ** - often, objects are managed internally by pointers, while allowing @@ -47,7 +50,7 @@ ** extended with the help of itertools.hpp ** ** Basically every class in compliance with our specific iterator concept - ** can be used as a building block in this framework. + ** can be used as a building block within this framework. ** ** ** \par Lumiera forward iterator concept @@ -75,8 +78,6 @@ ** \em dereferenced to yield the "current" value. ** - moreover, iterators may be incremented until exhaustion. ** - ** @todo naming of the iteration control function: TICKET #410 - ** ** @see iter-adapter-test.cpp ** @see itertools.hpp ** @see IterSource (completely opaque iterator) @@ -134,8 +135,8 @@ namespace lib { * -# it should be convertible to the pointer type it declares * -# dereferencing should yield a type that is convertible to the reference type * - CON points to the data source of this iterator (typically a data container type) - * We store a pointer-like backlink to invoke a special iteration control API: //////////////TICKET #410 - * -# \c hasNext yields true iff the source has yet more result values to yield + * We store a pointer-like backlink to invoke a special iteration control API: + * -# \c checkPoint yields true iff the source has yet more result values to yield * -# \c iterNext advances the POS to the next element * * @see scoped-ptrvect.hpp usage example @@ -158,7 +159,7 @@ namespace lib { : source_(src) , pos_(startpos) { - checkPos(); + check(); } IterAdapter () @@ -194,7 +195,7 @@ namespace lib { bool isValid () const { - return checkPos(); + return check(); } bool @@ -212,28 +213,25 @@ namespace lib { * for example setting it to a "stop iteration" mark. */ bool - checkPos() const - { - return source_ && hasNext (source_,pos_); //////////////TICKET #410 - } + check() const + { + return source_ && checkPoint (source_,pos_); // extension point: free function checkPoint(...) + } /** ask the controlling container to yield the next position. * The call is dispatched only if the current position is valid; - * any new position returned is again validated, so to detect - * the iteration end as soon as possible. + * any new position reached will typically be validated prior + * to any further access, through invocation of #check. */ - bool - iterate () - { - if (!checkPos()) return false; - - iterNext (source_,pos_); - return checkPos(); - } + void + iterate() + { + if (check()) + iterNext (source_,pos_); // extension point: free function iterNext(...) + } private: - void _maybe_throw() const { @@ -262,9 +260,19 @@ namespace lib { * right into the iterator. Contrast this to IterAdapter referring to an controlling * container behind the scenes. Here, all of the state is assumed to live in the * custom type embedded into this iterator, accessed and manipulated through - * an set of free function to be resolved by ADL. + * a set of free function to be resolved by ADL. * - * @see IterExplorer a monadic iterator built on top of IterStateWrapper + * \par Assumptions when building iterators based on IterStateWrapper + * There is a custom state representation type ST. + * - default constructible + * - this default state represents the \em bottom (invalid) state. + * - copyable, because iterators are passed by value + * - this type needs to provide an iteration control API through free functions + * -# \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 + * + * @see IterExplorer an iterator monad built on top of IterStateWrapper * @see iter-explorer-test.hpp * @see iter-adaptor-test.cpp */ @@ -275,14 +283,14 @@ namespace lib { ST core_; public: - typedef typename iter::TypeBinding::pointer pointer; - typedef typename iter::TypeBinding::reference reference; - typedef typename iter::TypeBinding::value_type value_type; + typedef T* pointer; + typedef T& reference; + typedef T value_type; IterStateWrapper (ST initialState) : core_(initialState) { - checkPos(core_); + checkPoint (core_); } IterStateWrapper () @@ -296,28 +304,28 @@ namespace lib { operator*() const { _maybe_throw(); - return yield (core_); // extension point: yield + return yield (core_); // extension point: yield } pointer operator->() const { _maybe_throw(); - return & yield(core_); // extension point: yield + return & yield(core_); // extension point: yield } IterStateWrapper& operator++() { _maybe_throw(); - iterNext (core_); // extension point: iterNext + iterNext (core_); // extension point: iterNext return *this; } bool isValid () const { - return checkPos(core_); // extension point: checkPos + return checkPoint(core_); // extension point: checkPoint } bool @@ -326,7 +334,6 @@ namespace lib { return !isValid(); } - private: void @@ -336,20 +343,32 @@ namespace lib { _throwIterExhausted(); } - /// comparison of equivalent iterators - friend bool operator== (IterStateWrapper const& il, IterStateWrapper const& ir) - { - return (il.empty() && ir.empty()) - || (il.isValid() && ir.isValid() && *il == *ir); - } - friend bool operator!= (IterStateWrapper const& il, IterStateWrapper const& ir) - { - return ! (il == ir); - } + + /// comparison is allowed to access state implementation core + template + friend bool operator== (IterStateWrapper const&, IterStateWrapper const&); }; + /// Supporting equality comparisons of equivalent iterators (same state type)... + template + bool operator== (IterStateWrapper const& il, IterStateWrapper const& ir) + { + return (il.empty() && ir.empty()) + || (il.isValid() && ir.isValid() && il.core_ == ir.core_); + } + + template + bool operator!= (IterStateWrapper const& il, IterStateWrapper const& ir) + { + return ! (il == ir); + } + + + + + diff --git a/src/lib/iter-source.hpp b/src/lib/iter-source.hpp index 41b56e2c5..c2f090710 100644 --- a/src/lib/iter-source.hpp +++ b/src/lib/iter-source.hpp @@ -112,7 +112,7 @@ namespace lib { /* == Iteration control API for IterAdapter frontend == */ friend bool - hasNext (DataHandle const&, Pos const& pos) ////TICKET #410 + checkPoint (DataHandle const&, Pos const& pos) { return bool(pos); } diff --git a/src/lib/scoped-collection.hpp b/src/lib/scoped-collection.hpp index e1cba4ec2..58f2f0433 100644 --- a/src/lib/scoped-collection.hpp +++ b/src/lib/scoped-collection.hpp @@ -526,7 +526,7 @@ namespace lib { /** Iteration-logic: detect iteration end. */ template friend bool - hasNext (const ScopedCollection* src, POS & pos) + checkPoint (const ScopedCollection* src, POS & pos) { REQUIRE (src); if ((pos) && (pos < src->_access_end())) diff --git a/src/proc/mobject/session/query-resolver.hpp b/src/proc/mobject/session/query-resolver.hpp index 7fe5631dc..c09ee9d9d 100644 --- a/src/proc/mobject/session/query-resolver.hpp +++ b/src/proc/mobject/session/query-resolver.hpp @@ -239,7 +239,7 @@ namespace session { friend bool - hasNext (PReso const&, Result const& pos) ////TICKET #410 + checkPoint (PReso const&, Result const& pos) { return bool(pos); } diff --git a/tests/lib/iter-adapter-test.cpp b/tests/lib/iter-adapter-test.cpp index ef6f2c9da..0361319f1 100644 --- a/tests/lib/iter-adapter-test.cpp +++ b/tests/lib/iter-adapter-test.cpp @@ -147,7 +147,7 @@ namespace test{ */ template friend bool - hasNext (const TestContainer* src, ITER& pos) + checkPoint (const TestContainer* src, ITER& pos) { REQUIRE (src); if ((pos != ITER(0)) && (pos != src->numberz_.end())) diff --git a/tests/lib/iter-explorer-test.cpp b/tests/lib/iter-explorer-test.cpp index 0ac8ac045..e29768c62 100644 --- a/tests/lib/iter-explorer-test.cpp +++ b/tests/lib/iter-explorer-test.cpp @@ -82,21 +82,21 @@ namespace test{ { } friend bool - checkPos (State const& st) + checkPoint (State const& st) { return st.p < st.e; } - friend uint const& + friend uint& yield (State const& st) { - return checkPos(st)? st.p : st.e; + return util::unConst(checkPoint(st)? st.p : st.e); } friend void iterNext (State & st) { - if (!checkPos (st)) return; + if (!checkPoint(st)) return; ++st.p; } };