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:
** - 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 <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-adaptor-test.cpp
*/
@ -275,14 +283,14 @@ namespace lib {
ST core_;
public:
typedef typename iter::TypeBinding<T>::pointer pointer;
typedef typename iter::TypeBinding<T>::reference reference;
typedef typename iter::TypeBinding<T>::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<class T1, class T2, class STX>
friend bool operator== (IterStateWrapper<T1,STX> const&, IterStateWrapper<T2,STX> const&);
};
/// 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 == */
friend bool
hasNext (DataHandle const&, Pos const& pos) ////TICKET #410
checkPoint (DataHandle const&, Pos const& pos)
{
return bool(pos);
}

View file

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

View file

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

View file

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

View file

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