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
This commit is contained in:
Fischlurch 2017-11-30 03:52:32 +01:00
parent 09a263431c
commit a3a64147c1
3 changed files with 159 additions and 17 deletions

View file

@ -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 IT>
class WrappedIteratorCore
: public IT
{
public:
template<typename...ARGS>
WrappedIteratorCore (ARGS&& ...init)
: IT(std::forward<ARGS>(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<class SRC, typename SEL=void>
struct _TreeExplorerTraits
struct _DecoratorTraits
{
static_assert (!sizeof(SRC), "Can not build TreeExplorer: Unable to figure out how to iterate the given SRC type.");
};
template<class SRC>
struct _TreeExplorerTraits<SRC, enable_if<is_StateCore<SRC>>>
struct _DecoratorTraits<SRC, enable_if<is_StateCore<SRC>>>
{
using SrcVal = typename std::remove_reference<decltype(yield (std::declval<SRC>()))>::type;
using SrcIter = iter_explorer::IterableDecorator<SrcVal, SRC>;
using SrcCore = SRC;
};
template<class SRC>
struct _TreeExplorerTraits<SRC, enable_if<shall_use_Lumiera_Iter<SRC>>>
struct _DecoratorTraits<SRC, enable_if<shall_use_Lumiera_Iter<SRC>>>
{
using SrcIter = typename std::remove_reference<SRC>::type;
using SrcCore = iter_explorer::WrappedIteratorCore<SRC>;
using SrcVal = typename SrcIter::value_type;
};
template<class SRC>
struct _TreeExplorerTraits<SRC, enable_if<shall_wrap_STL_Iter<SRC>>>
struct _DecoratorTraits<SRC, enable_if<shall_wrap_STL_Iter<SRC>>>
{
static_assert (not std::is_rvalue_reference<SRC>::value,
"container needs to exist elsewhere during the lifetime of the iteration");
using SrcIter = iter_explorer::StlRange<SRC>;
using SrcCore = iter_explorer::WrappedIteratorCore<SrcIter>;
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<class FUN, typename SRC>
struct _ExpansionTraits
@ -341,10 +391,6 @@ namespace lib {
using Arg = typename _Fun<Sig>::Args::List::Head;
using Res = typename _Fun<Sig>::Ret;
using ResultIter = typename _TreeExplorerTraits<Res>::SrcIter;
static_assert (std::is_convertible<typename ResultIter::value_type, typename SRC::value_type>::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<FUN,SrcIter>;
using ResIter = typename _Traits::ResultIter;
using ExpandFunctor = typename _Traits::Functor;
using ResIter = typename _DecoratorTraits<typename _Traits::Res>::SrcIter;
static_assert (std::is_convertible<typename ResIter::value_type, typename SRC::value_type>::value,
"the iterator from the expansion must yield compatible values");
ExpandFunctor expandChildren_;
IterStack<ResIter> expansions_;
@ -485,6 +534,78 @@ namespace lib {
++tx;
}
};
/**
*
*/
template<class COR, class FUN>
class Transformer
: public COR
{
using SrcIter = typename _DecoratorTraits<COR>::SrcIter;
using _Traits = _ExpansionTraits<FUN,SrcIter>;
using Res = typename _Traits::Res;
using TransformFunctor = typename _Traits::Functor;
using TransformedItem = wrapper::ItemWrapper<Res>;
TransformFunctor trafo_;
TransformedItem treated_;
public:
using value_type = typename iter::TypeBinding<Res>::value_type;
using reference = typename iter::TypeBinding<Res>::reference;
Transformer() =default;
// inherited default copy operations
Transformer (COR&& parentCore, FUN&& transformFunctor)
: COR{move (parentCore)}
, trafo_{forward<FUN> (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<decltype(*this)>::TypeReferred;
using Value = typename This::value_type;
using Core = iter_explorer::Expander<This, FUN>;
using SrcIter = typename _DecoratorTraits<This>::SrcIter;
using Value = typename SrcIter::value_type;
using Core = iter_explorer::Expander<SrcIter, FUN>;
using ExpandableExplorer = iter_explorer::IterableDecorator<Value, Core>;
@ -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<decltype(*this)>::TypeReferred;
using SrcCore = typename _DecoratorTraits<This>::SrcCore;
using ResCore = iter_explorer::Transformer<SrcCore, FUN>;
using Value = typename ResCore::value_type;
using TransformedExplorer = iter_explorer::IterableDecorator<Value, ResCore>;
return TransformedExplorer{move(*this), forward<FUN>(transformFunctor)};
}
private:
@ -624,7 +752,7 @@ namespace lib {
inline auto
treeExplore (IT&& srcSeq)
{
using SrcIter = typename _TreeExplorerTraits<IT>::SrcIter;
using SrcIter = typename _DecoratorTraits<IT>::SrcIter;
return TreeExplorer<SrcIter> {std::forward<IT>(srcSeq)};
}

View file

@ -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
}

View file

@ -5353,17 +5353,29 @@
<node CREATED="1511831773833" ID="ID_1367782989" MODIFIED="1511831783948" TEXT="IterableDecorator wegstrippen"/>
<node CREATED="1511831784823" ID="ID_764863277" MODIFIED="1511831794354" TEXT="Core direkt verwenden (slicing move)"/>
</node>
<node CREATED="1511831840336" ID="ID_1853594905" MODIFIED="1511831848587" TEXT="Pareint == Lumiera Iterator ">
<node CREATED="1511831840336" ID="ID_1853594905" MODIFIED="1511919879308" TEXT="Parent == Lumiera Iterator ">
<node CREATED="1511831893369" ID="ID_1403568713" MODIFIED="1511837159071" TEXT="WrappedIteratorCore dazwischenschieben"/>
</node>
<node CREATED="1511831940346" ID="ID_441709942" MODIFIED="1511831960963" TEXT="Resultat: Parent ist stets state-core"/>
</node>
<node CREATED="1511918986936" ID="ID_667088953" MODIFIED="1511918989357" TEXT="Konstrukt">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1511919003054" ID="ID_1728459315" MODIFIED="1511919013829" TEXT="Aufsetz-Punkt">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1511919032171" ID="ID_737737817" MODIFIED="1511919043219" TEXT="Problem Parent::Iterator">
<node CREATED="1511919050960" ID="ID_1621131204" MODIFIED="1511919070801" TEXT="grunds&#xe4;tzliches Problem jedes Dekorators"/>
<node CREATED="1511920447698" ID="ID_1780310210" MODIFIED="1511920468027" TEXT="gesucht: der Iterator, von dem wir Werte beziehen"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1511837060201" ID="ID_88038793" MODIFIED="1511837165852" TEXT="brauche WrappedIteratorCore">
<icon BUILTIN="flag-pink"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1511837027405" ID="ID_233806852" MODIFIED="1511837172811" TEXT="Argument-Detektor-Magie">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1511837039180" ID="ID_1296099637" MODIFIED="1511837047198" TEXT="ganz analog zur expand-Operation"/>
<node CREATED="1511837047810" ID="ID_684902103" MODIFIED="1511837057125" TEXT="kann man die Traits wiederverwenden?"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1511837060201" ID="ID_88038793" MODIFIED="1511837165852" TEXT="brauche WrappedIteratorCore">
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1512007357412" ID="ID_1659237225" MODIFIED="1512007370940" TEXT="was bedeutet ein generisches Lambda?">
<icon BUILTIN="help"/>
</node>
</node>
</node>
</node>