Fix naming of Iteration control API functions (closes #410)
comes in handy now, since IterStateWrapper uses a similar API
This commit is contained in:
parent
83a0f4b41f
commit
378ebe21f0
6 changed files with 70 additions and 51 deletions
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue