direction switching iterator unit test PASS

This commit is contained in:
Fischlurch 2015-12-06 02:28:47 +01:00
parent f9c0c4c3d0
commit eb208ea145
4 changed files with 61 additions and 22 deletions

View file

@ -286,7 +286,12 @@ namespace lib {
* -# \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
*
* @param T nominal result type (maybe const, but without reference).
* The resulting iterator will yield a reference to this type T
* @param ST type of the "state core", defaults to T.
* The resulting iterator will hold an instance of ST, which thus
* needs to be copyable and default constructible to the extent
* this is required for the iterator as such.
* @see IterExplorer an iterator monad built on top of IterStateWrapper
* @see iter-explorer-test.hpp
* @see iter-adaptor-test.cpp
@ -302,9 +307,15 @@ namespace lib {
typedef T& reference;
typedef T value_type;
IterStateWrapper (ST&& initialState)
: core_(std::forward<ST>(initialState))
{
checkPoint (core_); // extension point: checkPoint
}
IterStateWrapper (ST const& initialState)
: core_(initialState)
{
{
checkPoint (core_); // extension point: checkPoint
}

View file

@ -29,8 +29,6 @@
** ["Lumiera Forward Iterator"][iter-adapter.hpp] concept. But it has
** the additional ability to [switch the working direction][IterCursor::switchDir].
**
** @note as of 12/2015 this is complete bs
**
** @see IterCursor_test
** @see iter-adapter.hpp
** @see [usage example][event-log.hpp]
@ -44,11 +42,8 @@
#include "lib/error.hpp"
#include "lib/iter-adapter.hpp"
//#include "lib/symbol.hpp"
//#include "lib/util.hpp"
//#include <boost/noncopyable.hpp>
//#include <string>
#include <type_traits>
#include <utility>
@ -72,7 +67,7 @@ namespace lib {
public:
typedef typename iter::TypeBinding<IT>::pointer pointer;
typedef typename iter::TypeBinding<IT>::reference reference;
typedef typename iter::TypeBinding<IT>::value_type value_type;
typedef typename std::remove_reference<reference>::type value_type; ///< @note will be const for const iterators
CursorGear()
@ -94,8 +89,16 @@ namespace lib {
toggle()
{
if (start_ == end_) return;
backwards_ = not backwards_;
++pos_;
if (backwards_)
{
if (pos_ != start_) --pos_;
backwards_ = false;
}
else
{
if (pos_ != end_) ++pos_;
backwards_ = true;
}
}
/* === Iteration control API for IterStateWrapper == */
@ -122,6 +125,18 @@ namespace lib {
else
++gear.pos_;
}
friend bool
operator== (CursorGear const& g1, CursorGear const& g2)
{
return (not checkPoint(g1) and not checkPoint(g2)) // note: all exhausted iters are equal
or ( g1.pos_ == g2.pos_
and g1.backwards_ == g2.backwards_
and g1.start_ == g2.start_
and g1.end_ == g2.end_
);
}
};
@ -132,13 +147,21 @@ namespace lib {
/**
* A cursor-like iterator with the ability to switch iteration direction.
*
* It can be built on top of any bidirectional STL iterator or similar entity,
* which has an `--` operator. Initially, IterCursor will operate in forward
* direction; irrespective of the current direction, it always fulfils the
* ["Lumiera Forward Iterator"][iter-adapter.hpp] concept, i.e. it can be
* iterated until exhaustion, in which case it will evaluate to bool(false).
* @note IterCursor instances can be equality compared, also taking the
* current direction into account. As a special case, all
* exhausted iterators are treated as equal.
*/
template<class IT>
class IterCursor
: public IterStateWrapper<typename iter::CursorGear<IT>::reference, iter::CursorGear<IT>>
: public IterStateWrapper<typename iter::CursorGear<IT>::value_type, iter::CursorGear<IT>>
{
using _Core = IterStateWrapper<typename iter::CursorGear<IT>::reference, iter::CursorGear<IT>>;
using _Core = iter::CursorGear<IT>;
using _Parent = IterStateWrapper<typename _Core::value_type, _Core>;
public:
IterCursor() { }
@ -146,11 +169,11 @@ namespace lib {
template<class CON>
explicit
IterCursor (CON& container)
: _Core(container.begin(), container.end())
: _Parent(_Core(container.begin(), container.end()))
{ }
IterCursor (IT&& begin, IT&& end)
: _Core(std::forward<IT>(begin), std::forward<IT>(end))
: _Parent(_Core(std::forward<IT>(begin), std::forward<IT>(end)))
{ }

View file

@ -221,6 +221,11 @@ out-lit: ::22::21::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4:
END
TEST "forward/backward iterator" IterCursor_test 20 <<END
return: 0
END
TEST "Iterable data source" IterSource_test 13 <<END
out: ::13::12::11::10::9::8::7::6::5::4::3::2::1
out: ::.............::............::...........::..........::.........::........::.......::......::.....::....::...::..::.$

View file

@ -99,14 +99,14 @@ namespace test{
CHECK (0 == *i1);
++++++i1;
CHECK (3 == *i1);
for (uint i=*i1 ; i1; ++i1)
for (uint i=*i1 ; i1; ++i1, ++i)
CHECK (i == *i1);
CHECK (isnil(i1));
Iter i2{numz};
uint sum =0;
while (i2)
while (++i2)
sum += *i2;
uint n = numz.size() - 1;
CHECK (sum == n*(n+1) / 2);
@ -134,7 +134,7 @@ namespace test{
{
Numz numz{makeNumz()};
Iter iter{numz};
CHECK (0 == *iter);
++++++++iter;
CHECK (4 == *iter);
@ -162,7 +162,7 @@ namespace test{
CHECK (!isnil(iter));
++iter;
CHECK (1 == *iter);
iter.switchDir();
++iter;
CHECK (0 == *iter);
@ -205,7 +205,7 @@ namespace test{
Numz numz{makeNumz()};
Numz const& const_numz{numz};
int i = 0;
uint i = 0;
for (Iter iter{numz};
iter; ++iter, ++i
)
@ -227,7 +227,7 @@ namespace test{
CHECK (*iter == i-1);
// note: the previous run indeed modified
// the element within the container.
// the elements within the container.
// ++(*iter); // doesn't compile, because it yields a "* const"
}