direction switching iterator unit test PASS
This commit is contained in:
parent
f9c0c4c3d0
commit
eb208ea145
4 changed files with 61 additions and 22 deletions
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
{ }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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: ::.............::............::...........::..........::.........::........::.......::......::.....::....::...::..::.$
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue