diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 7d7f85cbd..9297f8f42 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -81,6 +81,7 @@ #include "lib/meta/trait.hpp" ////////////////TODO #include "lib/null-value.hpp" ////////////////TODO #include "lib/util.hpp" +#include "lib/test/test-helper.hpp"///////////TODO Bug-o //#include //////////////TODO #include ////////////////TODO @@ -279,6 +280,8 @@ namespace lib { using meta::_Fun; using std::__and_; using std::__not_; + using std::is_convertible; + using std::remove_reference_t; using meta::can_IterForEach; using meta::can_STL_ForEach; @@ -301,6 +304,13 @@ namespace lib { > { }; + template + struct shall_use_StateCore + : __and_<__not_> + ,is_StateCore + > + { }; + template struct shall_use_Lumiera_Iter : __and_ @@ -309,6 +319,18 @@ namespace lib { { }; + /** the _value type_ yielded by a »state core« */ + template + struct CoreYield + { + using Res = remove_reference_t()))>; + + using value_type = typename meta::TypeBinding::value_type; + using reference = typename meta::TypeBinding::reference; + using pointer = typename meta::TypeBinding::pointer; + }; + + /** decide how to adapt and embed the source sequence into the resulting TreeExplorer */ template struct _DecoratorTraits @@ -319,7 +341,7 @@ namespace lib { template struct _DecoratorTraits>> { - using SrcVal = typename std::remove_reference()))>::type; + using SrcVal = typename CoreYield::value_type; using SrcIter = iter_explorer::IterableDecorator; using SrcCore = SRC; }; @@ -327,7 +349,7 @@ namespace lib { template struct _DecoratorTraits>> { - using SrcIter = typename std::remove_reference::type; + using SrcIter = remove_reference_t; using SrcCore = iter_explorer::WrappedIteratorCore; using SrcVal = typename SrcIter::value_type; }; @@ -365,7 +387,7 @@ namespace lib { * 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 + * @tparam IT the source iterator type to apply when attempting to use a generic lambda as functor */ template struct _ExpansionTraits @@ -388,7 +410,7 @@ namespace lib { using Sig = typename FunDetector::Sig; - using Arg = typename _Fun::Args::List::Head; + using Arg = typename _Fun::Args::List::Head; // assuming function with a single argument using Res = typename _Fun::Ret; @@ -397,25 +419,44 @@ namespace lib { template struct ArgAccessor { - using FunArgType = typename std::remove_reference::type; + 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>> + struct ArgAccessor + ,is_convertible>>> { 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 { - function expandFun; + function boundFunction; template Res @@ -423,7 +464,7 @@ namespace lib { { auto accessArg = ArgAccessor::build(); - return expandFun (accessArg (arg)); + return boundFunction (accessArg (arg)); } }; }; @@ -559,6 +600,7 @@ namespace lib { public: using value_type = typename meta::TypeBinding::value_type; using reference = typename meta::TypeBinding::reference; + using pointer = typename meta::TypeBinding::pointer; Transformer() =default; @@ -581,7 +623,7 @@ namespace lib { friend reference yield (Transformer const& tx) { - return tx.invokeTransformation(); + return unConst(tx).invokeTransformation(); } friend void @@ -599,10 +641,10 @@ namespace lib { } reference - invokeTransformation () const + invokeTransformation () { if (not treated_) - treated_ = trafo_(yield (core())); + treated_ = trafo_(core()); return *treated_; } }; diff --git a/tests/library/iter-tree-explorer-test.cpp b/tests/library/iter-tree-explorer-test.cpp index fea6cd5ae..a87c63292 100644 --- a/tests/library/iter-tree-explorer-test.cpp +++ b/tests/library/iter-tree-explorer-test.cpp @@ -337,6 +337,7 @@ 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 @@ -360,6 +361,7 @@ namespace test{ // test routine called the expansion functor five times CHECK (5 == childBuffer.size()); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 @@ -370,12 +372,13 @@ 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}) @@ -386,6 +389,7 @@ 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 } @@ -451,10 +455,9 @@ namespace test{ auto multiply = [](int v){ return 2*v; }; _Fmt embrace{"≺%s≻"}; - auto formatify = [&](auto it){ return embrace % *it; }; + auto formatify = [&](auto it){ return string{embrace % *it}; }; -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888 auto ii = treeExplore (CountDown{7,4}) .transform(multiply) ; @@ -473,17 +476,17 @@ namespace test{ vector numz{1,-2,3,-5,8,-13}; cout << materialise (treeExplore(numz) - .transform(formatify)); + .transform(formatify)) < - + + + + + + + + + - + @@ -5382,8 +5390,7 @@ Dem ist nicht so, ab dem Moment, wo wir mehrere Decorator-Layer haben!!

- -
+
@@ -5408,7 +5415,185 @@ - + + + + + + + + + + + + + + + + + + + + + +

+ Aufrufpunkt: invokeTransformation() +

+ +
+ + + + + +

+ In instantiation of 'lib::{anonymous}::_ExpansionTraits<FUN, SRC>::Res lib::{anonymous}::_ExpansionTraits<FUN, SRC>::Functor::operator()(ARG&) [with ARG = long int; FUN = lib::test::IterTreeExplorer_test::verify_transformOperation()::<lambda(auto:2)>&; SRC = lib::iter_explorer::IterableDecorator<long int, lib::iter_explorer::WrappedIteratorCore<lib::TreeExplorer<lib::iter_explorer::StlRange<std::vector<long int>&> > > >; lib::{anonymous}::_ExpansionTraits<FUN, SRC>::Res = std::basic_string<char>]': +

+

+ +

+

+ src/lib/iter-tree-explorer.hpp:426:50: error: no match for call to '(std::function<std::basic_string<char>(lib::iter_explorer::IterableDecorator<long int, lib::iter_explorer::WrappedIteratorCore<lib::TreeExplorer<lib::iter_explorer::StlRange<std::vector<long int>&> > > >&)>) (long int&)' +

+ +
+ + + + + + + + + + + + + + + + +

+ also IterableDecorator aufgesetzt auf die Core im Transformer +

+ +
+
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+ wir gehen davon aus, +

+

+ daß der Optimizer solche inline-Accessor-Funktionen +

+

+ ohnehin restlos wegoptimieren wird +

+ +
+
+ + + + + + +

+ und zwar in dem Moment, wo man die Layer zusammensetzt. +

+ +
+
+
+ + + + + + + + + + + + + +
+
+ + + + + + + + + + + + +

+ ...denn wenn mal ein Layer "nur" Iterator wäre, +

+

+ dann könnte es eine Kombination geben, die einen solchen Layer übersrpingt +

+ +
+
+ + + + +
+
+
+
@@ -5419,7 +5604,7 @@
- + @@ -5546,6 +5731,10 @@ + + + + @@ -5569,8 +5758,7 @@ versehentlich wurde auch der an std::forward gegeben

- - +
@@ -5585,8 +5773,7 @@ Dazu in NumIter einen explizit tracenden move-ctor eingebaut

- -
+
@@ -5605,8 +5792,7 @@ Deshalb fällt dieses doppelte Problem nicht auf

- - + @@ -21839,8 +22025,7 @@ learned

- - + @@ -21855,8 +22040,7 @@ auf incomplete type achten

- - + @@ -21872,8 +22056,7 @@ mutually dependent templates

- - + @@ -21884,8 +22067,7 @@ kann eines der Templates im Zyklus vorrübergehend als "incomplete" gelten.

- -
+
@@ -21909,8 +22091,7 @@ Konsequenz: man wählt dann z.B. eine subtil falsche Spezialisierung.

- -
+