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;
}
};