Library: more aggressive testing with feature combinations

and yes ... this revealed a **long standing bug**

The `Filter::pullFilter()` invocation in the ctor may produce dangling refs,
whenever an underlying source-iterator generates a reference that points
into the iterator itself.

The reason is: due to the »onion shell« design of the iterator pipeline,
we are bound to move a source iterator into the next layer constructor.
This commit is contained in:
Fischlurch 2024-11-23 03:30:07 +01:00
parent 0b487735c2
commit 8d1740418b
4 changed files with 203 additions and 95 deletions

View file

@ -27,16 +27,12 @@
#include "lib/iter-adapter.hpp"
#include "lib/iter-explorer.hpp"
#include "lib/meta/tuple-helper.hpp"
#include "lib/util.hpp"
//#include <deque>
#include <utility>
namespace lib {
// using util::unConst;
namespace iter {
/** construction-helper: apply IterExplorer builder packaged tuple */
@ -71,11 +67,9 @@ namespace lib {
bool
checkPoint() const
{
bool active{true};
meta::forEach (iters_ // optimiser can unroll and short-circuit
,[&](auto& it){ active = active and bool(it); });
return active;
{ //note: short-circuit
return std::apply ([](auto&... its) { return (bool(its) and ...); }
, iters_);
}
ITUP&

View file

@ -356,7 +356,7 @@ return: 0
END
PLANNED "Tuple-zipped iterators" IterZip_test <<END
TEST "Tuple-zipped iterators" IterZip_test <<END
return: 0
END

View file

@ -32,9 +32,8 @@
namespace lib {
namespace test{
// using ::Test;
// using util::isnil;
using util::join;
using util::isnil;
using LERR_(ITER_EXHAUST);
using lib::meta::forEach;
using lib::meta::mapEach;
@ -64,10 +63,6 @@ namespace test{
}
}
/////////////////////////////////////////
/////////////////////////////////////////
#define TYPE(_EXPR_) showType<decltype(_EXPR_)>()
@ -77,7 +72,10 @@ namespace test{
/*********************************************************************************//**
* @test demonstrate construction and verify behaviour of a combined-iterator builder.
* - construction from arbitrary arguments by tuple-mapping a builder function
*
* - defining the operation on the product type by lifting individual operations
* - use the library building blocks to construct a zip-iter-builder
* - iterate a mix of source iterators and containers
* - apply additional processing logic by pipelining
* @see IterExplorer
* @see IterExplorer_test
*/
@ -94,7 +92,7 @@ namespace test{
verify_iteration();
verify_references();
UNIMPLEMENTED ("nebbich.");
verify_pipelining();
}
@ -308,9 +306,72 @@ namespace test{
"«tuple<ulong, uint&, uint&, uint&>»──(2,7,8,9)-"
"«tuple<ulong, uint&, uint&, uint&>»──(3,10,11,12)-"
"«tuple<ulong, uint&, uint&, uint&>»──(4,13,14,15)"_expect);
auto s6 = std::array{1,1,2,3,5,8};
auto s3 = {3,2,1};
auto s0 = eachNum(5u,5u);
CHECK (TYPE(s6) == "array<int, 6ul>"_expect );
CHECK (TYPE(s3) == "initializer_list<int>"_expect );
CHECK (TYPE(s0) == "NumIter<uint>"_expect );
CHECK (materialise (
zip (s6,s6,s6,eachNum('a'))
)
== "«tuple<int&, int&, int&, char>»──(1,1,1,a)-"
"«tuple<int&, int&, int&, char>»──(1,1,1,b)-"
"«tuple<int&, int&, int&, char>»──(2,2,2,c)-"
"«tuple<int&, int&, int&, char>»──(3,3,3,d)-"
"«tuple<int&, int&, int&, char>»──(5,5,5,e)-"
"«tuple<int&, int&, int&, char>»──(8,8,8,f)"_expect);
CHECK (materialise (
zip (s6,s3,s6,eachNum('a'))
)
== "«tuple<int&, int const&, int&, char>»──(1,3,1,a)-"
"«tuple<int&, int const&, int&, char>»──(1,2,1,b)-"
"«tuple<int&, int const&, int&, char>»──(2,1,2,c)"_expect);
CHECK (isnil (s0));
CHECK (materialise (
zip (s0,s3,s6,eachNum('a'))
)
== ""_expect);
CHECK (materialise (
zip (eachNum('a'),eachNum(-1),s0,s0)
)
== ""_expect);
CHECK (materialise (
zip (eachNum('a'),eachNum(-1),s3,s0)
)
== ""_expect);
CHECK (materialise (
zip (eachNum('a'),eachNum(-1),s3,s3)
)
== "«tuple<char, int, int const&, int const&>»──(a,-1,3,3)-"
"«tuple<char, int, int const&, int const&>»──(b,0,2,2)-"
"«tuple<char, int, int const&, int const&>»──(c,1,1,1)"_expect);
// a wild mix of data sources,
// including infinite and virtual ones....
CHECK (materialise (
izip (s6 // a STL container given by reference
,explore(s6).filter([](int i){ return i%2; }) // IterExplorer pipeline with filtering
,numS<17,170>().transform(hexed) // IterExplorer pipeline with transformer and object value result
,eachNum((1+sqrt(5))/2) // a Lumiera iterator which happens to be almost inexhaustible
,explore(s3).asIterSource() // an IterSource, which is a virtual (OO) iterator interface
)
)
== "«tuple<ulong, int&, int&, string&, double, int const&>»──(0,1,1,AA,1.618034,3)-"
"«tuple<ulong, int&, int&, string&, double, int const&>»──(1,1,1,BB,2.618034,2)-"
"«tuple<ulong, int&, int&, string&, double, int const&>»──(2,2,3,CC,3.618034,1)"_expect);
}
/** @test verify pass-through of references */
void
verify_references()
@ -318,7 +379,7 @@ namespace test{
auto vec = std::vector{1,5};
auto arr = std::array{2,3};
// Case-1
// Case-1 ------
auto i1 = izip (vec,arr);
CHECK (*i1 == "«tuple<ulong, int&, int&>»──(0,1,2)"_expect ); // initial state points to the first elements, prefixed with index≡0
@ -328,7 +389,7 @@ namespace test{
CHECK (join(vec) == "5, 5"_expect ); // manipulation indeed flipped the first element in the vector
CHECK (join(arr) == "2, 3"_expect ); // (while the array remains unaffected)
// Case-1
// Case-2 ------
auto i2 = izip (explore(vec).transform([](uint v){ return v-1; }) // this time the first iterator is a pipeline with a transformer
,arr); // while the second one is again a direct iteration of the array
@ -343,6 +404,33 @@ namespace test{
CHECK (join(vec) == "5, 5"_expect ); // ...which is in fact true for the vector, due to the transformer
CHECK (join(arr) == "9, 3"_expect ); // ...while the array could be reached through the reference
}
/** @test the result is actually an IterExplorer pipeline builder,
* which can be used to attach further processing
*/
void
verify_pipelining()
{
SHOW_EXPR
(materialise (
zip (num31(), num32(), num33())
. transform([](auto& it){ auto [a,b,c] = *it;
return a+b+c;
})
)
)
SHOW_EXPR
(materialise (
zip (num31(), num32(), num33())
. filter ([](auto& it){ auto [a,b,c] = *it;
return not ((a+b+c) % 2);
})
)
)
}
/*
SHOW_EXPR
(materialise (

View file

@ -19017,9 +19017,7 @@
<icon BUILTIN="clanbomber"/>
<node CREATED="1664766851269" ID="ID_1929258813" MODIFIED="1664767130682" TEXT="habe hier Bedenken wegen der Performance">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
<font color="#b1058d"><i>premature optimisation</i></font>??
@ -19485,9 +19483,7 @@
</node>
<node CREATED="1665871160235" ID="ID_247576641" MODIFIED="1665871348368" TEXT="derzeit nur hypothetischer Nutzen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...es w&#252;rde sich um irgendwelche ausgefallenen Use-Cases handeln, und das direkte Anheften der Kind-Widgets w&#252;rde dann Overhead sparen, gegen&#252;ber einem Canvas; weiterer Vorteil w&#228;re der direkte <i>push-back </i>f&#252;r die Allokation von Screen-Extension (was allerdings im Falle eines size-constrained Widget dann wieder ein Nachteil w&#228;re)
@ -19811,9 +19807,7 @@
<icon BUILTIN="forward"/>
<node CREATED="1661704175885" ID="ID_1381922176" MODIFIED="1661704361482" TEXT="die gesamte Positionierungs-Logik arbeitet mit Verh&#xe4;ltniszahlen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...wobei der Datentyp dieser Verh&#228;ltniszahlen noch w&#228;hlbar ist
@ -20383,9 +20377,7 @@
<icon BUILTIN="button_ok"/>
<node CREATED="1477600134217" ID="ID_1352260964" MODIFIED="1576282358100" TEXT="wie viel selber machen?">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Frage ist, wie viel des Verhaltens programmieren wir selber explizit aus,
@ -21137,9 +21129,7 @@
<node CREATED="1575217051398" ID="ID_1214822231" MODIFIED="1575217061441" TEXT="und Clips m&#xfc;&#xdf;ten ebenfalls einen lokalen Dienst bieten"/>
<node CREATED="1575216926792" ID="ID_1215187417" MODIFIED="1575220655549" TEXT="die Implementierung ist aber auch tats&#xe4;chlich flach">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...und nicht hierarchisch! Letzten Endes geht es nur darum, Widgets an einen gemeinsamen Canvas zu heften
@ -22890,9 +22880,7 @@
</node>
<node COLOR="#435e98" CREATED="1480742405505" FOLDED="true" ID="ID_1590367176" MODIFIED="1679360112757" TEXT="ACHTUNG: leere Sequenz?">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
<i>theoretisch</i>&#160;k&#246;nnte man eine Timeline ohne Sequenz
@ -25458,9 +25446,7 @@
<icon BUILTIN="button_ok"/>
<node CREATED="1612742259238" ID="ID_607718286" MODIFIED="1612742418037" TEXT="wichtig: die desired_height verwenden (&#x2192;size-request)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...nachdem erstmals ein size-request gesetzt wurde, hat sich die tats&#228;chliche H&#246;he des Widget noch nicht ver&#228;ndert (das wird erst mit dem nachfolgenden resize-event vollzogen). Aber der size-request spiegelt sich sofort in der desired_height wieder. Wir m&#252;ssen also die Ermittlung der &quot;aktuellen&quot; H&#246;he <i>darauf</i>&#160;aufbauen, damit die schon vorgenommenen Anpassungen nicht nochmal im Delta landen
@ -37999,9 +37985,7 @@
</node>
<node CREATED="1615563757154" ID="ID_1223828386" MODIFIED="1615563849447" TEXT="diese L&#xf6;sung erscheint tragf&#xe4;hig und koh&#xe4;rent">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...insofern sie genau an die Struktur anbaut, welche ich schon zur L&#246;sung der Querbeziehungen f&#252;r das Layout genutzt habe
@ -40759,9 +40743,7 @@
</node>
<node CREATED="1667350536992" ID="ID_1838246834" MODIFIED="1667476855366" TEXT="das stellt die Implementierungs-Basis in Frage">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Die &#181;-Ticks hatten wir seinerzeit gew&#228;hlt, weil sie einerseits hinreichend genau sind, andererseits sehr einfach zu implementieren, und dennoch die Darstellung extrem gro&#223;er Zeitspannen erm&#246;glichen
@ -42121,9 +42103,7 @@
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1668292845491" ID="ID_1723809039" MODIFIED="1668293079087" TEXT="Differenz wird noch vom Puffer in TimeValue aufgefangen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
ich habe ja ganz bewu&#223;t Time::MAX == INT_MAX/3 genommen
@ -42956,9 +42936,7 @@
</node>
<node CREATED="1670694912251" ID="ID_1739440365" LINK="#ID_324128019" MODIFIED="1670695001317" TEXT="Alternative: ULP aufschlagen &#x2014; ist numerisch nicht durchf&#xfc;hrbar">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das geht in Floating-Point aber eben grade nicht in Integer-Bruchrechnung; ein ULP ist der <i>&#187;maximal giftige Bruch&#171;</i>
@ -43600,9 +43578,7 @@
<node CREATED="1668292124740" ID="ID_1232493436" MODIFIED="1668292133321" TEXT="k&#xf6;nnte ein Restrisiko bleiben"/>
<node CREATED="1668292133979" ID="ID_770094379" MODIFIED="1668292156815">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
erfordert Analyse <i>aller relevanten </i>Code-Pfade
@ -43909,9 +43885,7 @@
<node CREATED="1668699891224" ID="ID_420975014" MODIFIED="1668699935567" TEXT="reduzieren um Z&#xe4;hler - LIM_HAZARD"/>
<node CREATED="1668699947962" ID="ID_307211451" MODIFIED="1668700039253" TEXT="das erste Quansitieren bewirkt n&#xe4;mlich u.U fast gar nix">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...und zwar in dem Fall, in dem der Nenner nur knapp &#252;ber der Schwelle LIM_HAZARD liegt; dann findet n&#228;mlich fast keine Reduktion der Gr&#246;&#223;enordnung statt
@ -44207,9 +44181,7 @@
</node>
<node CREATED="1669933281232" ID="ID_542233825" MODIFIED="1669933418231" TEXT="ohne Rundung: 3999&#xb5;s">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
parsing '1/250sec' resulted in 0:00:00.003 instead of 0:00:00.004
@ -52787,8 +52759,8 @@
<linktarget COLOR="#d41f46" DESTINATION="ID_1711720667" ENDARROW="Default" ENDINCLINATION="-179;-10;" ID="Arrow_ID_880963824" SOURCE="ID_1112527704" STARTARROW="None" STARTINCLINATION="176;10;"/>
</node>
<node CREATED="1732234626323" ID="ID_987261541" MODIFIED="1732234641012" TEXT="der Tupel-Konstruktor &#xbb;materialsiert&#xab; dann praktisch immer eine Kopie"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732234650247" ID="ID_1807559774" MODIFIED="1732234984331" TEXT="brauche also eine dedizierte Funktion buildIterTuple&lt;ARGS....&gt;">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1732234650247" ID="ID_1807559774" MODIFIED="1732328124794" TEXT="brauche also eine dedizierte Funktion buildIterTuple&lt;ARGS....&gt;">
<icon BUILTIN="button_ok"/>
<node COLOR="#5b280f" CREATED="1732234686810" ID="ID_1016277466" MODIFIED="1732234699400" TEXT="k&#xf6;nnte man auch als generisches Util extrahieren">
<icon BUILTIN="button_cancel"/>
</node>
@ -52923,13 +52895,13 @@
<node COLOR="#435e98" CREATED="1732299521810" ID="ID_185815307" MODIFIED="1732313502381" TEXT="schlank halten: es gen&#xfc;gt die ProductCore">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732299561444" ID="ID_1140916206" MODIFIED="1732299624657" TEXT="dazu eine free-function iter::buildIterTuple(its...)">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1732299561444" ID="ID_1140916206" MODIFIED="1732328110469" TEXT="dazu eine free-function iter::buildIterTuple(its...)">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1732308743486" ID="ID_1261102696" MODIFIED="1732308787453" TEXT="Pr&#xfc;fen und erweitern auf das Durchreichen von Referenzen">
<node COLOR="#338800" CREATED="1732308743486" ID="ID_1261102696" MODIFIED="1732328080578" TEXT="Pr&#xfc;fen und erweitern auf das Durchreichen von Referenzen">
<linktarget COLOR="#b36e78" DESTINATION="ID_1261102696" ENDARROW="Default" ENDINCLINATION="243;11;" ID="Arrow_ID_1182778536" SOURCE="ID_1663970369" STARTARROW="None" STARTINCLINATION="212;14;"/>
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732315275749" ID="ID_769235796" MODIFIED="1732315292779" TEXT="liefert dann &#xfc;berraschend oft eine Referenz">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1732315275749" ID="ID_769235796" MODIFIED="1732328069516" TEXT="liefert dann &#xfc;berraschend oft eine Referenz">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732315295690" ID="ID_565969002" MODIFIED="1732315304625" TEXT="m&#xf6;chte man das?"/>
<node CREATED="1732315305473" ID="ID_1790636201" MODIFIED="1732315324906" TEXT="ja &#x2014; und es gibt const">
@ -52957,10 +52929,10 @@
Bestenfalls eliminiert der Optimiser ohnehin alle Indirektionen, aber auch alle Kopien. Wenn das aber nicht geht, weil es von irgendwo noch einen Zugriff geben k&#246;nnte, dann sitzt man auf einem Speicherzugriff, wo andernfalls direkt ein Register verwendet werden k&#246;nnte. Und wenn dann auch noch die Referenz non-const ist, versaut man sich leicht internen State und wundert sich dann... Nee, nee! Wenn man wirklich Seiteneffekte &#252;ber Referenzen m&#246;chte, dann soll man sich das bitte explizit auscoden, aber nicht eine Library-Funktion kreativ nutzen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1732315722881" ID="ID_506428359" MODIFIED="1732315730323" TEXT="also hier stellen wir um">
<node COLOR="#338800" CREATED="1732315722881" ID="ID_506428359" MODIFIED="1732327993905" TEXT="also hier stellen wir um">
<icon BUILTIN="yes"/>
<node CREATED="1732315731512" ID="ID_70704811" MODIFIED="1732315759207" TEXT="die yield-Operation liefert explizit die Zahl by-value"/>
<node CREATED="1732315759868" ID="ID_1323105276" MODIFIED="1732315833747" TEXT="der operator-&gt; wird sogar entfernt">
<richcontent TYPE="NOTE"><html>
@ -52972,8 +52944,8 @@
</body>
</html></richcontent>
</node>
<node CREATED="1732317048384" ID="ID_146419454" MODIFIED="1732317054284" TEXT="Konsequenzen">
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1732317059614" ID="ID_20106465" MODIFIED="1732317075988" TEXT="Problem mit stringify / Itertools - TransformIter">
<node COLOR="#435e98" CREATED="1732317048384" FOLDED="true" ID="ID_146419454" MODIFIED="1732328064072" TEXT="Konsequenzen">
<node COLOR="#435e98" CREATED="1732317059614" ID="ID_20106465" MODIFIED="1732327929262" TEXT="Problem mit stringify / Itertools - TransformIter">
<icon BUILTIN="broken-line"/>
<node CREATED="1732317140456" ID="ID_837986381" MODIFIED="1732317155688" TEXT="kann nicht double&amp; an double-val binden">
<icon BUILTIN="stop-sign"/>
@ -52987,8 +52959,7 @@
Das hei&#223;t: in dem Moment wo wir die transformer-Funktion tats&#228;chlich installieren, packen wir sie in ein std::function-Objekt mit einer <b>neu synthetisierten Signatur</b>. Diese ist (der Intention nach) pa&#223;genau, d.h. sie nimmt den yield des vorgelagerten Iterators als Input
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732317252324" ID="ID_417114818" MODIFIED="1732322136155" TEXT="hier liegt der Hund begraben...">
<icon BUILTIN="broken-line"/>
@ -53003,8 +52974,7 @@
<font face="Monospaced">function&lt;VAL(InType)&gt; trafo_; </font>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1732317376563" ID="ID_627865570" MODIFIED="1732317617944" TEXT="das ist ein Schnellschlu&#xdf;...">
<richcontent TYPE="NOTE"><html>
@ -53017,8 +52987,7 @@
viele Jahre sp&#228;ter habe ich dann den NumIter definiert, und das ist vielleicht das erste Beispiel, bei dem dieses neue Konzept wirklich ausgereitzt wurde. Ich habe so dunkel in Erinnerung, da&#223; es dann nicht funktioniert hat, und ich deshalb &#8222;einfach&#8220; das <font color="#7510cd" face="Monospaced">const</font>&#160;in die eingebetteten Ergebnis-Typdefinitionen gepackt habe. Was ja nicht falsch war, aber der Weg des geringsten Wiederstandes
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1732317416174" ID="ID_1286735666" MODIFIED="1732317436999" TEXT="es ist in 90% der F&#xe4;lle in der Praxis so"/>
<node CREATED="1732317386082" ID="ID_1276663187" MODIFIED="1732317855187" TEXT="Nach aktuellem Stand gibt es aber keine entsprechende Konvention">
@ -53029,8 +52998,7 @@
Und das ist mir zunehmend wichtiger geworden, vor allem nach meinen Erfahrungen mit dem monadischen IterExplorer v1. Grade <i>weil man manchmal wirklich nur Values bieten kann,</i>&#160;mu&#223; diese Hintert&#252;r offen bleiben. Andererseits w&#228;re es ein gef&#228;hrlicher Fehlschlu&#223;, da&#223; eine Type-def &#187;reference&#171; hier &#8222;in Wirkklichkeit&#8220; meint, das was der Iterator liefert. Der Schlu&#223; liegt nahe, und deshalb bin ich ihm hier auch verfallen. Aber wenn man mit derartigem Konzept-Mapping erst mal anf&#228;ngt, dann verliert man schnell die Kontrolle
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node COLOR="#338800" CREATED="1732317867385" ID="ID_1371439047" MODIFIED="1732322117846" TEXT="also: stattdessen explizit den realen yield-Typ verwenden">
@ -53043,8 +53011,7 @@
in iter-adapter.hpp
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732318689596" ID="ID_1684194462" MODIFIED="1732322119411" TEXT="nach weiteren &#xe4;hnlichen Kurzschl&#xfc;ssen suchen...">
@ -53058,8 +53025,7 @@
also exakt die zentrale Stelle, an der entschieden wird, ob eine nachgeschaltete Funktion auf den Resultat-Wert losgeht, oder direkt auf den Iterator-Typ zugreift
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node COLOR="#435e98" CREATED="1732319784560" ID="ID_866009173" MODIFIED="1732322123344" TEXT="&#xe4;hnliches Denkmuster auch in util-coll">
<node COLOR="#435e98" CREATED="1732319797920" ID="ID_1305250293" MODIFIED="1732319806708" TEXT="hier ist auto viel besser!">
@ -53069,6 +53035,7 @@
</node>
</node>
</node>
</node>
<node COLOR="#5b280f" CREATED="1732322088730" ID="ID_1242739907" MODIFIED="1732323499529" TEXT="w&#xe4;re das auch anwendbar auf IterExplorer.transform() und expand() ?">
<icon BUILTIN="help"/>
<icon BUILTIN="closed"/>
@ -53085,10 +53052,15 @@
<node CREATED="1732322629737" ID="ID_676096219" MODIFIED="1732322648571" TEXT="operator-&gt; k&#xf6;nnte Adresse-von-Temporary nehmen">
<icon BUILTIN="broken-line"/>
</node>
<node CREATED="1732323357278" ID="ID_1689757044" MODIFIED="1732323387677" TEXT="unm&#xf6;glich da wir effektiv nur einen Ausgabepfad haben">
<node CREATED="1732323518400" ID="ID_1448081421" MODIFIED="1732323556103" TEXT="operator-&gt; verlangt zwingend nach einem stabilen Value"/>
<node CREATED="1732323556923" ID="ID_1568353234" MODIFIED="1732323592138" TEXT="daher kann Core::yield() niemals anders als per Ref auf einen stabilen Wert arbeiten"/>
<node CREATED="1732323615259" ID="ID_183489075" MODIFIED="1732323721859" TEXT="wollte man hier flexibel sein, ginge das stets nur an der Au&#xdf;engrenze">
<node COLOR="#5b280f" CREATED="1732323357278" ID="ID_1689757044" MODIFIED="1732327891664" TEXT="unm&#xf6;glich da wir effektiv nur einen Ausgabepfad haben">
<icon BUILTIN="stop-sign"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732323518400" ID="ID_1448081421" MODIFIED="1732327912529" TEXT="operator-&gt; verlangt zwingend nach einem stabilen Value">
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#5b280f" CREATED="1732323556923" ID="ID_1568353234" MODIFIED="1732327907757" TEXT="daher kann Core::yield() niemals anders als per Ref auf einen stabilen Wert arbeiten">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1732323615259" ID="ID_183489075" MODIFIED="1732327920070" TEXT="wollte man hier flexibel sein, ginge das stets nur an der Au&#xdf;engrenze">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -53096,13 +53068,20 @@
...das w&#252;rde bedeuten: man reicht eine weitere Typ-Def komplett durch die ganze Kette durch, und jeweils nur am Ende der Kette w&#252;rde diese f&#252;r den operator* gelten. Da wir aber Ketten im Builder auch noch nachtr&#228;glich weiter verl&#228;ngern, indem eine neue Core dar&#252;ber gesetzt wird, ist das jedoch nicht ohne Weiteres realisierbar
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
<icon BUILTIN="button_cancel"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732327966521" ID="ID_1122071116" MODIFIED="1732327983573" TEXT="erscheint mir nun ein guter Komrpomi&#xdf;">
<icon BUILTIN="yes"/>
<node CREATED="1732328013291" ID="ID_1566390757" MODIFIED="1732328021229" TEXT="der Loop-Index kommt als reine Zahl"/>
<node CREATED="1732328021813" ID="ID_253756107" MODIFIED="1732328030900" TEXT="ansonsten kann man auf Quellwerte durchgreifen"/>
<node CREATED="1732328031488" ID="ID_1120812520" MODIFIED="1732328043338" TEXT="sofern die zugrundeliegende Situation dies zul&#xe4;&#xdf;t"/>
<node CREATED="1732328044567" ID="ID_369672919" MODIFIED="1732328061744" TEXT="und der user kann stets values konstruieren"/>
</node>
</node>
</node>
@ -53117,7 +53096,9 @@
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235323997" ID="ID_1085200650" MODIFIED="1732235555231" TEXT="Iteratoren verschiedenen Typs">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1732313512667" ID="ID_1362209953" MODIFIED="1732313522016" TEXT="verschieden dekorierte Sequenzen"/>
<node COLOR="#338800" CREATED="1732313512667" ID="ID_1362209953" MODIFIED="1732328099863" TEXT="verschieden dekorierte Sequenzen">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1732313524489" ID="ID_824059713" MODIFIED="1732313531717" TEXT="Sequenzen verschiedener L&#xe4;nge"/>
<node CREATED="1732313533659" ID="ID_1229132868" MODIFIED="1732313539891" TEXT="verschiedene Quellen">
<node CREATED="1732313542680" ID="ID_918133774" MODIFIED="1732313546301" TEXT="Lumiera-Iterator"/>
@ -53129,9 +53110,54 @@
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235343138" ID="ID_1943784376" MODIFIED="1732235555231" TEXT="per structured Binding verarbeiten">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235434406" ID="ID_1663970369" MODIFIED="1732308796716" TEXT="Durchgriff auf die Quellen per Referenz">
<node COLOR="#338800" CREATED="1732235434406" ID="ID_1663970369" MODIFIED="1732328083295" TEXT="Durchgriff auf die Quellen per Referenz">
<arrowlink COLOR="#b36e78" DESTINATION="ID_1261102696" ENDARROW="Default" ENDINCLINATION="243;11;" ID="Arrow_ID_1182778536" STARTARROW="None" STARTINCLINATION="212;14;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1732332677537" ID="ID_800914951" MODIFIED="1732332688213" TEXT="nachgeschaltete Pipeline">
<icon BUILTIN="pencil"/>
<node CREATED="1732332692124" ID="ID_1457478622" MODIFIED="1732332701439" TEXT="transformer in einfache Zahl"/>
<node CREATED="1732332702041" ID="ID_682214158" MODIFIED="1732332719372" TEXT="Filter basieren auf Werten aus dem Tupel">
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732333449943" ID="ID_1811172733" MODIFIED="1732333478683" TEXT="Beobachtung: direkt gegebener IterExplorer wird nochmal gewrapped">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732333481816" ID="ID_488310307" MODIFIED="1732333491274" TEXT="das ist unsch&#xf6;n"/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1732333491869" ID="ID_34490328" MODIFIED="1732333528532" TEXT="...und w&#xfc;rde das Durchreichen eines Child-Expanders verhindern">
<icon BUILTIN="broken-line"/>
</node>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1732332721552" ID="ID_884561005" MODIFIED="1732332738918" TEXT="erstes Ausgabetupel enth&#xe4;lt uninitialisierte Werte">
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732335037680" ID="ID_883671623" MODIFIED="1732335076161" TEXT="Ursache: das erste pullFilter() im ctor wird vor dem move() aufgerufen">
<icon BUILTIN="broken-line"/>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1732334924952" ID="ID_1746517643" MODIFIED="1732334950212" TEXT="das ist ein schlummernder Bug im IterExplorer-Filter">
<icon BUILTIN="clanbomber"/>
<node CREATED="1732334965186" ID="ID_1456555909" MODIFIED="1732335007808" TEXT="tritt nur auf wenn der darunter liegende Iterator eine Referenz speichert"/>
<node CREATED="1732335008372" ID="ID_1329188040" MODIFIED="1732335016335" TEXT="und diese Referenz in den Iterator selbst zeigt"/>
<node COLOR="#b80990" CREATED="1732335125501" ID="ID_1555472016" MODIFIED="1732335151624" TEXT="&#xd83d;&#xdc80; Teufelszeug!!">
<font NAME="SansSerif" SIZE="14"/>
<node CREATED="1732335207642" ID="ID_955481326" MODIFIED="1732335217996" TEXT="immer wieder das Problem mit diesen move-Buildern"/>
<node CREATED="1732335320131" ID="ID_166629885" MODIFIED="1732335329917" TEXT="unklar: w&#xfc;rde ein RVO-Builder hier helfen??"/>
<node CREATED="1732335356217" ID="ID_1122958962" MODIFIED="1732335515135" TEXT="eigentliches Problem ist das Zwiebelschalen-Design">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
das zwingt mich, einen inneren Quell-Layer in den &#228;u&#223;eren Wrapper zu schieben; selbst wenn ich das Argument by-value nehme, ist es damit noch nicht in dem Objekt-Feld, wo es hingeh&#246;rt. Das bedeutet dann, entweder eine Kopie (und man ist vom Optimiser abh&#228;ngig), oder eben ein move(SRC).
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732335090297" ID="ID_1603332767" MODIFIED="1732335111791" TEXT="konkret liegt danach im ItemWrapper ein Tuple mit dangling-references">
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1732335516273" ID="ID_77601" MODIFIED="1732335551076" TEXT="Konsequenz: KEINE Aktivit&#xe4;t in einem Konstruktor darf Referenzen binden">
<icon BUILTIN="flag-pink"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235523602" ID="ID_1940842867" MODIFIED="1732235555232" TEXT="Durchgriff auf Child-Expander im Quell-Iterator">
<icon BUILTIN="flag-yellow"/>