clean-up: switch the tricky function-closure

This is one of the most problematic headers, because it is highly complex
and comprises tightly interwoven definitions (in functional programming style),
which in turn are used deep within other features.

What concerns me is that this header is very much tangled
and pushes me (as the author) to my mental limits.

And on top of this comes that this code has to deal with intricate aspects
like perfect forwarding, and proper handling of binder instances and
function argument copying (which basically should be left to `std::bind`)

Fortunately, the changes ''for this specific topic'' are transparent:
Type sequences are not used on the API for function closure and composition,
but only as an internal tool to assemble argument tuples used for either
binding or invocation of the resulting (partially closed) function.
This commit is contained in:
Fischlurch 2025-06-04 01:49:07 +02:00
parent 429a7e2339
commit 1a2c2ededa
5 changed files with 158 additions and 113 deletions

View file

@ -14,15 +14,19 @@
/** @file function-closure.hpp
** Partial function application and building a complete function closure.
** This is a addendum to std::bind, to support especially the case when a
** function should be _closed_ over (partially or all) arguments. This implies
** to bind some arguments immediately, while keeping other arguments open to
** be supplied on function invocation.
** Additionally, we allow for composing (chaining) of two functions.
** @warning this header is in a state of transition as of 2/2025, because functionality
** of this kind will certainly needed in future, but with full support for lambdas,
** move-only types and perfect forwarding. A gradual rework has been started, and
** will lead to a complete rewrite of the core functionality eventually, making
** These are features known from functional programming and are here implemented
** based on std::bind, to support especially the case when some arguments of a
** function are known at an earlier stage, and should thus be »baked in«, while
** further arguments will be supplied later, for the actual invocation. This
** implies to _close_ (and thus bind) some arguments immediately, while keeping
** other arguments open to so the result of this operation is again a function,
** albeit with fewer arguments.
** Additionally, we allow for _composing_ (chaining) of two functions.
** @warning this header is in a state of transition as of 6/2025, because functionality
** of this kind will certainly be needed in future, but with full support for lambdas,
** move-only types and perfect forwarding. The current implementation of std::bind
** is already quite optimal regarding this support. A gradual rework has been started,
** and will lead to a complete rewrite of the core functionality eventually, making
** better use of variadic templates and library functions like std::apply, which
** were not available at the time of the first implementation.
**
@ -41,6 +45,8 @@
** function-style front-end, it should be aligned with these standard facilities.
** We might want to retain a simple generic interface especially for binding some
** selected argument, which handles the intricacies of storing the functor.
** @todo 6/25 note however that the full-fledged partial function application is a
** **relevant core feature** and is used in the NodeBuilder (see tuple-closure.hpp).
**
** @see control::CommandDef usage example
** @see function-closure-test.hpp
@ -575,7 +581,7 @@ namespace func{
using Ret = typename _Fun<SIG>::Ret;
using ArgsList = typename Args::List;
using ValList = typename VAL::List;
using ValTypes = typename TyOLD<ValList>::Seq;
using ValTypes = typename TySeq<ValList>::Seq; // reconstruct a type-seq from a type-list
enum { ARG_CNT = count<ArgsList>()
, VAL_CNT = count<ValList>()
@ -587,8 +593,8 @@ namespace func{
using LeftReduced = typename Splice<ArgsList, ValList>::Back;
using RightReduced = typename Splice<ArgsList, ValList, ROFFSET>::Front;
using ArgsL = typename TyOLD<LeftReduced>::Seq;
using ArgsR = typename TyOLD<RightReduced>::Seq;
using ArgsL = typename TySeq<LeftReduced>::Seq;
using ArgsR = typename TySeq<RightReduced>::Seq;
// build a list, where each of the *remaining* arguments is replaced by a placeholder marker
@ -600,8 +606,8 @@ namespace func{
using LeftReplaced = typename Splice<ArgsList, TrailingPlaceholders, VAL_CNT>::List;
using RightReplaced = typename Splice<ArgsList, LeadingPlaceholders, 0 >::List;
using LeftReplacedTypes = typename TyOLD<LeftReplaced>::Seq;
using RightReplacedTypes = typename TyOLD<RightReplaced>::Seq;
using LeftReplacedTypes = typename TySeq<LeftReplaced>::Seq;
using RightReplacedTypes = typename TySeq<RightReplaced>::Seq;
// create a "builder" helper, which accepts exactly the value tuple elements
// and puts them at the right location, while default-constructing the remaining
@ -679,7 +685,7 @@ namespace func{
using Args = typename _Fun<SIG>::Args;
using Ret = typename _Fun<SIG>::Ret;
using ArgsList = typename Args::List;
using ValList = typename TyOLD<X>::List;
using ValList = typename TySeq<X>::List;
enum { ARG_CNT = count<ArgsList>() };
@ -694,8 +700,8 @@ namespace func{
>::List;
using ReducedArgs = typename Append<RemainingFront, RemainingBack>::List;
using PreparedArgTypes = typename TyOLD<PreparedArgs>::Seq;
using RemainingArgs = typename TyOLD<ReducedArgs>::Seq;
using PreparedArgTypes = typename TySeq<PreparedArgs>::Seq;
using RemainingArgs = typename TySeq<ReducedArgs>::Seq;
using ReducedSig = typename BuildFunType<Ret,RemainingArgs>::Sig;
@ -728,16 +734,16 @@ namespace func{
template<typename RET, typename ARG>
struct _Sig
{
typedef typename BuildFunType<RET, ARG>::Sig Type;
typedef TupleApplicator<Type> Applicator;
using Type = typename BuildFunType<RET, ARG>::Sig;
using Applicator = TupleApplicator<Type>;
};
template<typename SIG, typename ARG>
struct _Clo
{
typedef typename _Fun<SIG>::Ret Ret;
typedef typename _Sig<Ret,ARG>::Type Signature;
typedef FunctionClosure<Signature> Type;
using Ret = typename _Fun<SIG>::Ret;
using Signature = typename _Sig<Ret,ARG>::Type;
using Type = FunctionClosure<Signature>;
};
template<typename FUN1, typename FUN2>
@ -844,11 +850,11 @@ namespace func{
*/
template<typename...ARG>
inline
typename _Sig<void, TyOLD<ARG...>>::Applicator
typename _Sig<void, TySeq<ARG...>>::Applicator
tupleApplicator (std::tuple<ARG...>& args)
{
typedef typename _Sig<void,TyOLD<ARG...>>::Type Signature;
return TupleApplicator<Signature> (args);
using Signature = typename _Sig<void,TySeq<ARG...>>::Type;
return TupleApplicator<Signature>{args};
}
@ -859,9 +865,9 @@ namespace func{
typename _Fun<SIG>::Ret
apply (SIG& f, std::tuple<ARG...>& args)
{
typedef typename _Fun<SIG>::Ret Ret; //
typedef typename _Sig<Ret,TyOLD<ARG...>>::Type Signature; // Note: deliberately re-building the Signature Type
return TupleApplicator<Signature> (args) (f); // in order to get better error messages here
using Ret = typename _Fun<SIG>::Ret; //
using Signature = typename _Sig<Ret,TySeq<ARG...>>::Type; // Note: deliberately re-building the Signature Type
return TupleApplicator<Signature>{args} (f); // in order to get better error messages here
}
/** close the given function over all arguments,
@ -871,10 +877,10 @@ namespace func{
* function result. */
template<typename SIG, typename...ARG>
inline
typename _Clo<SIG,TyOLD<ARG...>>::Type
typename _Clo<SIG,TySeq<ARG...>>::Type
closure (SIG& f, std::tuple<ARG...>& args)
{
typedef typename _Clo<SIG,TyOLD<ARG...>>::Type Closure;
using Closure = typename _Clo<SIG,TySeq<ARG...>>::Type;
return Closure (f,args);
}

View file

@ -182,6 +182,8 @@ namespace engine {
* - the Build is completed with the NodeBuilder::build() terminal,
* which generates a \ref Connectivity object, that can be directly
* dropped into the constructor of ProcNode.
* @tparam POL policy to control allocation etc...
* @tparam DAT pattern data structure built during chained NodeBuilder invocations
*/
template<class POL, class DAT = PatternDataAnchor>
class NodeBuilder
@ -325,6 +327,9 @@ namespace engine {
* Nested DSL-Builder context to define a regular media processing Port
* @remark relies on [delegate sub-builder](\ref WeavingBuilder) for
* technical details of data feed and parameter wiring.
* @tparam POL policy (allocation)
* @tparam DAT pattern data (collect results for chained calls)
* @tparam WAB concrete instantiation of the WeavingBuilder delegate
*/
template<class POL, class DAT, class WAB>
class PortBuilder

View file

@ -52,11 +52,11 @@ namespace test {
typedef TyOLD< Num<1>
typedef TySeq< Num<1>
, Num<2>
, Num<3>
>::List List1;
typedef TyOLD< Num<5>
typedef TySeq< Num<5>
, Num<6>
, Num<7>
>::List List2;
@ -98,13 +98,15 @@ namespace test {
* - bind free function to tuple
* - bind functor to tuple
* - build a simple "tuple closure"
* @remark this test is _rather low-level_ and documents the construction
* of the implementation
*/
class FunctionClosure_test : public Test
{
virtual void
run (Arg)
{
check_diagnostics ();
verify_setup();
check_signatureTypeManip();
check_applyFree();
check_applyFunc();
@ -115,11 +117,11 @@ namespace test {
/** verify the test input data
* @see TypeListManipl_test#check_diagnostics()
* for an explanation of the DISPLAY macro
* @see TypeListManipl_test#check_diagnostics() for
* explanation of the DISPLAY and EXPECT macros.
*/
void
check_diagnostics ()
verify_setup()
{
DISPLAY (List1);
DISPLAY (List2);
@ -153,10 +155,10 @@ namespace test {
{
cout << "\t:\n\t: ---Apply---\n";
Tuple<TyOLD<>> tup0 ;
Tuple<TyOLD<int>> tup1 (11);
Tuple<TyOLD<int,int>> tup2 (11,12);
Tuple<TyOLD<int,int,int>> tup3 (11,12,13);
Tuple<TySeq<>> tup0 ;
Tuple<TySeq<int>> tup1 (11);
Tuple<TySeq<int,int>> tup2 (11,12);
Tuple<TySeq<int,int,int>> tup3 (11,12,13);
DUMPVAL (tup0);
DUMPVAL (tup1);
DUMPVAL (tup2);
@ -183,10 +185,10 @@ namespace test {
void
check_applyFunc ()
{
Tuple<TyOLD<>> tup0 ;
Tuple<TyOLD<int>> tup1 (11);
Tuple<TyOLD<int,int>> tup2 (11,12);
Tuple<TyOLD<int,int,int>> tup3 (11,12,13);
Tuple<TySeq<>> tup0 ;
Tuple<TySeq<int>> tup1 (11);
Tuple<TySeq<int,int>> tup2 (11,12);
Tuple<TySeq<int,int,int>> tup3 (11,12,13);
function<int()> functor0 (fun0);
function<int(int)> functor1 (fun1);
function<int(int,int)> functor2 (fun2);
@ -215,10 +217,10 @@ namespace test {
{
cout << "\t:\n\t: ---Bind----\n";
Tuple<TyOLD<>> tup0 ;
Tuple<TyOLD<int>> tup1 (11);
Tuple<TyOLD<int,int>> tup2 (11,12);
Tuple<TyOLD<int,int,int>> tup3 (11,12,13);
Tuple<TySeq<>> tup0 ;
Tuple<TySeq<int>> tup1 (11);
Tuple<TySeq<int,int>> tup2 (11,12);
Tuple<TySeq<int,int,int>> tup3 (11,12,13);
typedef function<int()> BoundFun;
@ -248,10 +250,10 @@ namespace test {
void
check_bindFunc ()
{
Tuple<TyOLD<>> tup0 ;
Tuple<TyOLD<int>> tup1 (11);
Tuple<TyOLD<int,int>> tup2 (11,12);
Tuple<TyOLD<int,int,int>> tup3 (11,12,13);
Tuple<TySeq<>> tup0 ;
Tuple<TySeq<int>> tup1 (11);
Tuple<TySeq<int,int>> tup2 (11,12);
Tuple<TySeq<int,int,int>> tup3 (11,12,13);
function<int()> unbound_functor0 (fun0);
function<int(int)> unbound_functor1 (fun1);
function<int(int,int)> unbound_functor2 (fun2);
@ -285,10 +287,10 @@ namespace test {
void
build_closure ()
{
Tuple<TyOLD<>> tup0 ;
Tuple<TyOLD<int>> tup1 (11);
Tuple<TyOLD<int,int>> tup2 (11,12);
Tuple<TyOLD<int,int,int>> tup3 (11,12,13);
Tuple<TySeq<>> tup0 ;
Tuple<TySeq<int>> tup1 (11);
Tuple<TySeq<int,int>> tup2 (11,12);
Tuple<TySeq<int,int,int>> tup3 (11,12,13);
FunctionClosure<int()> clo0 (fun0,tup0);
FunctionClosure<int(int)> clo1 (fun1,tup1);
@ -327,7 +329,7 @@ namespace test {
// finally combine all techniques....
using NumberzArg = TyOLD<List2>::Seq;
using NumberzArg = TySeq<List2>::Seq;
using NumberzSig = BuildFunType<int,NumberzArg>::Sig;
Tuple<NumberzArg> numberzTup (Num<5>(22), Num<6>(33), Num<7>(44));

View file

@ -173,7 +173,7 @@ namespace test {
typedef Num<1> Sig123(Num<1>, Num<2>, Num<3>); // signature of the original function
typedef Num<1> Sig23(Num<2>, Num<3>); // signature after having closed over the first argument
typedef function<Sig23> F23; // and a std::function object to hold such a function
using F23 = function<Sig23>; // and a std::function object to hold such a function
Sig123& f = fun13<1,2,3>; // the actual input: a reference to the bare function
@ -200,8 +200,8 @@ namespace test {
// Version2: extract the binding arguments from a tuple--- //
using PartialArg = Tuple<TyOLD<Num<1>, PH1, PH2>>; // Tuple type to hold the binding values. Note the placeholder types
PartialArg arg(num18, PH1(), PH2()); // Value for partial application (the placeholders are default constructed)
using PartialArg = Tuple<TySeq<Num<1>, PH1, PH2>>; // Tuple type to hold the binding values. Note the placeholder types
PartialArg arg{num18, PH1(), PH2()}; // Value for partial application (the placeholders are default constructed)
fun_23 = std::bind (f, get<0>(arg) // now extract the values to bind from this tuple
, get<1>(arg)
@ -216,8 +216,8 @@ namespace test {
// Version3: let the PApply-template do the work for us--- //
typedef TyOLD<Num<1>> ArgTypes; // now package just the argument(s) to be applied into a tuple
Tuple<ArgTypes> args_to_bind (Num<1>(18));
using ArgTypes = TySeq<Num<1>>; // now package just the argument(s) to be applied into a tuple
Tuple<ArgTypes> args_to_bind{Num<1>(18)};
fun_23 = PApply<Sig123, ArgTypes>::bindFront (f , args_to_bind);
// "bindFront" will close the parameters starting from left....
@ -241,12 +241,12 @@ namespace test {
// what follows is the real unit test...
function<Sig123> func123 (f); // alternatively do it with an std::function object
function<Sig123> func123{f}; // alternatively do it with an std::function object
fun_23 = func::applyFirst (func123, Num<1>(19));
res = fun_23(_2_,_3_).o_;
CHECK (24 == res);
typedef function<Num<1>(Num<1>, Num<2>)> F12;
using F12 = function<Num<1>(Num<1>, Num<2>)>;
F12 fun_12 = func::applyLast (f, Num<3>(20)); // close the *last* argument of a function
res = fun_12(_1_,_2_).o_;
CHECK (23 == res);
@ -279,11 +279,11 @@ namespace test {
// covering the general case of partial function closure:
typedef Num<5> Sig54321 (Num<5>, Num<4>, Num<3>, Num<2>, Num<1>); // Signature of the 5-argument function
typedef Num<5> Sig54 (Num<5>, Num<4>); // ...closing the last 3 arguments should yield this 2-argument function
typedef TyOLD<Num<3>,Num<2>,Num<1>> Args2Close; // Tuple type to hold the 3 argument values used for the closure
using Args2Close = TyOLD<Num<3>, Num<2>, Num<1>>; // Tuple type to hold the 3 argument values used for the closure
// Close the trailing 3 arguments of the 5-argument function...
function<Sig54> fun_54 = PApply<Sig54321, Args2Close>::bindBack(fun15<5,4,3,2,1>,
make_tuple(_3_,_2_,_1_)
function<Sig54> fun_54 = PApply<Sig54321,Args2Close>::bindBack (fun15<5,4,3,2,1>
,make_tuple (_3_,_2_,_1_)
);
// apply the remaining argument values

View file

@ -58636,11 +58636,11 @@
</node>
<node CREATED="1739743156265" ID="ID_221325784" MODIFIED="1739743198704" TEXT="&#xdc;bergang per alternativer Definition: Types&lt;...&gt; vs TySeq&lt;...&gt;"/>
<node CREATED="1739743142166" ID="ID_1562037968" MODIFIED="1739743153038" TEXT="schrittweise kompatibel machen und schwenken">
<node COLOR="#338800" CREATED="1739743226160" ID="ID_490359788" MODIFIED="1739743238719" TEXT="_Fun&lt;SIG&gt; liefert nun variadic-sequence">
<node COLOR="#338800" CREATED="1739743226160" ID="ID_490359788" MODIFIED="1748990717720" TEXT="_Fun&lt;SIG&gt; liefert nun variadic-sequence">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1739743240214" ID="ID_1756740911" MODIFIED="1739743248263" TEXT="geplant: Namen austauschen">
<icon BUILTIN="hourglass"/>
<node BACKGROUND_COLOR="#d2ccaf" COLOR="#5c4d6e" CREATED="1739743240214" ID="ID_1756740911" MODIFIED="1748990676800" TEXT="Idee f&#xfc;r schrittweise migration: Namen austauschen">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1748826315559" ID="ID_575940847" MODIFIED="1748826459126" TEXT="gehe das Thema jetzt vor C++20 an">
<arrowlink COLOR="#4c5dd7" DESTINATION="ID_358783348" ENDARROW="Default" ENDINCLINATION="-1131;-56;" ID="Arrow_ID_470275962" STARTARROW="None" STARTINCLINATION="-4286;314;"/>
@ -106148,7 +106148,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1739242327059" FOLDED="true" ID="ID_1669934372" MODIFIED="1739907809832" TEXT="Adapter zum Binden bestimmter Argumente im Node-Builder generieren">
<node COLOR="#435e98" CREATED="1739242327059" ID="ID_1669934372" MODIFIED="1748990571547" TEXT="Adapter zum Binden bestimmter Argumente im Node-Builder generieren">
<icon BUILTIN="full-3"/>
<node COLOR="#435e98" CREATED="1739549014719" ID="ID_1456986239" MODIFIED="1739901513065" TEXT="Design-Frage: wie weit ausarbeiten?">
<node CREATED="1739549031081" ID="ID_1258607359" MODIFIED="1739890680031" TEXT="minimal-L&#xf6;sung: gar nix bieten &#x2014; User soll &#x3bb; bauen">
@ -106305,7 +106305,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1739582050928" FOLDED="true" ID="ID_1634640852" MODIFIED="1739907799729" TEXT="also mal im Test-Setup beispielhaft ausarbeiten">
<node COLOR="#435e98" CREATED="1739582050928" ID="ID_1634640852" MODIFIED="1748990607692" TEXT="also mal im Test-Setup beispielhaft ausarbeiten">
<linktarget COLOR="#4936b3" DESTINATION="ID_1634640852" ENDARROW="Default" ENDINCLINATION="82;-233;" ID="Arrow_ID_40372708" SOURCE="ID_1709833697" STARTARROW="None" STARTINCLINATION="-287;31;"/>
<icon BUILTIN="yes"/>
<node CREATED="1739644403194" ID="ID_1724825463" MODIFIED="1739644431815" TEXT="Beispiel-Funktion nimmt ein Array mit 5 Parametern"/>
@ -106460,7 +106460,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<node COLOR="#338800" CREATED="1739742027076" ID="ID_1345350905" MODIFIED="1739834260054" TEXT="schrittweise verallgemeinern">
<arrowlink COLOR="#29d01f" DESTINATION="ID_116229103" ENDARROW="Default" ENDINCLINATION="73;-65;" ID="Arrow_ID_1782513655" STARTARROW="None" STARTINCLINATION="-195;18;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1739742051151" FOLDED="true" ID="ID_240638029" MODIFIED="1739890549558" TEXT="Hindernis wegr&#xe4;umen: trailing NullType in Typsequenz der Funktions-Argumente">
<node COLOR="#338800" CREATED="1739742051151" ID="ID_240638029" MODIFIED="1748990610930" TEXT="Hindernis wegr&#xe4;umen: trailing NullType in Typsequenz der Funktions-Argumente">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#e6e1bd" CREATED="1739742093416" ID="ID_74503597" LINK="#ID_490359788" MODIFIED="1739743326711" TEXT="zugleich ein wichtiger Schritt f&#xfc;r #987">
<icon BUILTIN="idea"/>
@ -164240,9 +164240,7 @@ Since then others have made contributions, see the log for the history.</font></
<node COLOR="#435e98" CREATED="1748828247849" ID="ID_476644412" MODIFIED="1748869713383" TEXT="Verbindung mit Typelisten">
<node COLOR="#338800" CREATED="1749001830758" ID="ID_91346918" MODIFIED="1749007560980" TEXT="eigenst&#xe4;ndige Konstruktion von Type-Listen hinzuf&#xfc;gen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
bisher wurde das durch Delegieren an die alte Loki-Implementierung bewerkstelligt; das nun direkt auf der Basis von Variadics zu machen, w&#228;re der zentrale Schritt, der das neue &#214;kosystem der variadischen Typlisten autonom macht (so da&#223; man am Ende die alte nicht-variadische Definition entfernen kann)
@ -164257,9 +164255,7 @@ Since then others have made contributions, see the log for the history.</font></
<arrowlink DESTINATION="ID_281104576" ENDARROW="Default" ENDINCLINATION="589;-82;" ID="Arrow_ID_351374746" STARTARROW="None" STARTINCLINATION="458;41;"/>
<node CREATED="1748828416378" ID="ID_1994646495" MODIFIED="1748869656471" TEXT="es gibt eine Spezialisierung von TyOLD">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
in typeseq-util (etwas versteckt zwischen den Spezialisierungen von Prepend, was wiederum Vorraussetzung ist, so einen R&#252;ckweg konstruieren zu k&#246;nnen)
@ -164274,9 +164270,7 @@ Since then others have made contributions, see the log for the history.</font></
</node>
<node COLOR="#338800" CREATED="1748828579825" ID="ID_873142911" MODIFIED="1748900607872" TEXT="typelist-manip ist v&#xf6;llig eigenst&#xe4;ndig">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
d.h arbeitet ausschlie&#223;lich auf Typlisten und bezieht sich nirgends auf Typ-Sequenzen
@ -164297,9 +164291,7 @@ Since then others have made contributions, see the log for the history.</font></
<node COLOR="#435e98" CREATED="1748828754106" ID="ID_138237629" MODIFIED="1749003967494" TEXT="typelist-diagnostic ebenso">
<node CREATED="1748828767089" ID="ID_1047311703" MODIFIED="1748828818895" TEXT="meta::is_Typelist ist geschickt definiert">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
es stellt n&#228;mllich nur auf einen nested&#160;&#160;X::List ab
@ -164327,23 +164319,54 @@ Since then others have made contributions, see the log for the history.</font></
<node COLOR="#435e98" CREATED="1748829095135" ID="ID_1295682918" MODIFIED="1749007403090" TEXT="Funktionen">
<node COLOR="#435e98" CREATED="1748829099022" ID="ID_766756688" MODIFIED="1749007398648" TEXT="Signatur-Utils">
<node CREATED="1748829959670" ID="ID_1188075291" MODIFIED="1748829968228" TEXT="sind bereits mit beiden kompatibel"/>
<node COLOR="#374933" CREATED="1748990516282" ID="ID_1244770313" LINK="#ID_490359788" MODIFIED="1748990753597" TEXT="Typ der Argumentliste wird als variadische Sequenz geliefert">
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1748829102455" ID="ID_1254282139" MODIFIED="1749007395415" TEXT="Closure">
<icon BUILTIN="button_ok"/>
<node CREATED="1748829838133" ID="ID_1933174501" MODIFIED="1748995159628" TEXT="wenige wichtige Verwendungen">
<node CREATED="1748829860803" ID="ID_517247632" MODIFIED="1748829863739" TEXT="Commands"/>
<node CREATED="1748829872320" ID="ID_568804131" MODIFIED="1748829875428" TEXT="Random-Draw"/>
<node CREATED="1748829881837" ID="ID_1354679657" MODIFIED="1748829885400" TEXT="tuple-closure"/>
<node CREATED="1748829881837" ID="ID_1354679657" MODIFIED="1748829885400" TEXT="tuple-closure">
<node CREATED="1748994867978" ID="ID_233227122" MODIFIED="1748994877591" TEXT="NodeBuilder">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1748994962147" ID="ID_1390459320" MODIFIED="1748995118216" TEXT="volles Feature">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
das ist m.W. der einzige Use-Case, der das <i>vollst&#228;ndige Feature</i>&#160; der partiellen Funktions-Closure mit N argumenten verwendet; meist wird nur der einfache convenience-Fall mit dem ersten oder letzten Argument genommen. Das bedeutet, hier wird auch eine Typ-Sequenz generiert, und daraus ein Tupel... (und da ich dieses Feature erst 2025 entwickelt habe, arbeitet es bereits ausschlie&#223;lich mit den neuen variadischen Sequenzen)
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1748829890844" ID="ID_1803577911" MODIFIED="1748829894782" TEXT="view-spec-dsl"/>
</node>
<node CREATED="1749007506535" ID="ID_240022720" MODIFIED="1749007506535" TEXT="mu&#xdf; auf einen Schlag geschwenkt werden (Komplexit&#xe4;t)"/
<node CREATED="1748992492455" ID="ID_240022720" MODIFIED="1748992513597" TEXT="mu&#xdf; auf einen Schlag geschwenkt werden (Komplexit&#xe4;t)">
<arrowlink DESTINATION="ID_142039126" ENDARROW="Default" ENDINCLINATION="726;0;" ID="Arrow_ID_535671141" STARTARROW="None" STARTINCLINATION="726;0;"/>
<arrowlink DESTINATION="ID_1545630215" ENDARROW="Default" ENDINCLINATION="741;0;" ID="Arrow_ID_1949399206" STARTARROW="None" STARTINCLINATION="741;0;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1748829733384" ID="ID_83679265" MODIFIED="1748829744922" TEXT="sollte sich bereits ohne weiteres schwenken lassen"/>
<node CREATED="1748829745682" ID="ID_61352432" MODIFIED="1748829759664" TEXT="erzeugt nur Tuple, oder macht Split / Prepend"/>
<node CREATED="1748829779637" ID="ID_1158113558" MODIFIED="1748829835939" TEXT="man k&#xf6;nnte dann im Nachgang die Apply-Definition eliminieren">
<node CREATED="1748829745682" ID="ID_61352432" MODIFIED="1748829759664" TEXT="erzeugt nur Tuple, oder macht Split / Prepend">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1749000930632" ID="ID_858022461" MODIFIED="1749001079813" TEXT="Vorsicht Types&lt;List&gt;::Seq">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Das sieht auf den ersten Blick d&#228;mlich aus, aber vorsicht, der Template-Parameter ist kein Variadic, sondern eine Loki-Liste; damit greift hier eine Spezialisierung, die im Header typeseq-util.hpp definiert ist: die variadische Sequenz wird eigens per Prepend&lt;...&gt; wieder aufgebaut... (hab lange gebraucht bist ich das geschnallt habe)
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1748992588450" ID="ID_262144930" MODIFIED="1748992602312" TEXT="Typ-Sequenzen treten nur intern auf, nicht auf dem API"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1748829779637" ID="ID_1158113558" MODIFIED="1749001112944" TEXT="man k&#xf6;nnte dann im Nachgang die Apply-Definition eliminieren">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...aber nur wenn's einfach geht; eigentlich ist das au&#223;erhalb vom Scope und k&#246;nnte auch sp&#228;ter mal gemacht werden (ist nur ein Implementierungsdetail), sofern die bestehende Impl mit den neuen Typlisten arbeitet
@ -164351,6 +164374,7 @@ Since then others have made contributions, see the log for the history.</font></
</body>
</html>
</richcontent>
<icon BUILTIN="hourglass"/>
</node>
</node>
</node>
@ -164409,8 +164433,16 @@ Since then others have made contributions, see the log for the history.</font></
<node CREATED="1748829442778" MODIFIED="1748829442778" TEXT="HandlingPatternBasics_test"/>
<node CREATED="1748829453011" MODIFIED="1748829453011" TEXT="BuilderTool_test"/>
<node CREATED="1748829468217" MODIFIED="1748829468217" TEXT="SessionServiceAccess_test"/>
<node CREATED="1748829480048" MODIFIED="1748829480048" TEXT="FunctionClosure_test"/>
<node CREATED="1748829502213" MODIFIED="1748829502213" TEXT="FunctionComposition_test"/>
<node COLOR="#435e98" CREATED="1748829480048" ID="ID_142039126" MODIFIED="1749007517616" TEXT="FunctionClosure_test">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_142039126" ENDARROW="Default" ENDINCLINATION="726;0;" ID="Arrow_ID_535671141" SOURCE="ID_240022720" STARTARROW="None" STARTINCLINATION="726;0;"/>
</node>
<node COLOR="#435e98" CREATED="1748829502213" ID="ID_1545630215" MODIFIED="1749007517616" TEXT="FunctionComposition_test">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1545630215" ENDARROW="Default" ENDINCLINATION="741;0;" ID="Arrow_ID_1949399206" SOURCE="ID_240022720" STARTARROW="None" STARTINCLINATION="741;0;"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#cd016f" CREATED="1748993653112" ID="ID_1058696109" MODIFIED="1748993677622" TEXT="Stackoverflow in Eclipse">
<font NAME="SansSerif" SIZE="10"/>
<icon BUILTIN="smiley-angry"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1748829512571" ID="ID_1542151497" MODIFIED="1749007468620" TEXT="GeneratorCombinations_test"/>
<node COLOR="#435e98" CREATED="1748829523737" ID="ID_803058969" MODIFIED="1748883754992" TEXT="TypeListGenerator_test">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_803058969" ENDARROW="Default" ENDINCLINATION="852;0;" ID="Arrow_ID_1971292758" SOURCE="ID_511778446" STARTARROW="None" STARTINCLINATION="302;17;"/>