diff --git a/research/try.cpp b/research/try.cpp index 41a5fefbe..7792e4308 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -128,6 +128,10 @@ main (int, char**) show(); show(); + SHOW_EXPR(bool(std::is_integral_v)) + SHOW_EXPR(bool(std::is_integral_v)) + SHOW_EXPR(bool(std::is_integral_v)) + cout << "\n.gulp." < using lib::test::showSizeof; using util::toString; +using util::_Fmt; +using std::is_same_v; +using std::make_tuple; using std::get; namespace lib { @@ -57,7 +62,88 @@ namespace test { } // (End) test data +////////////////////////////////////////OOO + template + class WithIdxSeq2 + { + template + static void + invoke_forEach (FUN&& fun, std::index_sequence) + { + (fun (std::integral_constant{}), ...); + } + + template + static bool + and_forEach (FUN&& fun, std::index_sequence) + { + return (fun (std::integral_constant{}) and ...); + } + + template + static bool + or_forEach (FUN&& fun, std::index_sequence) + { + return (fun (std::integral_constant{}) or ...); + } + + using IdxSeq = typename ElmTypes::Idx; + + public: + template + static void + invoke (FUN&& fun) + { + invoke_forEach (std::forward(fun), IdxSeq{}); + } + + template + static bool + andAll (FUN&& fun) + { + return and_forEach (std::forward(fun), IdxSeq{}); + } + + template + static bool + orAny (FUN&& fun) + { + return or_forEach (std::forward(fun), IdxSeq{}); + } + }; + /** + * Invoke a function (or λ) with index numbers derived from some variadic count. + * Notably this construct can be used for compile-time iteration over a structure. + * Instances of `std::integral_constant` are passed in sequence to the functor. + * The _size_ of the index sequence is derived from the following sources + * - if the type \a TTX is _tuple-like,_ then std::tuple_size is used + * - otherwise, if the type is a loki-style type sequence or type list, + * the number of type nodes is used + * - otherwise, as fall-back the number of template parameters is used + */ + template + inline void + forEachIDX2 (FUN&& fun) + { + WithIdxSeq2::invoke (std::forward (fun)); + } + + template + inline bool + andAllIDX2 (FUN&& fun) + { + return WithIdxSeq2::andAll (std::forward (fun)); + } + + template + inline bool + orAnyIDX2 (FUN&& fun) + { + return WithIdxSeq2::orAny (std::forward (fun)); + } + +////////////////////////////////////////OOO /*********************************************************************//** @@ -74,6 +160,7 @@ namespace test { { check_diagnostics(); check_tuple_from_Typelist(); + demonstrate_generic_iteration(); } @@ -162,6 +249,66 @@ namespace test { CHECK (sizeof(prep) == sizeof(int)+sizeof(Num<1>)+sizeof(Num<3>)+sizeof(Num<5>)); } + + + /** @test demonstrate generic tuple iteration mechanisms + * - apply a generic lambda to each element of a tuple + * - iterate over all index numbers of a tuple (or tuple-like) + * @remark the _iteration_ happens at compile-time, i.e. the given + * lambda-template is instantiated for each type of the tuple; + * however, at runtime, each of these instantiations is invoked + * in sequence, performing the body of the λ-function, which may + * access the actual data value for each of the tuple elements. + */ + void + demonstrate_generic_iteration() + { + auto tup = make_tuple (1, 2.3, '4'); + using Tup = decltype(tup); + CHECK (toString(tup) == "«tuple»──(1,2.3,4)"_expect); + + string dump{}; + CHECK (dump == ""); + // apply λ-generic to each element... + forEach (tup, [&](auto elm){ dump += "|"+toString(elm); }); + CHECK (dump == "|1|2.3|4"_expect); + + // apply λ-generic to each element and build new tuple from results + auto tupStr = mapEach (tup, [](auto const& elm){ return toString(elm); }); + CHECK (tupStr == "«tuple»──(1,2.3,4)"_expect); + + _Fmt showElm{"|%d|▷%s◁"}; + dump = ""; + // apply λ-generic with (constexpr) index + forEachIDX2 ([&](auto idx) + { + using Idx = decltype(idx); + using Iii = std::integral_constant; + CHECK ((is_same_v)); + dump += showElm % uint(idx) % get(tup); + }); + CHECK (dump == "|0|▷1◁|1|▷2.3◁|2|▷4◁"_expect); + + + // apply λ-generic and combine results + auto boolFun = [&](auto idx){ return bool(get(tup)); }; + + CHECK ( andAllIDX2 (boolFun)); + get<0>(tup) = 0; // ◁————————————————————— demonstrate that a run-time evaluation happens + CHECK (not andAllIDX2 (boolFun)); + CHECK ( orAnyIDX2 (boolFun)); + + // can use this mechanism also for sole compile-time computation + auto integralCheckFun = [](auto idx){ return std::is_integral_v>;}; + + CHECK (not andAllIDX2 (integralCheckFun)); + CHECK ( orAnyIDX2 (integralCheckFun)); + + // Note however, the same can also be achieved simpler, + // using any meta-function which takes a single type argument... + CHECK (not ElmTypes::AndAll()); // ... __and_,is_integral,is_integral> + CHECK ( ElmTypes::OrAll()); + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a89710b62..6690baded 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -166216,8 +166216,7 @@ Since then others have made contributions, see the log for the history. - - + @@ -166253,8 +166252,78 @@ Since then others have made contributions, see the log for the history. - - + + + + + + + + +

+ in der FeedManifold (spielt dort aber eine essentielle Rolle, weil nur auf diesem Weg die völlige Flexibilität in allen Argumenten erreicht wird) +

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

+ ElmTypes<TUP>::Tup macht ein variadic rebind von einer Typ-Sequenz in ein std::tuple +

+ + +
+
+ + + + + + +

+ ...das bedeutet, der Fall einer reinen Loki-Typliste fällt erst mal weg (wird ja derzeit nicht verwendet), und der sonderbare »fallback« ändert nun sein Veralten und würde zu einem 1-Tupel. Dafür kann die gesamte constexpr-if-Logik wegfallen, weil ElmTypes<Tup> bereits eine Index-Sequenz fertig bereitstellt. +

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

+ siehe Entdeckung, die ich im Test dokumentiert habe: eine reine Compile-Time evaluation kann man zwar so machen, das wäre aber von hinten durch die Brust ins Auge... +

+ + +
+ +
+ + + + + + + + @@ -166346,8 +166415,7 @@ Since then others have made contributions, see the log for the history. - - + @@ -166368,8 +166436,7 @@ Since then others have made contributions, see the log for the history.sehr spezieller Compiler-Bug

- - +