From a3a64147c1ff2d65252374a35a28e6dba69c88c0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 30 Nov 2017 03:52:32 +0100 Subject: [PATCH] TreeExplorer: implementation draft for the transform-operation attempt to re-use the same traits as much as possible NOTE: new code not passing compiler yet, but refactored old code does, and still passes unit test --- src/lib/iter-tree-explorer.hpp | 156 ++++++++++++++++++++-- tests/library/iter-tree-explorer-test.cpp | 2 + wiki/thinkPad.ichthyo.mm | 18 ++- 3 files changed, 159 insertions(+), 17 deletions(-) diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 208496faa..9f4b896e6 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -75,6 +75,7 @@ #include "lib/meta/trait.hpp" #include "lib/meta/duck-detector.hpp" #include "lib/meta/function.hpp" +#include "lib/wrapper.hpp" ////////////TODO : could be more lightweight by splitting FunctionResult into separate header. Relevant? #include "lib/iter-adapter.hpp" #include "lib/iter-stack.hpp" #include "lib/meta/trait.hpp" ////////////////TODO @@ -224,6 +225,48 @@ 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 @@ -268,30 +311,35 @@ namespace lib { /** decide how to adapt and embed the source sequence into the resulting TreeExplorer */ template - struct _TreeExplorerTraits + struct _DecoratorTraits { static_assert (!sizeof(SRC), "Can not build TreeExplorer: Unable to figure out how to iterate the given SRC type."); }; template - struct _TreeExplorerTraits>> + struct _DecoratorTraits>> { using SrcVal = typename std::remove_reference()))>::type; using SrcIter = iter_explorer::IterableDecorator; + using SrcCore = SRC; }; template - struct _TreeExplorerTraits>> + struct _DecoratorTraits>> { using SrcIter = typename std::remove_reference::type; + using SrcCore = iter_explorer::WrappedIteratorCore; + using SrcVal = typename SrcIter::value_type; }; template - struct _TreeExplorerTraits>> + struct _DecoratorTraits>> { 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; }; @@ -316,6 +364,8 @@ namespace lib { * keep the argument-accepting front-end still generic (templated `operator()`). This * special adapter supports the case when the _expansion functor_ yields a child sequence * type different but compatible to the original source sequence embedded in TreeExplorer. + * @tparam FUN something _"function-like"_ passed as functor to be bound + * @tparam SRC the source type to apply when attempting to use a generic lambda as functor */ template struct _ExpansionTraits @@ -341,10 +391,6 @@ namespace lib { using Arg = typename _Fun::Args::List::Head; using Res = typename _Fun::Ret; - using ResultIter = typename _TreeExplorerTraits::SrcIter; - - static_assert (std::is_convertible::value, - "the iterator from the expansion must yield compatible values"); /** adapt to a functor, which accesses the source iterator or embedded "state core" */ @@ -416,9 +462,12 @@ namespace lib { { using SrcIter = typename SRC::SrcIter; using _Traits = _ExpansionTraits; - using ResIter = typename _Traits::ResultIter; using ExpandFunctor = typename _Traits::Functor; + using ResIter = typename _DecoratorTraits::SrcIter; + static_assert (std::is_convertible::value, + "the iterator from the expansion must yield compatible values"); + ExpandFunctor expandChildren_; IterStack expansions_; @@ -485,6 +534,78 @@ namespace lib { ++tx; } }; + + + + /** + * + */ + template + class Transformer + : public COR + { + + using SrcIter = typename _DecoratorTraits::SrcIter; + + using _Traits = _ExpansionTraits; + using Res = typename _Traits::Res; + + using TransformFunctor = typename _Traits::Functor; + using TransformedItem = wrapper::ItemWrapper; + + TransformFunctor trafo_; + TransformedItem treated_; + + public: + using value_type = typename iter::TypeBinding::value_type; + using reference = typename iter::TypeBinding::reference; + + + Transformer() =default; + // inherited default copy operations + + Transformer (COR&& parentCore, FUN&& transformFunctor) + : COR{move (parentCore)} + , trafo_{forward (transformFunctor)} + { } + + + protected: /* === Iteration control API for IterableDecorator === */ + + friend bool + checkPoint (Transformer const& tx) + { + return checkPoint (tx.core()); + } + + friend reference + yield (Transformer const& tx) + { + return tx.invokeTransformation(); + } + + friend void + iterNext (Transformer & tx) + { + iterNext (tx.core()); + tx.treated_.reset(); + } + + private: + COR& + core() const + { + return unConst(*this); + } + + reference + invokeTransformation () const + { + if (not treated_) + treated_ = trafo_(yield (core())); + return *treated_; + } + }; } @@ -569,8 +690,9 @@ namespace lib { expand (FUN&& expandFunctor) { using This = typename meta::Strip::TypeReferred; - using Value = typename This::value_type; - using Core = iter_explorer::Expander; + using SrcIter = typename _DecoratorTraits::SrcIter; + using Value = typename SrcIter::value_type; + using Core = iter_explorer::Expander; using ExpandableExplorer = iter_explorer::IterableDecorator; @@ -584,8 +706,14 @@ namespace lib { auto transform (FUN&& transformFunctor) { - TODO ("make the world a better place....(WIP)"); - return *this; // LoLoLoL + using This = typename meta::Strip::TypeReferred; + using SrcCore = typename _DecoratorTraits::SrcCore; + using ResCore = iter_explorer::Transformer; + using Value = typename ResCore::value_type; + + using TransformedExplorer = iter_explorer::IterableDecorator; + + return TransformedExplorer{move(*this), forward(transformFunctor)}; } private: @@ -624,7 +752,7 @@ namespace lib { inline auto treeExplore (IT&& srcSeq) { - using SrcIter = typename _TreeExplorerTraits::SrcIter; + using SrcIter = typename _DecoratorTraits::SrcIter; return TreeExplorer {std::forward(srcSeq)}; } diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index 0d6b1dec0..fea6cd5ae 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -454,6 +454,7 @@ namespace test{ auto formatify = [&](auto it){ return embrace % *it; }; +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 auto ii = treeExplore (CountDown{7,4}) .transform(multiply) ; @@ -520,6 +521,7 @@ namespace test{ ++jj; CHECK (fact == 2*23); CHECK (isnil (jj)); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 74cf7a0e0..f7388e22f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -5353,17 +5353,29 @@ - + + + + + + + + + + + + - - + + +