From 83a0f4b41fc8b4ce7e5af591fedaa8e32fe45f9d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 16 May 2012 01:01:20 +0200 Subject: [PATCH] Implementation (I) : IterStateWrapper as foundation (passing test) --- src/lib/iter-adapter.hpp | 94 ++++++++++++++++++++ tests/lib/iter-explorer-test.cpp | 143 +++++++++++++++++++++++++++++-- 2 files changed, 232 insertions(+), 5 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index 9cb5f6bee..ca69dec8d 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -256,6 +256,100 @@ namespace lib { + + /** + * Another Lumiera Forward Iterator building block, based on incorporating a state type + * 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. + * + * @see IterExplorer a monadic iterator built on top of IterStateWrapper + * @see iter-explorer-test.hpp + * @see iter-adaptor-test.cpp + */ + template + class IterStateWrapper + : public lib::BoolCheckable > + { + ST core_; + + public: + typedef typename iter::TypeBinding::pointer pointer; + typedef typename iter::TypeBinding::reference reference; + typedef typename iter::TypeBinding::value_type value_type; + + IterStateWrapper (ST initialState) + : core_(initialState) + { + checkPos(core_); + } + + IterStateWrapper () + : core_() + { } + + + /* === lumiera forward iterator concept === */ + + reference + operator*() const + { + _maybe_throw(); + return yield (core_); // extension point: yield + } + + pointer + operator->() const + { + _maybe_throw(); + return & yield(core_); // extension point: yield + } + + IterStateWrapper& + operator++() + { + _maybe_throw(); + iterNext (core_); // extension point: iterNext + return *this; + } + + bool + isValid () const + { + return checkPos(core_); // extension point: checkPos + } + + bool + empty () const + { + return !isValid(); + } + + + private: + + void + _maybe_throw() const + { + if (!isValid()) + _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); + } + }; + + + diff --git a/tests/lib/iter-explorer-test.cpp b/tests/lib/iter-explorer-test.cpp index f47f99000..0ac8ac045 100644 --- a/tests/lib/iter-explorer-test.cpp +++ b/tests/lib/iter-explorer-test.cpp @@ -31,18 +31,34 @@ #include "lib/linked-elements.hpp" #include -#include +//#include +#include #include namespace lib { + + namespace iter { + + template<> + struct TypeBinding + { + typedef uint value_type; + typedef uint const& reference; + typedef uint const* pointer; + }; + } + + + namespace test{ using ::Test; // using boost::lexical_cast; // using util::for_each; // using util::isnil; + using util::isnil; using util::isSameObject; // using std::vector; // using std::cout; @@ -53,12 +69,86 @@ namespace test{ namespace { // test dummy source iterator - uint NUM_ELMS = 10; +// uint NUM_ELMS = 10; + + class State + { + uint p,e; + + public: + State(uint start, uint end) + : p(start) + , e(end) + { } + + friend bool + checkPos (State const& st) + { + return st.p < st.e; + } + + friend uint const& + yield (State const& st) + { + return checkPos(st)? st.p : st.e; + } + + friend void + iterNext (State & st) + { + if (!checkPos (st)) return; + ++st.p; + } + }; + + /** */ class NumberSequence + : public IterStateWrapper { + + public: + explicit + NumberSequence(uint end = 0) + : IterStateWrapper (State(0,end)) + { } + NumberSequence(uint start, uint end) + : IterStateWrapper (State(start,end)) + { } }; + + inline NumberSequence + seq (uint end) + { + return NumberSequence(end); + } + + inline NumberSequence + seq (uint start, uint end) + { + return NumberSequence(start, end); + } + + NumberSequence NIL_Sequence; + + + + /** Diagnostic helper: "squeeze out" the given iterator + * and join all yielded elements into a string + */ + template + inline string + materialise (II & ii) + { + std::ostringstream buff; + while (ii) + { + buff << *ii; + if (++ii) buff << "-"; + } + return buff.str(); + } } // (END) impl test dummy container @@ -104,10 +194,45 @@ namespace test{ { virtual void - run (Arg arg) + run (Arg) { - verifyChainedIterators (); - verifyComparisons (); + verifyStateAdapter(); + + UNIMPLEMENTED ("IterExplorer Monad"); + verifyChainedIterators(); + verifyRawChainedIterators(); + + verifyDepthFirstExploration(); + verifyBreadthFirstExploration(); + } + + + + /** @test all of the following IterExplorer flavours are built on top + * of a special iterator adapter, centred at the notion of an iterable + * state element type. The actual iterator just embodies one element + * of this state representation, and typically there is not an hidden + * back-link to some kind of container in charge of the elements yielded + */ + void + verifyStateAdapter () + { + NumberSequence ii = seq(5); + CHECK (!isnil (ii)); + CHECK (0 == *ii); + CHECK (materialise(ii) == "0-1-2-3-4"); + CHECK ( isnil (ii)); + CHECK (!ii); + + VERIFY_ERROR (ITER_EXHAUST, *ii ); + VERIFY_ERROR (ITER_EXHAUST, ++ii ); + + ii = seq(5,8); + CHECK (materialise(ii) == "5-6-7"); + + ii = NIL_Sequence; + CHECK ( isnil (ii)); + CHECK (!ii); } @@ -122,6 +247,7 @@ namespace test{ void verifyChainedIterators () { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 typedef ChainedIters Chain; Chain ci = iter::chain (seq(5),seq(7),seq(9)); @@ -159,6 +285,7 @@ namespace test{ CHECK (0 == *s9); pullOut (s9); CHECK (isnil(s9)); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 } @@ -169,6 +296,7 @@ namespace test{ void verifyRawChainedIterators () { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 typedef LinkedElements IterContainer; typedef IterContainer::const_iterator IterIter; @@ -236,6 +364,7 @@ namespace test{ CHECK (isnil(s5)); CHECK (isnil(s7)); CHECK (isnil(s9)); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 } @@ -276,11 +405,13 @@ namespace test{ void verifyDepthFirstExploration () { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 typedef DepthFirstExplorer DepthFirst; DepthFirst root (seq(1)); NumberSequence explorationResult = root >>= exploreChildren(8); CHECK (materialise(explorationResult) == "1-1-1-1-2-2-3-4-2-3-5-6-4-7-8"); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 } @@ -294,11 +425,13 @@ namespace test{ void verifyBreadthFirstExploration () { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 typedef BreadthFirstExplorer BreadthFirst; BreadthFirst root (seq(1)); NumberSequence explorationResult = root >>= exploreChildren(8); CHECK (materialise(explorationResult) == "1-1-2-1-2-3-4-1-2-3-4-5-6-7-8"); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #892 }