Library: handle chaining of iterator-pipelines

This involves some quite tricky changes in the way types are composed to form an iterator-pipeline.
Some wrappers are added as adaptors or for additional safety-checks, and to provide a builder-API.
Unfortunately, when building a new `IterExplorer` iterator pipeline from an existing pipeline naively,
composing all those types will add several unecessary intermediary wrapper-layers.
Worse even, the handling of `BaseAdapter` prevents the new tuple-zipping iterator
actually to pass-through any `expandChildren()` call.

These issues are a consequence of using templated types, instead of fixed types with an interface;
we can not just determine if some wrapper is present — unless the wrapper itself ''helps by exposing a tag.''
Even while I must admit that the whole packaging and adaptation machinery of `IterExplorer`
looks dangerously complex already, using dedicated type tags for this single purpose
seems like a tenable soulution.
This commit is contained in:
Fischlurch 2024-11-24 19:53:07 +01:00
parent e50e9cb8e7
commit a683e689f0
12 changed files with 401 additions and 87 deletions

View file

@ -426,7 +426,8 @@ namespace diff{
void
swap (Rec& existingInstance) noexcept
{
std::swap (existingInstance, record_);
using std::swap;
swap (existingInstance, record_);
}
bool
@ -641,7 +642,7 @@ namespace diff{
RecordRef&
operator= (RecordRef &&o)
{
std::swap(record_, o.record_);
std::swap (record_, o.record_);
return *this;
}

View file

@ -551,6 +551,8 @@ namespace lib {
CheckedCore& operator= (CheckedCore&&) =default;
CheckedCore& operator= (CheckedCore const&) =default;
using TAG_CheckedCore_Raw = COR; ///< marker to allow unwrapping the raw core
/* === state protocol API for IterStateWrapper === */
bool

View file

@ -264,7 +264,9 @@ namespace lib {
using CoreYield = decltype(std::declval<COR>().yield());
/** decide how to adapt and embed the source sequence into the resulting IterExplorer */
/**
* @internal Type-selector template to adapt for IterExplorer:
* decide how to adapt and embed the source sequence */
template<class SRC, typename SEL=void>
struct _DecoratorTraits
{
@ -513,6 +515,8 @@ namespace lib {
void expandChildren() { } ///< collaboration: recurse into nested scope
size_t depth() const { return 0; } ///< collaboration: number of nested scopes
using TAG_IterExplorer_BaseAdapter = SRC; ///< @internal for \ref _BaseDetector
};
@ -1578,6 +1582,8 @@ namespace lib {
using reference = typename meta::ValueTypeBinding<SRC>::reference;
using pointer = typename meta::ValueTypeBinding<SRC>::pointer;
using TAG_IterExplorer_Src = SRC; ///< @internal for \ref _PipelineDetector
/** pass-through ctor */
using SRC::SRC;
@ -2056,6 +2062,61 @@ namespace lib {
};
namespace {// internal logic to pick suitable pipeline adapters...
/** Detect or otherwise add BaseAdapter.
* @remark in addition to just iteration, IterExplorer uses an internal wiring for some
* of the additional processing layers, which works by calling to the base class.
* When building a new pipeline, a BaseAdapter is added on top of the raw iterator
* to absorb these internal calls (and do nothing); however, if the raw iterator
* in fact is already a pipeline built by IterExplorer, than no BaseAdapter is
* required and rather both pipelines can be connected together
*/
template<class SRC, class SEL =void>
struct _BaseDetector
{
using BaseAdapter = iter_explorer::BaseAdapter<SRC>;
};
template<class SRC> // used when type tag is present on some baseclass
struct _BaseDetector<SRC, std::void_t<typename SRC::TAG_IterExplorer_BaseAdapter> >
{
using BaseAdapter = SRC;
};
/** Detect and remove typical adapter layers added by a preceding IterExplorer usage */
template<class SRC, class SEL =void>
struct _UnstripAdapter
{
using RawIter = SRC;
};
template<class COR> // used when actually a CheckedCore was attached
struct _UnstripAdapter<COR, std::void_t<typename COR::TAG_CheckedCore_Raw> >
{
using RawIter = typename COR::TAG_CheckedCore_Raw;
};
/** Detect if given source was already built by IterExplorer;
* @remark when building on-top of an existing pipeline, some adapter can be stripped
* to simplify the type hierarchy; for this purpose, IterExplorer places a tag type
* into its own products, which point to a suitable source type below the adapter.
*/
template<class SRC, class SEL =void>
struct _PipelineDetector
{
using RawIter = SRC;
};
template<class SRC>
struct _PipelineDetector<SRC, std::void_t<typename SRC::TAG_IterExplorer_Src> >
{
using _SrcIT = typename SRC::TAG_IterExplorer_Src;
using RawIter = typename _UnstripAdapter<_SrcIT>::RawIter;
};
}//(End)internal adapter logic
@ -2116,8 +2177,9 @@ namespace lib {
inline auto
explore (IT&& srcSeq)
{
using SrcIter = typename _DecoratorTraits<IT>::SrcIter;
using Base = iter_explorer::BaseAdapter<SrcIter>;
using RawIter = typename _PipelineDetector<IT>::RawIter; // possibly strip an underlying IterExplorer
using SrcIter = typename _DecoratorTraits<RawIter>::SrcIter; // then decide how to adapt the source / iterator
using Base = typename _BaseDetector<SrcIter>::BaseAdapter; // detect if a BaseAdapter exists or must be added
return IterExplorer<Base> (std::forward<IT> (srcSeq));
}

View file

@ -84,6 +84,32 @@ namespace lib {
meta::forEach (iters_
,[](auto& it){ ++it; });
}
/* === connector for IterAdapter internal protocol === */
/**
* instruct a follow-up IterAdapter not to add a BaseAdapter
* but rather to connect to the dispatcher functions defined here
*/
using TAG_IterExplorer_BaseAdapter = ITUP;
/** delegate to the IterExplorers in the tuple */
void
expandChildren()
{
meta::forEach (iters_
,[](auto& it){ it.expandChildren(); });
}
size_t
depth() const
{
size_t maxDepth{0};
meta::forEach (iters_
,[&](auto& it){ maxDepth = std::max (maxDepth, it.depth()); });
return maxDepth;
}
};
} // namespace lib::iter

View file

@ -130,26 +130,9 @@ namespace lib {
std::swap (storage_, rr.storage_);
}
Extension& operator= (Extension const& o)
Extension& operator= (Extension o)
{
if (this != &o)
{
std::unique_ptr<Literal[]> cp;
if (o.storage_)
cp.reset (o.newCopy());
if (storage_)
delete[] storage_;
storage_ = cp.release();
}
return *this;
}
Extension& operator= (Extension&& rr) noexcept
{
if (this != &rr)
{
std::swap (storage_, rr.storage_);
}
std::swap (storage_, o.storage_);
return *this;
}

View file

@ -380,7 +380,7 @@ namespace lib {
/** @internal adapt output side of a given function, allowing to handle it's results
* - a function producing the overall result-type is installed as-is
* - a `size_t` result is assumed be a hash and passed into #drawLimited
* - a `size_t` result is assumed to be a hash and passed into #drawLimited
* - likewise a `double` is assumed to be already a random val to be #limited
* - special treatment is given to a function returning a `RandomDraw` instance
* by value; such a function is assumed to set some parametrisation based

View file

@ -231,7 +231,8 @@ namespace stat{
CSVData csv{{}};
csv.reserve (size()+1);
auto header = generateHeaderSpec();
std::swap (csv[0], header);
using std::swap;
swap (csv[0], header);
for (uint i=0; i < size(); ++i)
csv.emplace_back (formatCSVRow(i));
return csv;

View file

@ -912,7 +912,8 @@ namespace lib {
}
else
{ // restore original data context
std::swap (dataSrc_, ctxStack_.top().second);
using std::swap;
swap (dataSrc_, ctxStack_.top().second);
ctxStack_.pop();
return false;
}

View file

@ -179,8 +179,9 @@ namespace lib {
friend void
swap (UninitialisedDynBlock& u1, UninitialisedDynBlock& u2)
{
std::swap (u1.size_, u2.size_);
std::swap (u1.buff_, u2.buff_);
using std::swap;
swap (u1.size_, u2.size_);
swap (u1.buff_, u2.buff_);
}
explicit

View file

@ -66,7 +66,48 @@ namespace test{
#define TYPE(_EXPR_) showType<decltype(_EXPR_)>()
template<class SRC, class SEL =void>
struct _PipelineDetector
{
using RawIter = SRC;
};
template<class SRC>
struct _PipelineDetector<SRC, std::void_t<typename SRC::TAG_Explode> >
{
using RawIter = typename SRC::TAG_Explode;
};
struct BOO
{
int uh{42};
};
template<class SRC>
struct Moo
: SRC
{
using TAG_Explode = SRC;
};
template<class SRC>
struct D
: SRC
{ };
void
plonk()
{
using P1 = D<D<BOO>>;
using P2 = D<D<Moo<D<BOO>>>>;
using R1 = typename _PipelineDetector<P1>::RawIter;
using R2 = typename _PipelineDetector<P2>::RawIter;
SHOW_TYPE(P1)
SHOW_TYPE(R1)
SHOW_TYPE(P2)
SHOW_TYPE(R2)
}
/*********************************************************************************//**
@ -85,6 +126,7 @@ namespace test{
virtual void
run (Arg)
{
plonk();
simpleUsage();
test_Fixture();
demo_mapToTuple();
@ -409,27 +451,41 @@ namespace test{
/** @test the result is actually an IterExplorer pipeline builder,
* which can be used to attach further processing
* which can be used to attach further processing.
* @note the design of IterExplorer inherently requires that
* generic lambdas accept the _iterator type_ by reference;
* structural bindings can only be used in a second step.
*/
void
verify_pipelining()
{
SHOW_EXPR
(materialise (
// transform the tuple into another data value
CHECK (materialise (
zip (num31(), num32(), num33())
. transform([](auto& it){ auto [a,b,c] = *it;
return a+b+c;
})
)
)
SHOW_EXPR
(materialise (
== "6-15-24-33-42"_expect);
// filter tuples based on inspecting contents
CHECK (materialise (
zip (num31(), num32(), num33())
. filter ([](auto& it){ auto [a,b,c] = *it;
return not ((a+b+c) % 2);
})
)
)
== "«tuple<uint&, uint&, uint&>»──(1,2,3)-"
"«tuple<uint&, uint&, uint&>»──(7,8,9)-"
"«tuple<uint&, uint&, uint&>»──(13,14,15)"_expect);
// reduce with accessor and std::plus
CHECK (zip (num31(), num32(), num33())
. reduce ([](auto& it){ auto [a,b,c] = *it;
return a+b+c;
})
== 6+15+24+33+42);
SHOW_EXPR(TYPE(izip(num31())))
}
/*
SHOW_EXPR

View file

@ -169,7 +169,7 @@ namespace test {
CHECK (w1->val == l1->val);
CHECK (w1->val == l3->val);
std::swap (l2, l3);
swap (l2, l3);
CHECK (w1->val == l1->val);
CHECK (w1->val == l2->val);
CHECK (w2->val == l3->val);

View file

@ -19375,9 +19375,7 @@
</node>
<node CREATED="1664056051832" ID="ID_528560555" MODIFIED="1664056323292" TEXT="m&#xf6;glicherweise die human-readable-Form">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...die name-ID mu&#223; eindeutig sein (modulo Objekt-Typ), weil allein daraus eine EntryID zu konstruieren ist, verm&#246;ge deren die Kommunikation &#252;ber den Bus gesteuert wird. Daher ist es denkbar, da&#223; die User [optional] eine mnemonische Form definieren wollen, und diese steht dann im Label-Widget. Und noch etwas: der Label-Text wird ggfs. zur Anzeige gek&#252;rzt, also mu&#223; irgendwo der Basis-Text stehen (es sei denn, man holt sich den via Request &#252;ber den Bus)
@ -19754,9 +19752,7 @@
</node>
<node CREATED="1661703733113" ID="ID_1280505961" MODIFIED="1661704551822" TEXT="Angaben m&#xfc;ssen angepa&#xdf;t werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...wannimmersich die Display-Metrik &#228;ndert (bei jeder Zoom-Anpassung!)
@ -20185,9 +20181,7 @@
<node CREATED="1666315741368" ID="ID_581715301" MODIFIED="1666315759423" TEXT="und die Voraussetzung: man braucht ein zugeordnetes GdkWindow"/>
<node CREATED="1666315760552" ID="ID_491760379" MODIFIED="1666315831393" TEXT="Diagnose: Gtk::Frame hat kein Window">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
get_has_window()&#160;&#160;&#10132; <font face="Monospaced" color="#6c13de">false</font>
@ -20737,9 +20731,7 @@
<node CREATED="1569799685975" ID="ID_1899453702" MODIFIED="1569799698129" TEXT="zun&#xe4;chst einmal ziemlich festgelegt">
<node CREATED="1569799719906" ID="ID_201546085" MODIFIED="1576282358095" TEXT="Lambdas w&#xfc;rden einen Ziel-Pointer pro Lambda erfordern">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Erl&#228;uterung: man k&#246;nnte auf die Idee kommen, die vier notwendigen Operationen auf dem Ziel durch Lambdas zu verkapseln. Wenn man dann aber nicht aufpa&#223;t, resultiert das in einer Closure f&#252;r jedes dieser vier Lamdas, und diese Closure h&#228;lt zumindest einen Pointer auf das Zielobjekt. <i>Der Vorteil eines solchen Ansatzes </i>w&#228;re nat&#252;rlich, da&#223; der konkrete Typ von Quelle und Ziel aus der Definition des ViewHook verschwindet (allerdings auch nur, wenn diese Lambdas in std::function-Objekte gewickelt sind)
@ -21624,9 +21616,7 @@
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1675387257113" ID="ID_324465991" MODIFIED="1675387413606" TEXT="Anhaltspunkt: TreeMutator f&#xfc;r Clips im TrackPresenter">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
dieser greift im &#187;Constructor&#171; binding...
@ -23337,9 +23327,7 @@
<icon BUILTIN="info"/>
<node CREATED="1666476598232" ID="ID_412611180" MODIFIED="1666476751149" TEXT="zun&#xe4;chst als Dependency-Injection in die Track-Struktur eingewoben">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
per &#187;einh&#228;kel-&#955;&#171;
@ -26667,9 +26655,7 @@
<icon BUILTIN="button_cancel"/>
<node CREATED="1582926631295" ID="ID_1387833468" MODIFIED="1582926643826">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<i>wenn</i>&#160;das so relevant werden sollte
@ -36842,9 +36828,7 @@
</node>
<node CREATED="1532791334135" ID="ID_669771307" MODIFIED="1576282358028">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
wohl <b>einzige verbleibende</b>&#160;Verwendung
@ -40024,9 +40008,7 @@
</node>
<node CREATED="1672672309323" ID="ID_903266469" MODIFIED="1672672619791" TEXT="es gibt technische Beschr&#xe4;nkungen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
bedingt durch die interne Repr&#228;sesntation (als 64bit &#181;-Ticks bzw. signed fraction)...
@ -41555,9 +41537,7 @@
</node>
<node COLOR="#338800" CREATED="1668110543283" ID="ID_1610967476" MODIFIED="1668110656569" TEXT="Test auf Anhieb erfolgreich">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Mathematik halt....
@ -42435,9 +42415,7 @@
</node>
<node CREATED="1670607798845" ID="ID_1832446179" MODIFIED="1670607935324" TEXT="es gibt hier keine Garantien">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
anders im Nenner;&#160;&#160;md * dd ist garantiert berechenbar, sofern die Duration selber aus einem time::Duration gebildet wurde (und md ist durch das detox() limitiert worden)
@ -43053,9 +43031,7 @@
<node CREATED="1670717895146" ID="ID_750112679" MODIFIED="1670717903085" TEXT="effektiv ~ 1e-9"/>
<node CREATED="1670717904177" ID="ID_850581245" MODIFIED="1670718019510" TEXT="oder etwas kleiner falls MAX_TIMESPAN">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
die MAX_TIMESPAN-Limitierung beginnt etwas &#252;ber 1000px zu greifen; diese Unterschwelle w&#228;re aber px &#183; 1e-14
@ -43491,9 +43467,7 @@
<node CREATED="1671291612706" ID="ID_1061099064" MODIFIED="1671291623193" TEXT="obwohl wir da definitiv mehr darstellen k&#xf6;nnten"/>
<node CREATED="1671292172775" ID="ID_778157874" MODIFIED="1671292310771" TEXT="ich sehe aber keinen Nutzen daf&#xfc;r">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
selbst Sound-Samples sind (absolut betrachet) noch 10.41ms auseinander; solange wir <i>das</i>&#160;komfortabel und sauber im GUI darstellen und handhaben k&#246;nnen, sind wir fein
@ -43767,9 +43741,7 @@
<node CREATED="1668399055151" ID="ID_1320606425" MODIFIED="1668399066085" TEXT="sind beide in der gleichen Gr&#xf6;&#xdf;enordnung"/>
<node CREATED="1668399066733" ID="ID_833533643" MODIFIED="1668399154910" TEXT="was dagegen spricht: ich kenne nicht den Grund warum std::ilogb so schnell ist">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
eine andere Standard-Library, und ilogb() k&#246;nnte deutlich langsamer sein.
@ -52784,8 +52756,9 @@
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732221642486" ID="ID_1450873226" MODIFIED="1732233711887" TEXT="neues Problem: expander-Kollaborations-API weitergeben">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732221665403" ID="ID_421112241" MODIFIED="1732221694417" TEXT="bisher wurde dieses auf dem BaseAdapter terminiert"/>
<node CREATED="1732221701598" ID="ID_776445249" MODIFIED="1732221710825" TEXT="ich brauche also einen anderen Base-Adapter"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732221711745" ID="ID_1004997061" MODIFIED="1732233705544" TEXT="&#x27f9; den untersten InterExplorer-Layer mu&#xdf; ich explizit konstruieren">
<node CREATED="1732221701598" ID="ID_776445249" MODIFIED="1732404349453" TEXT="ich brauche also einen anderen oder gar keinen Base-Adapter"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732221711745" ID="ID_1004997061" MODIFIED="1732404392929" TEXT="&#x27f9; M&#xf6;glichkeit zur Anpassung des Base-Adapters schaffen">
<arrowlink COLOR="#a22991" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="-276;-254;" ID="Arrow_ID_125112633" STARTARROW="None" STARTINCLINATION="-524;25;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
@ -52860,6 +52833,143 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732404219427" ID="ID_87985222" MODIFIED="1732404384050" TEXT="Adapter-Generierung neu ordnen">
<linktarget COLOR="#ed5a59" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="180;171;" ID="Arrow_ID_1403487927" SOURCE="ID_1051749303" STARTARROW="None" STARTINCLINATION="425;-32;"/>
<linktarget COLOR="#a22991" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="-276;-254;" ID="Arrow_ID_125112633" SOURCE="ID_1004997061" STARTARROW="None" STARTINCLINATION="-524;25;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1732404405058" ID="ID_912348266" MODIFIED="1732404409231" TEXT="Feststellungen">
<node CREATED="1732404411080" ID="ID_619838250" MODIFIED="1732404450348" TEXT="IterExplorer f&#xfc;gt bisweilen unn&#xf6;tig Adapter hinzu"/>
<node CREATED="1732404451204" ID="ID_1816461381" MODIFIED="1732404472437" TEXT="der Base-Adapter k&#xf6;nnte ganz wegfallen &#x2014; wenn bereits einer da ist"/>
<node CREATED="1732404473288" ID="ID_1944760216" MODIFIED="1732404531008" TEXT="ein IterableDecorator und ggfs ein IterExplorer k&#xf6;nnen abgehoben werden"/>
</node>
<node CREATED="1732405205696" ID="ID_474793959" MODIFIED="1732405220566" TEXT="ich ziehe hier vor, auf explizite Type-Tags zu setzen">
<node CREATED="1732405221708" ID="ID_156327017" MODIFIED="1732405242941" TEXT="diese geh&#xf6;ren sicher zum IterExplorer-&#xd6;kosystem"/>
<node CREATED="1732405244193" ID="ID_1388758928" MODIFIED="1732405273344" TEXT="als Extension-Point k&#xf6;nnen sie auch explizit gesetzt werden &#x27f9; L&#xf6;sung"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1732405282395" ID="ID_1720349507" MODIFIED="1732418699090" TEXT="zwei neue Aufbereitungs-Schritte">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1732405300562" ID="ID_1747377543" MODIFIED="1732418717425" TEXT="BaseSrc freilgen anhand von Type-Tags">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1732405337093" ID="ID_119797718" MODIFIED="1732418749082" TEXT="IterExplorer setzt dieses Tag stets auf den direkt unterliegenden SRC-Typ">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1732405363656" ID="ID_1939842999" MODIFIED="1732418735716" TEXT="darunter liegender IterableDecorator wird automatisch auf Core gestrippt">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1732405652074" ID="ID_3854674" MODIFIED="1732418743893" TEXT="sonst: nichts machen (d.h. IT &#x2259; BaseSrc)">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1732418790617" ID="ID_817698426" MODIFIED="1732487151425" TEXT="kann man hier auch noch eine redundant eingef&#xfc;gte CheckedCore strippen?">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
<node COLOR="#5b280f" CREATED="1732418814782" ID="ID_1506139893" MODIFIED="1732418841725" TEXT="1. Versuch: direkt in die _DecoratorTraits">
<icon BUILTIN="button_cancel"/>
<node CREATED="1732418842978" ID="ID_1120619472" MODIFIED="1732418878886" TEXT="erst mal : mu&#xdf; die CheckedCore selber mit Type-Tag markieren">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
andere Tricks mit der _rawCore()-Zugriffsfunktion scheinen nicht zu gehen
</p>
</body>
</html>
</richcontent>
</node>
<node COLOR="#5b280f" CREATED="1732418880968" ID="ID_1435649475" MODIFIED="1732418978932" TEXT="Tilt! das f&#xfc;hrt dazu, da&#xdf; jeder Processing-Layer sofort wieder gestrippt wird">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...da alle Processing-Layer auf State-Cores beruhen, pr&#228;sentieren wir dem dar&#252;berzulegenden IterExplorer die neue Core, und der findet dann die unter diesem Layer liegende CheckedCore des Vorg&#228;ngers und strippt den neuen Layer weg. <i>YESS es funktioniert!!!!!!</i>
</p>
</body>
</html></richcontent>
<icon BUILTIN="broken-line"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732487080930" ID="ID_1941671854" MODIFIED="1732487106352" TEXT="2. Versuch: an der gleichen Stelle beim Einstieg">
<icon BUILTIN="button_ok"/>
<node CREATED="1732487107328" ID="ID_448728086" MODIFIED="1732487121488" TEXT="also jeweils nur wenn der IterExplorer initial konstruiert wird"/>
<node CREATED="1732487124717" ID="ID_287102344" MODIFIED="1732487148843" TEXT="genaure: sogar nur als ein 2.Preprocessing-Schritt auf der freigelegten BaseSrc"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1732405404073" ID="ID_1428756660" MODIFIED="1732418719461" TEXT="Optional einen Base-Adapter einf&#xfc;gen">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1732405423113" ID="ID_1973273876" MODIFIED="1732418740596" TEXT="falls kein Base-Adapter-Tag gefunden wurde">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732405460404" ID="ID_994840933" MODIFIED="1732418741710" TEXT="sonst: nichts machen (d.h. bestehenden Base-Adapter verwenden)">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732487170847" ID="ID_1262167504" MODIFIED="1732487199877" TEXT="Ergebnis: nun viel schlankere und minimale Typ-Schachtelung">
<icon BUILTIN="forward"/>
<node CREATED="1732487344743" HGAP="31" ID="ID_488136081" MODIFIED="1732487803727" STYLE="bubble" VSHIFT="11">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
<u><font size="2">vorher</font></u><font size="2">:</font>
</p>
<p>
<font face="Monospaced" size="1">IterExplorer&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160; </font><font color="#a70230" face="Monospaced" size="1">BaseAdapter</font><font face="Monospaced" size="1">&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;IterableDecorator&lt;uint, </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;CheckedCore&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</font><font color="#9301d5" face="Monospaced" size="1">IterExplorer</font><font face="Monospaced" size="1">&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</font><font color="#da3300" face="Monospaced" size="1">IterableDecorator</font><font face="Monospaced" size="1">&lt;uint, </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</font><font color="#da3300" face="Monospaced" size="1">CheckedCore</font><font face="Monospaced" size="1">&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Transformer&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;BaseAdapter&lt;NumIter&lt;int&gt; &gt;, </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;uint </font>
</p>
<p>
<u><font size="2">nachher</font></u><font size="2">:</font>
</p>
<p>
<font face="Monospaced" size="1">IterExplorer&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;IterableDecorator&lt;uint, </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;CheckedCore&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;Transformer&lt; </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;BaseAdapter&lt;NumIter&lt;int&gt; &gt;, </font>
</p>
<p>
<font face="Monospaced" size="1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;uint </font>
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1732235208972" ID="ID_1764687143" MODIFIED="1732308740170" TEXT="nun in Library-Code extrahieren">
@ -53088,16 +53198,20 @@
</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 COLOR="#338800" CREATED="1732332692124" ID="ID_1457478622" MODIFIED="1732401346084" TEXT="transformer in einfache Zahl">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732332702041" ID="ID_682214158" MODIFIED="1732401344958" TEXT="Filter basierend auf Werten aus dem Tupel">
<icon BUILTIN="button_ok"/>
<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">
<arrowlink COLOR="#7d7a99" DESTINATION="ID_1051749303" ENDARROW="Default" ENDINCLINATION="196;-161;" ID="Arrow_ID_922384929" STARTARROW="None" STARTINCLINATION="-576;25;"/>
<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">
<node COLOR="#435e98" CREATED="1732332721552" ID="ID_884561005" MODIFIED="1732380040032" 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"/>
@ -53125,10 +53239,31 @@
<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 BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732336927298" ID="ID_1133143344" MODIFIED="1732336965422" TEXT="das betrifft auch Weitere, z.B. das Grouping">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732335516273" ID="ID_77601" MODIFIED="1732380035456" TEXT="Konsequenz: KEINE Aktivit&#xe4;t in einem Konstruktor darf Referenzen binden">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732336927298" ID="ID_1133143344" MODIFIED="1732379480374" TEXT="das betrifft m&#xf6;glicherweise auch Weitere, z.B. das Grouping">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732378962487" ID="ID_507210660" MODIFIED="1732378981608" TEXT="alle durchgesehen: tats&#xe4;chlich ist das Grouping i.d.R davon nicht betroffen"/>
<node CREATED="1732378982412" ID="ID_298559499" MODIFIED="1732379024090" TEXT="alles was per-Value arbeitet, ist sicher (ein Aggregator ist potentiell gef&#xe4;hrlich)"/>
<node CREATED="1732379482769" ID="ID_1391046371" MODIFIED="1732379567301">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
tats&#228;chlich ist der Filter <b>besonders</b>&#160;gef&#228;hrdet
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
weil der Filter selber ja nur den Feed pullt, aber selber keine Werte speichert; damit erzeugt er m&#246;glicherweise <i>upstream</i>&#160;obsolete Referenzen.
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1732336967005" ID="ID_643449650" MODIFIED="1732337008685">
<richcontent TYPE="NODE"><html>
@ -53166,12 +53301,36 @@
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#5617c6" CREATED="1732379576452" ID="ID_1580080364" MODIFIED="1732379866080">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
ungutes Gef&#252;hl...
</p>
<p>
<font size="5">das Design hat hier eine </font><font size="5" color="#c20c49">Schwachstelle</font>
</p>
</body>
</html>
</richcontent>
<linktarget COLOR="#dc1411" DESTINATION="ID_1580080364" ENDARROW="Default" ENDINCLINATION="-714;76;" ID="Arrow_ID_705169700" SOURCE="ID_1846153024" STARTARROW="None" STARTINCLINATION="639;23;"/>
<icon BUILTIN="clanbomber"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732380041706" ID="ID_1315871262" MODIFIED="1732380070726" TEXT="mit dem Workaround ist das Problem (in diesem Fall) behoben">
<icon BUILTIN="smiley-oh"/>
</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"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732404127247" ID="ID_1051749303" MODIFIED="1732404283575" TEXT="setzt Anpassungen an den Adaptern voraus">
<arrowlink COLOR="#ed5a59" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="180;171;" ID="Arrow_ID_1403487927" STARTARROW="None" STARTINCLINATION="425;-32;"/>
<linktarget COLOR="#7d7a99" DESTINATION="ID_1051749303" ENDARROW="Default" ENDINCLINATION="196;-161;" ID="Arrow_ID_922384929" SOURCE="ID_34490328" STARTARROW="None" STARTINCLINATION="-576;25;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
@ -54443,6 +54602,28 @@
</node>
</node>
</node>
<node CREATED="1732379711542" ID="ID_1700111124" MODIFIED="1732379714311" TEXT="Erfahrungen">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#980009" CREATED="1732379716299" ID="ID_1803167134" MODIFIED="1732379732267" TEXT="Referenzen sind potentiell gef&#xe4;hrlich">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732379745207" ID="ID_1270739421" MODIFIED="1732379997110" TEXT="besonders der Transformer ist ein Gefahrenherd">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Diese Gefahr resultiert exakt aus seiner St&#228;rke, da&#223; er n&#228;mlich <i>jede beliebige Funktion</i>&#160;adaptieren kann, also auch eine Funktion, die Referenzen liefert. Wenn diese Referenzen in internen State der Iterator-Pipeline zeigen, dann werden sie <b>dangling</b>, sobald man die Pipeline verschiebt. Und das passiert leider bereits <b>bei der Konstruktion</b>. Wenn dann hinter dem Transformer noch ein Filter h&#228;ngt, nimmt das Verh&#228;ngnis seinen Lauf
</p>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732379999989" ID="ID_903683469" LINK="#ID_1863518121" MODIFIED="1732380026881" TEXT="Woraround versucht"/>
<node CREATED="1732380011224" ID="ID_832964054" MODIFIED="1732380020278" TEXT="bin nicht sicher ob der &#xbb;dicht&#xab; ist"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732379768428" ID="ID_1846153024" MODIFIED="1732379866080" TEXT="das wurde relevant im Iter-Zip, welches ein Tupel von Referenzen speichert">
<arrowlink COLOR="#dc1411" DESTINATION="ID_1580080364" ENDARROW="Default" ENDINCLINATION="-714;76;" ID="Arrow_ID_705169700" STARTARROW="None" STARTINCLINATION="639;23;"/>
<icon BUILTIN="broken-line"/>
</node>
</node>
</node>
<node CREATED="1535893137527" ID="ID_994961372" MODIFIED="1535893142488" TEXT="Verwendungen">
<icon BUILTIN="info"/>
<node CREATED="1535893144518" ID="ID_1137736223" MODIFIED="1535893214860" TEXT="ViewSpec solver im UI">