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:
parent
0b487735c2
commit
8d1740418b
4 changed files with 203 additions and 95 deletions
|
|
@ -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&
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "Tuple-zipped iterators" IterZip_test <<END
|
||||
TEST "Tuple-zipped iterators" IterZip_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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ürde sich um irgendwelche ausgefallenen Use-Cases handeln, und das direkte Anheften der Kind-Widgets würde dann Overhead sparen, gegenüber einem Canvas; weiterer Vorteil wäre der direkte <i>push-back </i>für die Allokation von Screen-Extension (was allerdings im Falle eines size-constrained Widget dann wieder ein Nachteil wäre)
|
||||
|
|
@ -19811,9 +19807,7 @@
|
|||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1661704175885" ID="ID_1381922176" MODIFIED="1661704361482" TEXT="die gesamte Positionierungs-Logik arbeitet mit Verhältniszahlen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...wobei der Datentyp dieser Verhältniszahlen noch wä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üßten ebenfalls einen lokalen Dienst bieten"/>
|
||||
<node CREATED="1575216926792" ID="ID_1215187417" MODIFIED="1575220655549" TEXT="die Implementierung ist aber auch tatsä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> kö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 (→size-request)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...nachdem erstmals ein size-request gesetzt wurde, hat sich die tatsächliche Höhe des Widget noch nicht verändert (das wird erst mit dem nachfolgenden resize-event vollzogen). Aber der size-request spiegelt sich sofort in der desired_height wieder. Wir müssen also die Ermittlung der "aktuellen" Höhe <i>darauf</i> 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ösung erscheint tragfähig und kohärent">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...insofern sie genau an die Struktur anbaut, welche ich schon zur Lösung der Querbeziehungen fü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 µ-Ticks hatten wir seinerzeit gewählt, weil sie einerseits hinreichend genau sind, andererseits sehr einfach zu implementieren, und dennoch die Darstellung extrem großer Zeitspannen ermö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ß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 — ist numerisch nicht durchfü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>»maximal giftige Bruch«</i>
|
||||
|
|
@ -43600,9 +43578,7 @@
|
|||
<node CREATED="1668292124740" ID="ID_1232493436" MODIFIED="1668292133321" TEXT="kö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ähler - LIM_HAZARD"/>
|
||||
<node CREATED="1668699947962" ID="ID_307211451" MODIFIED="1668700039253" TEXT="das erste Quansitieren bewirkt nä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 über der Schwelle LIM_HAZARD liegt; dann findet nämlich fast keine Reduktion der Größenordnung statt
|
||||
|
|
@ -44207,9 +44181,7 @@
|
|||
</node>
|
||||
<node CREATED="1669933281232" ID="ID_542233825" MODIFIED="1669933418231" TEXT="ohne Rundung: 3999µ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 »materialsiert« 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<ARGS....>">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1732234650247" ID="ID_1807559774" MODIFIED="1732328124794" TEXT="brauche also eine dedizierte Funktion buildIterTuple<ARGS....>">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#5b280f" CREATED="1732234686810" ID="ID_1016277466" MODIFIED="1732234699400" TEXT="kö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ü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üfen und erweitern auf das Durchreichen von Referenzen">
|
||||
<node COLOR="#338800" CREATED="1732308743486" ID="ID_1261102696" MODIFIED="1732328080578" TEXT="Prü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 überraschend oft eine Referenz">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1732315275749" ID="ID_769235796" MODIFIED="1732328069516" TEXT="liefert dann überraschend oft eine Referenz">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732315295690" ID="ID_565969002" MODIFIED="1732315304625" TEXT="möchte man das?"/>
|
||||
<node CREATED="1732315305473" ID="ID_1790636201" MODIFIED="1732315324906" TEXT="ja — 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önnte, dann sitzt man auf einem Speicherzugriff, wo andernfalls direkt ein Register verwendet werden kö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 über Referenzen mö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-> 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& an double-val binden">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
|
|
@ -52987,8 +52959,7 @@
|
|||
Das heißt: in dem Moment wo wir die transformer-Funktion tatsächlich installieren, packen wir sie in ein std::function-Objekt mit einer <b>neu synthetisierten Signatur</b>. Diese ist (der Intention nach) paß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<VAL(InType)> trafo_; </font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1732317376563" ID="ID_627865570" MODIFIED="1732317617944" TEXT="das ist ein Schnellschluß...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -53017,8 +52987,7 @@
|
|||
viele Jahre spä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ß es dann nicht funktioniert hat, und ich deshalb „einfach“ das <font color="#7510cd" face="Monospaced">const</font> 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ä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> muß diese Hintertür offen bleiben. Andererseits wäre es ein gefährlicher Fehlschluß, daß eine Type-def »reference« hier „in Wirkklichkeit“ meint, das was der Iterator liefert. Der Schluß liegt nahe, und deshalb bin ich ihm hier auch verfallen. Aber wenn man mit derartigem Konzept-Mapping erst mal anfä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 ähnlichen Kurzschlü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="ä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ä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-> könnte Adresse-von-Temporary nehmen">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node CREATED="1732323357278" ID="ID_1689757044" MODIFIED="1732323387677" TEXT="unmöglich da wir effektiv nur einen Ausgabepfad haben">
|
||||
<node CREATED="1732323518400" ID="ID_1448081421" MODIFIED="1732323556103" TEXT="operator-> 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ßengrenze">
|
||||
<node COLOR="#5b280f" CREATED="1732323357278" ID="ID_1689757044" MODIFIED="1732327891664" TEXT="unmö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-> 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ßengrenze">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -53096,13 +53068,20 @@
|
|||
...das würde bedeuten: man reicht eine weitere Typ-Def komplett durch die ganze Kette durch, und jeweils nur am Ende der Kette würde diese für den operator* gelten. Da wir aber Ketten im Builder auch noch nachträglich weiter verlängern, indem eine neue Core darü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ß">
|
||||
<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äß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ä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ön"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1732333491869" ID="ID_34490328" MODIFIED="1732333528532" TEXT="...und wü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ä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="�� 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ü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 äußeren Wrapper zu schieben; selbst wenn ich das Argument by-value nehme, ist es damit noch nicht in dem Objekt-Feld, wo es hingehört. Das bedeutet dann, entweder eine Kopie (und man ist vom Optimiser abhä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ä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"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue