From b5453cc429fb262ec5dd4e9fc4417d420518d550 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 3 Dec 2017 04:24:02 +0100 Subject: [PATCH] TreeExplorer: reimplementation with simpler design - always layer the TreeExplorer (builder) on top of the stack - always intersperse an IterableDecorator in between adjacent layers - consequently... * each layer implementation is now a "state core" * and the source is now always a Lumiera Iterator This greatly simplifies all the type rebindings and avoids the ambiguities in argument converison. Basically now we can always convert down, and we just need to pick the result type of the bound functor. Downside is we have now always an adaptation wrapper in between, but we can assume the compiler is able to optimise such inline accessors away without overhead. --- .../diff/tree-mutator-collection-binding.hpp | 2 +- src/lib/iter-tree-explorer.hpp | 131 ++++-------------- src/lib/meta/trait.hpp | 2 +- tests/library/iter-tree-explorer-test.cpp | 18 +-- wiki/thinkPad.ichthyo.mm | 51 ++++++- 5 files changed, 86 insertions(+), 118 deletions(-) diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index 9b4a5bcc5..138a5854d 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -362,7 +362,7 @@ namespace diff{ { binding_.inject (move(*found)); } - return found; + return bool(found); } else return PAR::findSrc (refSpec); diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 9297f8f42..08c3fedb8 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -164,7 +164,7 @@ namespace lib { IterableDecorator& operator= (IterableDecorator&&) =default; IterableDecorator& operator= (IterableDecorator const&) =default; - operator bool() const { return isValid(); } + explicit operator bool() const { return isValid(); } /* === lumiera forward iterator concept === */ @@ -225,49 +225,6 @@ namespace lib { } }; - - /** @todo WIP 11/17 */ - template - class WrappedIteratorCore - : public IT - { - public: - - template - WrappedIteratorCore (ARGS&& ...init) - : IT(std::forward(init)...) - { } - - WrappedIteratorCore() =default; - WrappedIteratorCore (WrappedIteratorCore&&) =default; - WrappedIteratorCore (WrappedIteratorCore const&) =default; - WrappedIteratorCore& operator= (WrappedIteratorCore&&) =default; - WrappedIteratorCore& operator= (WrappedIteratorCore const&) =default; - - - protected: /* === Iteration control API for IterableDecorator === */ - - friend bool - checkPoint (WrappedIteratorCore const& core) - { - return core.isValid(); - } - - friend typename IT::reference - yield (WrappedIteratorCore const& core) - { - return *core; - } - - friend void - iterNext (WrappedIteratorCore & core) - { - ++core; - } - }; - - - }//(End) namespace iter_explorer : predefined policies and configurations @@ -343,14 +300,12 @@ namespace lib { { using SrcVal = typename CoreYield::value_type; using SrcIter = iter_explorer::IterableDecorator; - using SrcCore = SRC; }; template struct _DecoratorTraits>> { using SrcIter = remove_reference_t; - using SrcCore = iter_explorer::WrappedIteratorCore; using SrcVal = typename SrcIter::value_type; }; @@ -360,7 +315,6 @@ namespace lib { static_assert (not std::is_rvalue_reference::value, "container needs to exist elsewhere during the lifetime of the iteration"); using SrcIter = iter_explorer::StlRange; - using SrcCore = iter_explorer::WrappedIteratorCore; using SrcVal = typename SrcIter::value_type; }; @@ -422,36 +376,17 @@ namespace lib { using FunArgType = remove_reference_t; static_assert (std::is_convertible::value, "the expansion functor must accept the source iterator or state core as parameter"); - test::TypeDebugger guggi; static auto build() { return [](ARG& arg) -> ARG& { return arg; }; } }; /** adapt to a functor, which accepts the value type of the source sequence ("monadic" usage pattern) */ template - struct ArgAccessor - ,is_convertible>>> + struct ArgAccessor>> { static auto build() { return [](auto& iter) { return *iter; }; } }; - /** in a similar way, adapt when the passed source argument is a "state core" ("monadic" usage pattern) */ - template - struct ArgAccessor - ,is_convertible::value_type, Arg>>>> - { -// test::TypeDebugger buggi; - static auto build() { return [](COR const& core) { return yield(core); }; } - }; - - template - struct ArgAccessor - ,std::is_same>>> - { -// test::TypeDebugger muggi; - static auto build() { return [](COR& core) ->SRC& { return static_cast (core); }; } - }; - /** holder for the suitably adapted _expansion functor_ */ struct Functor @@ -501,8 +436,8 @@ namespace lib { class Expander : public SRC { - using SrcIter = typename SRC::SrcIter; - using _Traits = _ExpansionTraits; + static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + using _Traits = _ExpansionTraits; using ExpandFunctor = typename _Traits::Functor; using ResIter = typename _DecoratorTraits::SrcIter; @@ -517,7 +452,7 @@ namespace lib { // inherited default copy operations Expander (SRC&& parentExplorer, FUN&& expandFunctor) - : SRC{move (parentExplorer)} + : SRC{move (parentExplorer)} // NOTE: slicing move to strip TreeExplorer (Builder) , expandChildren_{forward (expandFunctor)} , expansions_{} { } @@ -525,7 +460,7 @@ namespace lib { /** core operation: expand current head element */ Expander& - expand() + expandChildren() { REQUIRE (checkPoint(*this), "attempt to expand an empty explorer"); @@ -581,14 +516,12 @@ namespace lib { /** * */ - template + template class Transformer - : public COR + : public SRC { - - using SrcIter = typename _DecoratorTraits::SrcIter; - - using _Traits = _ExpansionTraits; + static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + using _Traits = _ExpansionTraits; using Res = typename _Traits::Res; using TransformFunctor = typename _Traits::Functor; @@ -606,8 +539,8 @@ namespace lib { Transformer() =default; // inherited default copy operations - Transformer (COR&& parentCore, FUN&& transformFunctor) - : COR{move (parentCore)} + Transformer (SRC&& dataSrc, FUN&& transformFunctor) + : SRC{move (dataSrc)} , trafo_{forward (transformFunctor)} { } @@ -617,7 +550,7 @@ namespace lib { friend bool checkPoint (Transformer const& tx) { - return checkPoint (tx.core()); + return bool(tx.srcIter()); } friend reference @@ -629,13 +562,13 @@ namespace lib { friend void iterNext (Transformer & tx) { - iterNext (tx.core()); + ++ tx.srcIter(); tx.treated_.reset(); } private: - COR& - core() const + SRC& + srcIter() const { return unConst(*this); } @@ -643,8 +576,8 @@ namespace lib { reference invokeTransformation () { - if (not treated_) - treated_ = trafo_(core()); + if (not treated_) // invoke transform function once per src item + treated_ = trafo_(srcIter()); return *treated_; } }; @@ -665,13 +598,13 @@ namespace lib { class TreeExplorer : public SRC { + static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); public: - using SrcIter = SRC; - using value_type = typename SrcIter::value_type; - using reference = typename SrcIter::reference; - using pointer = typename SrcIter::pointer; + using value_type = typename meta::TypeBinding::value_type; + using reference = typename meta::TypeBinding::reference; + using pointer = typename meta::TypeBinding::pointer; /** by default create an empty iterator */ @@ -731,14 +664,10 @@ namespace lib { auto expand (FUN&& expandFunctor) { - using This = typename meta::Strip::TypeReferred; - using SrcIter = typename _DecoratorTraits::SrcIter; - using Value = typename SrcIter::value_type; - using Core = iter_explorer::Expander; + using ResCore = iter_explorer::Expander; + using ResIter = typename _DecoratorTraits::SrcIter; - using ExpandableExplorer = iter_explorer::IterableDecorator; - - return ExpandableExplorer{move(*this), forward(expandFunctor)}; + return TreeExplorer (ResCore {move(*this), forward(expandFunctor)}); } @@ -748,14 +677,10 @@ namespace lib { auto transform (FUN&& transformFunctor) { - using This = typename meta::Strip::TypeReferred; - using SrcCore = typename _DecoratorTraits::SrcCore; - using ResCore = iter_explorer::Transformer; - using Value = typename ResCore::value_type; + using ResCore = iter_explorer::Transformer; + using ResIter = typename _DecoratorTraits::SrcIter; - using TransformedExplorer = iter_explorer::IterableDecorator; - - return TransformedExplorer{move(*this), forward(transformFunctor)}; + return TreeExplorer (ResCore {move(*this), forward(transformFunctor)}); } private: diff --git a/src/lib/meta/trait.hpp b/src/lib/meta/trait.hpp index 57ba9051b..e100a8f14 100644 --- a/src/lib/meta/trait.hpp +++ b/src/lib/meta/trait.hpp @@ -435,7 +435,7 @@ namespace meta { META_DETECT_OPERATOR_INC(); public: - enum{ value = std::is_convertible::value + enum{ value = std::is_constructible::value && HasNested_value_type::value && HasOperator_deref::value && HasOperator_inc::value diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index a87c63292..184820568 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -337,7 +337,6 @@ namespace test{ .expand([](uint j){ return CountDown{j-1}; }) // expand-functor: Val > StateCore ); -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 verify_treeExpandingIterator( treeExplore(CountDown{5}) .expand([](uint j){ return NumberSequence{j-1}; }) // expand-functor: Val > Iter @@ -361,7 +360,6 @@ namespace test{ // test routine called the expansion functor five times CHECK (5 == childBuffer.size()); -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 @@ -372,13 +370,12 @@ namespace test{ .expand([](CountDown const& core){ return CountDown{ yield(core) - 1}; }) // expand-functor: StateCore const& -> StateCore ); -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 verify_treeExpandingIterator( treeExplore(CountDown{5}) .expand([](CountDown core){ return NumberSequence{ yield(core) - 1}; }) // expand-functor: StateCore -> Iter ); -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1118 : GDB Segfault on loading the inferior /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1118 : Generated code works just fine and passes Test though verify_treeExpandingIterator( treeExplore(CountDown{5}) @@ -389,7 +386,6 @@ namespace test{ treeExplore(CountDown{5}) .expand([](auto it){ return decltype(it){ *it - 1}; }) // generic Lambda: Iter -> Iter ); -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1118 : GDB Segfault on loading the inferior #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1118 : GDB Segfault on loading the inferior } @@ -404,13 +400,13 @@ namespace test{ CHECK (4 == *ii); CHECK (0 == ii.depth()); - ii.expand(); + ii.expandChildren(); CHECK (3 == *ii); CHECK (1 == ii.depth()); ++ii; CHECK (2 == *ii); CHECK (1 == ii.depth()); - ii.expand(); + ii.expandChildren(); CHECK (1 == *ii); CHECK (2 == ii.depth()); ++ii; @@ -420,20 +416,20 @@ namespace test{ CHECK (3 == *ii); CHECK (0 == ii.depth()); CHECK (materialise(ii) == "3-2-1"); - ii.expand(); + ii.expandChildren(); CHECK (1 == ii.depth()); CHECK (materialise(ii) == "2-1-2-1"); ++++ii; CHECK (0 == ii.depth()); CHECK (materialise(ii) == "2-1"); - ii.expand(); + ii.expandChildren(); CHECK (1 == ii.depth()); CHECK (materialise(ii) == "1-1"); ++ii; CHECK (0 == ii.depth()); CHECK (1 == *ii); CHECK (materialise(ii) == "1"); - ii.expand(); + ii.expandChildren(); CHECK (isnil (ii)); VERIFY_ERROR (ITER_EXHAUST, *ii ); VERIFY_ERROR (ITER_EXHAUST, ++ii ); @@ -452,6 +448,7 @@ namespace test{ void verify_transformOperation() { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 auto multiply = [](int v){ return 2*v; }; _Fmt embrace{"≺%s≻"}; @@ -524,7 +521,6 @@ namespace test{ ++jj; CHECK (fact == 2*23); CHECK (isnil (jj)); -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index baa5eb4b6..f0dd39e18 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -5344,7 +5344,12 @@ - + + + + + + @@ -5366,6 +5371,43 @@ + + + + + + + + + + + + + + +

+ TreeExplorer per slicing move entfernen +

+ + +
+
+ + + + + + + + + + + + + + + + @@ -5550,7 +5592,8 @@ - + + @@ -5563,6 +5606,10 @@ + + + +