Fix naming of Iteration control API functions (closes #410)

comes in handy now, since IterStateWrapper uses a similar API
This commit is contained in:
Fischlurch 2012-05-19 02:13:18 +02:00
parent 83a0f4b41f
commit 378ebe21f0
6 changed files with 70 additions and 51 deletions

View file

@ -32,6 +32,9 @@
** Depending on the concrete situation, several flavours are provided: ** Depending on the concrete situation, several flavours are provided:
** - the IterAdapter retains an active callback connection to the ** - the IterAdapter retains an active callback connection to the
** controlling container, thus allowing arbitrary complex behaviour. ** 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 ** - the RangeIter allows just to expose a range of elements defined
** by a STL-like pair of "start" and "end" iterators ** by a STL-like pair of "start" and "end" iterators
** - often, objects are managed internally by pointers, while allowing ** - often, objects are managed internally by pointers, while allowing
@ -47,7 +50,7 @@
** extended with the help of itertools.hpp ** extended with the help of itertools.hpp
** **
** Basically every class in compliance with our specific iterator concept ** 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 ** \par Lumiera forward iterator concept
@ -75,8 +78,6 @@
** \em dereferenced to yield the "current" value. ** \em dereferenced to yield the "current" value.
** - moreover, iterators may be incremented until exhaustion. ** - moreover, iterators may be incremented until exhaustion.
** **
** @todo naming of the iteration control function: TICKET #410
**
** @see iter-adapter-test.cpp ** @see iter-adapter-test.cpp
** @see itertools.hpp ** @see itertools.hpp
** @see IterSource (completely opaque iterator) ** @see IterSource (completely opaque iterator)
@ -134,8 +135,8 @@ namespace lib {
* -# it should be convertible to the pointer type it declares * -# it should be convertible to the pointer type it declares
* -# dereferencing should yield a type that is convertible to the reference type * -# 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) * - 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 * We store a pointer-like backlink to invoke a special iteration control API:
* -# \c hasNext yields true iff the source has yet more result values to yield * -# \c checkPoint yields true iff the source has yet more result values to yield
* -# \c iterNext advances the POS to the next element * -# \c iterNext advances the POS to the next element
* *
* @see scoped-ptrvect.hpp usage example * @see scoped-ptrvect.hpp usage example
@ -158,7 +159,7 @@ namespace lib {
: source_(src) : source_(src)
, pos_(startpos) , pos_(startpos)
{ {
checkPos(); check();
} }
IterAdapter () IterAdapter ()
@ -194,7 +195,7 @@ namespace lib {
bool bool
isValid () const isValid () const
{ {
return checkPos(); return check();
} }
bool bool
@ -212,28 +213,25 @@ namespace lib {
* for example setting it to a "stop iteration" mark. * for example setting it to a "stop iteration" mark.
*/ */
bool bool
checkPos() const check() const
{ {
return source_ && hasNext (source_,pos_); //////////////TICKET #410 return source_ && checkPoint (source_,pos_); // extension point: free function checkPoint(...)
} }
/** ask the controlling container to yield the next position. /** ask the controlling container to yield the next position.
* The call is dispatched only if the current position is valid; * The call is dispatched only if the current position is valid;
* any new position returned is again validated, so to detect * any new position reached will typically be validated prior
* the iteration end as soon as possible. * to any further access, through invocation of #check.
*/ */
bool void
iterate () iterate()
{ {
if (!checkPos()) return false; if (check())
iterNext (source_,pos_); // extension point: free function iterNext(...)
iterNext (source_,pos_); }
return checkPos();
}
private: private:
void void
_maybe_throw() const _maybe_throw() const
{ {
@ -262,9 +260,19 @@ namespace lib {
* right into the iterator. Contrast this to IterAdapter referring to an controlling * 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 * 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 * 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 <b>iteration control API</b> 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-explorer-test.hpp
* @see iter-adaptor-test.cpp * @see iter-adaptor-test.cpp
*/ */
@ -275,14 +283,14 @@ namespace lib {
ST core_; ST core_;
public: public:
typedef typename iter::TypeBinding<T>::pointer pointer; typedef T* pointer;
typedef typename iter::TypeBinding<T>::reference reference; typedef T& reference;
typedef typename iter::TypeBinding<T>::value_type value_type; typedef T value_type;
IterStateWrapper (ST initialState) IterStateWrapper (ST initialState)
: core_(initialState) : core_(initialState)
{ {
checkPos(core_); checkPoint (core_);
} }
IterStateWrapper () IterStateWrapper ()
@ -296,28 +304,28 @@ namespace lib {
operator*() const operator*() const
{ {
_maybe_throw(); _maybe_throw();
return yield (core_); // extension point: yield return yield (core_); // extension point: yield
} }
pointer pointer
operator->() const operator->() const
{ {
_maybe_throw(); _maybe_throw();
return & yield(core_); // extension point: yield return & yield(core_); // extension point: yield
} }
IterStateWrapper& IterStateWrapper&
operator++() operator++()
{ {
_maybe_throw(); _maybe_throw();
iterNext (core_); // extension point: iterNext iterNext (core_); // extension point: iterNext
return *this; return *this;
} }
bool bool
isValid () const isValid () const
{ {
return checkPos(core_); // extension point: checkPos return checkPoint(core_); // extension point: checkPoint
} }
bool bool
@ -326,7 +334,6 @@ namespace lib {
return !isValid(); return !isValid();
} }
private: private:
void void
@ -336,20 +343,32 @@ namespace lib {
_throwIterExhausted(); _throwIterExhausted();
} }
/// comparison of equivalent iterators
friend bool operator== (IterStateWrapper const& il, IterStateWrapper const& ir) /// comparison is allowed to access state implementation core
{ template<class T1, class T2, class STX>
return (il.empty() && ir.empty()) friend bool operator== (IterStateWrapper<T1,STX> const&, IterStateWrapper<T2,STX> const&);
|| (il.isValid() && ir.isValid() && *il == *ir);
}
friend bool operator!= (IterStateWrapper const& il, IterStateWrapper const& ir)
{
return ! (il == ir);
}
}; };
/// Supporting equality comparisons of equivalent iterators (same state type)...
template<class T1, class T2, class ST>
bool operator== (IterStateWrapper<T1,ST> const& il, IterStateWrapper<T2,ST> const& ir)
{
return (il.empty() && ir.empty())
|| (il.isValid() && ir.isValid() && il.core_ == ir.core_);
}
template<class T1, class T2, class ST>
bool operator!= (IterStateWrapper<T1,ST> const& il, IterStateWrapper<T2,ST> const& ir)
{
return ! (il == ir);
}

View file

@ -112,7 +112,7 @@ namespace lib {
/* == Iteration control API for IterAdapter frontend == */ /* == Iteration control API for IterAdapter frontend == */
friend bool friend bool
hasNext (DataHandle const&, Pos const& pos) ////TICKET #410 checkPoint (DataHandle const&, Pos const& pos)
{ {
return bool(pos); return bool(pos);
} }

View file

@ -526,7 +526,7 @@ namespace lib {
/** Iteration-logic: detect iteration end. */ /** Iteration-logic: detect iteration end. */
template<typename POS> template<typename POS>
friend bool friend bool
hasNext (const ScopedCollection* src, POS & pos) checkPoint (const ScopedCollection* src, POS & pos)
{ {
REQUIRE (src); REQUIRE (src);
if ((pos) && (pos < src->_access_end())) if ((pos) && (pos < src->_access_end()))

View file

@ -239,7 +239,7 @@ namespace session {
friend bool friend bool
hasNext (PReso const&, Result const& pos) ////TICKET #410 checkPoint (PReso const&, Result const& pos)
{ {
return bool(pos); return bool(pos);
} }

View file

@ -147,7 +147,7 @@ namespace test{
*/ */
template<class ITER> template<class ITER>
friend bool friend bool
hasNext (const TestContainer* src, ITER& pos) checkPoint (const TestContainer* src, ITER& pos)
{ {
REQUIRE (src); REQUIRE (src);
if ((pos != ITER(0)) && (pos != src->numberz_.end())) if ((pos != ITER(0)) && (pos != src->numberz_.end()))

View file

@ -82,21 +82,21 @@ namespace test{
{ } { }
friend bool friend bool
checkPos (State const& st) checkPoint (State const& st)
{ {
return st.p < st.e; return st.p < st.e;
} }
friend uint const& friend uint&
yield (State const& st) yield (State const& st)
{ {
return checkPos(st)? st.p : st.e; return util::unConst(checkPoint(st)? st.p : st.e);
} }
friend void friend void
iterNext (State & st) iterNext (State & st)
{ {
if (!checkPos (st)) return; if (!checkPoint(st)) return;
++st.p; ++st.p;
} }
}; };