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:
parent
09a263431c
commit
a3a64147c1
3 changed files with 159 additions and 17 deletions
|
|
@ -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)};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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ä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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue