Library: solve forwarding of child-expansion

For sake of completeness, since the `IterExplorer` supports building extended
search- and evaluation patterns, a tuple-zipping adapter can be expected
to handle these extended usages transparently.

While the idea is simple, making this actually happen had several ramifications
and required to introduce additional flexibility within the adaptor-framework
to cope better with those cases were some iterator must return a value, not a ref.
In the end, this could be solved with a bit of metaprogramming based on `std::common_type`

...and indeed, this is all quite nasty stuff — in hindsight, my initial intuition
to shy away from this topic was spot-on....
This commit is contained in:
Fischlurch 2024-11-26 02:56:28 +01:00
parent a683e689f0
commit 252c735b7b
8 changed files with 764 additions and 152 deletions

View file

@ -637,13 +637,15 @@ namespace lib {
* checks; it might be a good idea to build safety checks into the Core
* API functions instead, or to wrap the Core into \ref CheckedCore.
* @tparam T nominal result type (maybe const, but without reference).
* The resulting iterator will yield a reference to this type T
* @tparam COR type of the »state core«. The resulting iterator will _mix-in_
* this type, and thus inherit properties like copy, move, compare, VTable, POD.
* The COR must implement the following _iteration control API:_
* -# `checkPoint` establishes if the given state element represents a valid state
* -# ´iterNext` evolves this state by one step (sideeffect)
* -# `yield` realises the given state, exposing a result of type `T&`
* @note the resulting iterator will attempt to yield a reference to type \a T when possible;
* but when the wrapped `COR::yield()` produces a value, this is passed and also
* #operator-> is then disabled, to prevent taking the adress of the value (temporary)
* @see IterExplorer a pipeline builder framework on top of IterableDecorator
* @see iter-explorer-test.hpp
* @see iter-adaptor-test.cpp
@ -664,9 +666,17 @@ namespace lib {
}
public:
typedef T* pointer;
typedef T& reference;
typedef T value_type;
// typedef T* pointer;
// typedef T& reference;
// typedef T value_type;
/////////////////////////////////////////////////////////////////////////////OOO new YieldRes code
using CoreYield = decltype(std::declval<COR>().yield());
using _CommonT = meta::CommonResultYield<T&, CoreYield>;
using YieldRes = typename _CommonT::ResType;
using value_type = typename _CommonT::value_type;
using reference = typename _CommonT::reference;
using pointer = typename _CommonT::pointer;
/** by default, pass anything down for initialisation of the core.
* @note especially this allows move-initialisation from an existing core.
@ -689,22 +699,30 @@ namespace lib {
explicit operator bool() const { return isValid(); }
reference
YieldRes
// reference
operator*() const
{
return _core().yield(); // core interface: yield
return _core().yield(); // core interface: yield
}
// lib::meta::enable_if_c<_CommonT::isRef,
// pointer >
pointer
operator->() const
{
return & _core().yield(); // core interface: yield
if constexpr (_CommonT::isRef)
return & _core().yield(); // core interface: yield
else
static_assert (_CommonT::isRef,
"can not provide operator-> "
"since iterator pipeline generates a value");
}
IterableDecorator&
operator++()
{
_core().iterNext(); // core interface: iterNext
_core().iterNext(); // core interface: iterNext
return *this;
}

View file

@ -320,30 +320,29 @@ namespace lib {
* helper to derive a suitable common type when expanding children
* @tparam SRC source iterator fed into the Expander
* @tparam RES result type of the expansion function
* @note this also implies the decision, if the common result
* can be exposed by-ref or must be delivered as value,
* which may have further ramification down the pipeline.
*/
template<class SRC, class RES>
struct _ExpanderTraits
{
using ResIter = typename _DecoratorTraits<RES>::SrcIter;
using SrcYield = typename ValueTypeBinding<SRC>::value_type;
using ResYield = typename ValueTypeBinding<ResIter>::value_type;
static constexpr bool can_reconcile =
has_TypeResult<common_type<SrcYield,ResYield>>();
using SrcYield = iter::Yield<SRC>;
using ResYield = iter::Yield<ResIter>;
using _CommonT = meta::CommonResultYield<SrcYield,ResYield>;
static constexpr bool can_reconcile = _CommonT::value;
static constexpr bool isRefResult = _CommonT::isRef;
static_assert (can_reconcile,
"source iterator and result from the expansion must yield compatible values");
static_assert (is_const_v<SrcYield> == is_const_v<ResYield>,
"source and expanded types differ in const-ness");
// NOTE: unfortunately std::common_type decays (strips cv and reference)
// in C++20, there would be std::common_reference; for now we have to work around that
using CommonType = conditional_t<is_const_v<SrcYield> or is_const_v<ResYield>
, const common_type_t<SrcYield,ResYield>
, common_type_t<SrcYield,ResYield>
>;
using value_type = typename ValueTypeBinding<CommonType>::value_type;
using reference = typename ValueTypeBinding<CommonType>::reference;
using pointer = typename ValueTypeBinding<CommonType>::pointer;
using YieldRes = typename _CommonT::ResType;
using value_type = typename _CommonT::value_type;
using reference = typename _CommonT::reference;
using pointer = typename _CommonT::pointer;
};
}//(End) IterExplorer traits
@ -545,6 +544,14 @@ namespace lib {
* need not be implemented in the same way, which simplifies the definition of algorithms.
* @tparam SRC the wrapped source iterator, typically a IterExplorer or nested decorator.
* @tparam FUN the concrete type of the functor passed. Will be dissected to find the signature
* @note the _return type_ of #yield depends _both_ on the return type produced from the original
* sequence and the return type of the sequence established through the expand functor.
* An attempt is made to _reconcile these_ and this attempt may fail (at compile time).
* The reason is, any further processing downstream can not tell if data was produced
* by the original sequence of the expansion sequence. Notably, if one of these two
* delivers results by-value, then the Expander will _always_ deliver all results
* by-value, because it would not be possible to expose a reference to some value
* that was just delivered temporarily from a source iterator.
*/
template<class SRC, class RES>
class Expander
@ -617,9 +624,10 @@ namespace lib {
public: /* === Iteration control API for IterableDecorator === */
/** @note result type bindings based on a common type of source and expanded result */
using YieldRes = typename _Trait::YieldRes;
using value_type = typename _Trait::value_type;
using reference = typename _Trait::reference;
using pointer = typename _Trait::pointer;
using reference = typename _Trait::reference;
using pointer = typename _Trait::pointer;
bool
@ -631,7 +639,7 @@ namespace lib {
or SRC::isValid();
}
reference
YieldRes
yield() const
{
return hasChildren()? **expansions_

View file

@ -107,6 +107,15 @@ namespace meta {
using std::__and_;
using std::__or_;
template<typename T>
static constexpr bool isConst_v = std::is_const_v<remove_reference_t<T>>;
template<typename T>
static constexpr bool isLRef_v = std::is_lvalue_reference_v<T>;
template<typename T>
static constexpr bool isRRef_v = std::is_rvalue_reference_v<T>;
template<typename T>
static constexpr bool isRef_v = std::is_reference_v<T>;
/**
* Helper for type analysis and convenience accessors:

View file

@ -119,6 +119,43 @@ namespace meta {
};
/**
* Decision helper to select between returning results by value or reference.
* - when both types can not be reconciled, not type result is provided
* - when one of both types is `const`, the `ResType` will be const
* - when both types are LValue-references, then the result will be a reference,
* otherwise the result will be a value type
*/
template<typename T1, typename T2, bool = has_TypeResult<std::common_type<T1,T2>>()>
struct CommonResultYield
: std::false_type
{ };
template<typename T1, typename T2>
struct CommonResultYield<T1, T2, true >
: std::true_type
{
using _Common = std::common_type_t<T1,T2>;
// NOTE: unfortunately std::common_type decays (strips cv and reference)
static constexpr bool isConst = isConst_v<T1> or isConst_v<T2>;
static constexpr bool isRef = isLRef_v<T1> and isLRef_v<T2>;
using _ConstT = std::conditional_t<isConst
, const _Common
, _Common
>;
using _ValRef = std::conditional_t<isRef
, std::add_lvalue_reference_t<_ConstT>
, std::remove_reference_t<_ConstT>
>;
using ResType = _ValRef;
using value_type = typename RefTraits<ResType>::Value;
using reference = typename RefTraits<ResType>::Reference;
using pointer = typename RefTraits<ResType>::Pointer;
};
}} // namespace lib::meta
#endif /*LIB_META_VALUE_TYPE_BINDING_H*/

View file

@ -312,6 +312,11 @@ return: 0
END
TEST "Lumiera state-core iteration" IterCoreAdapter_test 20 <<END
return: 0
END
TEST "forward/backward iterator" IterCursor_test 20 <<END
return: 0
END

View file

@ -0,0 +1,242 @@
/*
IterCoreAdapter(Test) - iterating over a »state core«
Copyright (C)
2024, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file iter-core-adapter-test.cpp
** unit test \ref IterCoreAdapter_test
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/util.hpp"
#include "lib/test/diagnostic-output.hpp"////////////TODO
#include "lib/iter-adapter.hpp"
//#include <boost/lexical_cast.hpp>
//#include <vector>
namespace lib {
using util::unConst;
namespace test{
using LERR_(ITER_EXHAUST);
// using boost::lexical_cast;
// using util::for_each;
// using util::isnil;
using util::isSameObject;
// using std::vector;
namespace {
/**
* A »*State Core*« to step down numbers to zero.
* @note this is a minimal description of a state progression towards a goal
* - default constructed is equivalent to _goal was reached_
* - can be copied, manipulated and compared
* - yields reference to internal state
* - no safety checks whatsoever
*/
struct StepDown
{
uint n;
StepDown(uint start =0)
: n(start)
{ }
bool
checkPoint () const
{
return n != 0;
}
uint&
yield () const
{
return util::unConst(n);
}
void
iterNext ()
{
--n;
}
bool
operator== (StepDown const& o) const
{
return n == o.n;
}
};
} // (END) impl test dummy container
/*****************************************************************//**
* @test cover the concept of a »state core«, which is used in Lumiera
* for various aspects of data generation and iteration.
* @see IterStateWrapper
* @see iter-explorer.hpp
*/
class IterCoreAdapter_test : public Test
{
virtual void
run (Arg)
{
simpleUsage();
stateManipulation();
checked_and_protected();
value_and_reference_yield();
}
/** @test build a »Lumiera Forward Iterator«
* to transition a State-Core towards it final state
*/
void
simpleUsage()
{
auto it = IterableDecorator<int, StepDown>{3};
CHECK (it);
CHECK (*it == 3);
++it;
CHECK (it);
CHECK (*it == 2);
++it;
CHECK (it);
CHECK (*it == 1);
++it;
CHECK (not it);
}
/** @test state of a decorated un-checked core can be manipulated */
void
stateManipulation()
{
auto it = IterableDecorator<int, StepDown>{};
CHECK (not it);
CHECK (*it == 0);
++it;
CHECK (*it == uint(-1));
CHECK (it);
*it = 5;
CHECK (*it == 5);
++it;
CHECK (*it == 4);
it.n = 1;
CHECK (*it == 1);
CHECK (it);
++it;
CHECK (not it);
CHECK (it.n == 0);
CHECK (isSameObject(*it, it.n));
}
/** @test additional wrappers to add safety checks
* or to encapsulate the state core altogether */
void
checked_and_protected()
{
auto cc = CheckedCore<StepDown>{2};
CHECK (cc.checkPoint());
CHECK (cc.yield() == 2u);
cc.n = 1;
CHECK (cc.yield() == 1u);
cc.iterNext();
CHECK (not cc.checkPoint());
CHECK (cc.n == 0u);
VERIFY_ERROR (ITER_EXHAUST, cc.yield() );
VERIFY_ERROR (ITER_EXHAUST, cc.iterNext() );
auto it = IterStateWrapper<uint,StepDown>{StepDown{2}};
CHECK (it);
CHECK (*it == 2u);
++it;
CHECK (*it == 1u);
++it;
CHECK (not it);
VERIFY_ERROR (ITER_EXHAUST, *it );
VERIFY_ERROR (ITER_EXHAUST, ++it );
}
/** @test adapters can (transparently) handle a core which yields values
* - demonstrate how cores can be augmented by decoration
* - the decorated core here yields by-value
* - both CheckedCore and IterableDecorator can cope with that
* - the result is then also delivered by-value from the iterator
* @remark the »Lumiera Forward Iterator« concept does not exactly specify
* what to expect when dereferencing an iterator; yet for obvious reasons,
* most iterators in practice expose a reference to some underlying container
* or internal engine state, since this is more or less the whole point of using
* an iterator: we want to expose something for manipulation, without revealing
* what it actually is (even while in most cases the implementation is visible
* for the compiler, the code using the iterator is not tightly coupled). This
* scheme has ramifications for the way any iterator pipeline works; notably
* any _transformation_ will have to capture a function result. However,
* sometimes an iterator can only return a computed value; such a usage
* can be valid and acceptable and is supported to the degree possible.
*/
void
value_and_reference_yield ()
{
struct ValueStep
: StepDown
{
using StepDown::StepDown;
int yield() const { return StepDown::yield(); }
};
auto it = IterableDecorator<int, CheckedCore<ValueStep>>{2};
CHECK (it);
CHECK (*it == 2);
CHECK (it.n == 2);
CHECK (not isSameObject(*it, it.n));
CHECK (showType<decltype(*it)>() == "int"_expect);
StepDown& ix{it};
CHECK (ix.yield() == 2u);
CHECK ( isSameObject(ix.yield(), ix.n));
CHECK ( isSameObject(ix.yield(), it.n));
CHECK (showType<decltype(ix.yield())>() == "uint&"_expect);
++it;
CHECK (*it == 1);
++it;
VERIFY_ERROR (ITER_EXHAUST, *it );
VERIFY_ERROR (ITER_EXHAUST, ++it );
}
};
LAUNCHER (IterCoreAdapter_test, "unit common");
}} // namespace lib::test

View file

@ -34,6 +34,7 @@ namespace test{
using util::join;
using util::isnil;
using util::noneg;
using LERR_(ITER_EXHAUST);
using lib::meta::forEach;
using lib::meta::mapEach;
@ -66,48 +67,6 @@ 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)
}
/*********************************************************************************//**
@ -126,7 +85,6 @@ SHOW_TYPE(R2)
virtual void
run (Arg)
{
plonk();
simpleUsage();
test_Fixture();
demo_mapToTuple();
@ -135,6 +93,7 @@ SHOW_TYPE(R2)
verify_iteration();
verify_references();
verify_pipelining();
verify_exploration();
}
@ -485,7 +444,140 @@ SHOW_TYPE(R2)
return a+b+c;
})
== 6+15+24+33+42);
SHOW_EXPR(TYPE(izip(num31())))
}
template<typename T1, typename T2>
void
resu()
{ MARK_TEST_FUN
using RT = meta::CommonResultYield<T1,T2>;
SHOW_EXPR(RT())
if constexpr (RT())
{
SHOW_EXPR(RT::isConst)
SHOW_EXPR(RT::isRef)
SHOW_TYPE(typename RT::_Common )
SHOW_TYPE(typename RT::_ConstT )
SHOW_TYPE(typename RT::_ValRef )
SHOW_TYPE(typename RT::ResType )
SHOW_TYPE(typename RT::reference)
}
}
/** @test verify the interplay of _child expansion_ and tuple-zipping.
* @remark the expansion mechanism implies that a _child sequence_ is generated
* by an _expand functor,_ based on the current iterator value at that point.
* The tricky part here is that this expand functor can sit somewhere in the
* source iterators, while the actual signal to expand is sent from »downstream«
* and has to be propagated to all children.
* Thus two expander-setups are demonstrated first, and then triggered from
* a combined iterator, dispatching the trigger over the tuple-zipping step.
* - the expansion-sequences unfold the same in each case
* - the shortest sequence terminates the overall zip()-evaluation
* - when generating the `expandChildrem()` call _after_ the `zip()`,
* it is also passed to other iterators that have no expand-functor defined;
* for those, it is absorbed without effect. Now, since the expandAll()
* actually works by replacing the iterate() by expandChildern(), this means
* that the _other sequences_ just do not make any progress.
*/
void
verify_exploration()
{
/*
resu<string,string>();
resu<string&,string>();
resu<string&,string&>();
resu<string&&,string&&>();
resu<string const&,string const&>();
resu<int, long const&>();
resu<double&, long const&>();
resu<int, string>();
resu<int, long*>();
*/
CHECK (materialise (
num31()
)
== "1-4-7-10-13"_expect);
CHECK (materialise (
explore(num31())
.expand ([](int i){ return NumIter{noneg(i-1),i}; })
.expandAll()
)
== "1-0-4-3-2-1-0-7-6-5-4-3-2-1-0-10-9-8-7-6-5-4-3-2-1-0-13-12-11-10-9-8-7-6-5-4-3-2-1-0"_expect);
CHECK (materialise (
explore(num31())
.expand ([](int i){ return NumIter{noneg(i-2),i-1}; })
.expandAll()
)
== "1-4-2-0-7-5-3-1-10-8-6-4-2-0-13-11-9-7-5-3-1"_expect);
CHECK (materialise (
zip
( eachNum(10)
, explore(num31())
.expand ([](int i){ return NumIter{noneg(i-1),i}; })
.expandAll()
, explore(num31())
.expand ([](int i){ return NumIter{noneg(i-2),i-1}; })
.expandAll()
)
)
== "«tuple<int, uint, uint>»──(10,1,1)-"
"«tuple<int, uint, uint>»──(11,0,4)-"
"«tuple<int, uint, uint>»──(12,4,2)-"
"«tuple<int, uint, uint>»──(13,3,0)-"
"«tuple<int, uint, uint>»──(14,2,7)-"
"«tuple<int, uint, uint>»──(15,1,5)-"
"«tuple<int, uint, uint>»──(16,0,3)-"
"«tuple<int, uint, uint>»──(17,7,1)-"
"«tuple<int, uint, uint>»──(18,6,10)-"
"«tuple<int, uint, uint>»──(19,5,8)-"
"«tuple<int, uint, uint>»──(20,4,6)-"
"«tuple<int, uint, uint>»──(21,3,4)-"
"«tuple<int, uint, uint>»──(22,2,2)-"
"«tuple<int, uint, uint>»──(23,1,0)-"
"«tuple<int, uint, uint>»──(24,0,13)-"
"«tuple<int, uint, uint>»──(25,10,11)-"
"«tuple<int, uint, uint>»──(26,9,9)-"
"«tuple<int, uint, uint>»──(27,8,7)-"
"«tuple<int, uint, uint>»──(28,7,5)-"
"«tuple<int, uint, uint>»──(29,6,3)-"
"«tuple<int, uint, uint>»──(30,5,1)"_expect);
CHECK (materialise (
zip
( eachNum(10)
, explore(num31())
.expand ([](int i){ return NumIter{noneg(i-1),i}; })
, explore(num31())
.expand ([](int i){ return NumIter{noneg(i-2),i-1}; })
)
.expandAll() // ◁──────────┲━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ note the difference: expand triggered after the zip()
) // ▽
== "«tuple<int, uint, uint>»──(10,1,1)-"
"«tuple<int, uint, uint>»──(10,0,4)-"
"«tuple<int, uint, uint>»──(10,4,2)-"
"«tuple<int, uint, uint>»──(10,3,0)-"
"«tuple<int, uint, uint>»──(10,2,7)-"
"«tuple<int, uint, uint>»──(10,1,5)-"
"«tuple<int, uint, uint>»──(10,0,3)-"
"«tuple<int, uint, uint>»──(10,7,1)-"
"«tuple<int, uint, uint>»──(10,6,10)-"
"«tuple<int, uint, uint>»──(10,5,8)-"
"«tuple<int, uint, uint>»──(10,4,6)-"
"«tuple<int, uint, uint>»──(10,3,4)-"
"«tuple<int, uint, uint>»──(10,2,2)-"
"«tuple<int, uint, uint>»──(10,1,0)-"
"«tuple<int, uint, uint>»──(10,0,13)-"
"«tuple<int, uint, uint>»──(10,10,11)-"
"«tuple<int, uint, uint>»──(10,9,9)-"
"«tuple<int, uint, uint>»──(10,8,7)-"
"«tuple<int, uint, uint>»──(10,7,5)-"
"«tuple<int, uint, uint>»──(10,6,3)-"
"«tuple<int, uint, uint>»──(10,5,1)"_expect);
}
/*
SHOW_EXPR

View file

@ -19570,9 +19570,7 @@
<node CREATED="1665873092646" ID="ID_764903267" MODIFIED="1665873111767" TEXT="reduziert sich auf ein Label + einen pop-up-Menu-Provider"/>
<node CREATED="1665873149175" ID="ID_329681558" MODIFIED="1665873228305" TEXT="(optional) Pivot-Content">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Ein Stichwort, eine (ggfs. dynamische) Kurzinformation, ein pivot-Frame als Erkennungszeichen
@ -19956,9 +19954,7 @@
<icon BUILTIN="broken-line"/>
<node CREATED="1665972027480" ID="ID_1481599747" MODIFIED="1665972094845">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<font color="#f12b4f"><b>ASSERTION</b></font>&#160;: widget mu&#223; bereits realized sein
@ -20417,9 +20413,7 @@
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...und das hei&#223;t, wir betreiben ggfs sogar erheblichen Aufwand,
@ -20870,9 +20864,7 @@
</node>
<node CREATED="1573944816092" ID="ID_1520827984" MODIFIED="1575057093965" TEXT="k&#xf6;nnte man auf diese Design-Elemente verzichten?">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...wohl ehr nicht, aber sie sind nicht allgemeing&#252;ltig, das ist das Problem
@ -21879,9 +21871,7 @@
<icon BUILTIN="yes"/>
<node CREATED="1575132543936" ID="ID_427533687" MODIFIED="1576282358091" TEXT="im urspr&#xfc;nglichen Design hat mich der Canvas auf eine falsche Spur geschickt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
denn auch der Canvas ist ein Gtk::Container und hat eine Liste von Widgets
@ -23279,9 +23269,7 @@
</node>
<node CREATED="1541862056646" ID="ID_262489955" MODIFIED="1557498707226">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Widgets arbeiten <b>stets in Pixeln</b>
@ -26362,9 +26350,7 @@
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1576705150754" FOLDED="true" ID="ID_584153731" MODIFIED="1576973221801" TEXT="bestehendes Design mu&#xdf; &quot;justiert&quot; werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
....sonst wird es zur Sackgasse.
@ -37003,9 +36989,7 @@
</node>
<node CREATED="1533221681199" ID="ID_979914270" MODIFIED="1576282358027" TEXT="Folge unserer Architektur">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
denn es ist gradezu der Sinn von Glib::Dispatcher,
@ -39957,9 +39941,7 @@
<node CREATED="1542384165737" ID="ID_705415129" MODIFIED="1557498707233" TEXT="die konkret sichbare TimeSpan"/>
<node CREATED="1542384188438" ID="ID_444895141" MODIFIED="1576282358023" TEXT="stets in realem relativem Zeitma&#xdf;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<ul>
<li>
@ -41221,9 +41203,7 @@
</node>
<node COLOR="#990000" CREATED="1667747539288" ID="ID_1951969589" MODIFIED="1667754024155" TEXT="naiver-Ansatz: ein ULP abziehen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
da wird die Rechnung schwierig, denn ich kann es nicht ohne Weiteres mathematisch greifen....
@ -42270,9 +42250,7 @@
<icon BUILTIN="help"/>
<node CREATED="1670513034252" ID="ID_1850302207" MODIFIED="1670513344405" TEXT="nein, aber man kann sie verbessern">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...zwar ist der Bias in Richtung auf ein gr&#246;&#223;eres Fenster weiterhin im Code gegeben, aber dieser Fall hier zeigt eben, da&#223; er durch andere Rundungs-Effekte sogar &#252;bersteuert werden kann; aber wir k&#246;nnen sogar eine st&#228;rkere Bedinung errichten, n&#228;mlich da&#223; wir nicht zu weit von der Vorgabe abweichen
@ -42736,9 +42714,7 @@
</node>
<node COLOR="#435e98" CREATED="1670634676452" ID="ID_829552595" MODIFIED="1670642079860">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<b>Grund</b>&#160;sind die expliziten <i>Limitierungen </i>in dieser Funktion
@ -43224,9 +43200,7 @@
</node>
<node COLOR="#435e98" CREATED="1670889380176" ID="ID_390014316" MODIFIED="1670889436751" TEXT="finde nur einen Tesfall der ohne Optimierung / detox genau aufgeht">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
1000_r/LIM_HAZARD * 1024_r/1023
@ -43555,9 +43529,7 @@
<node CREATED="1668293830823" ID="ID_615954964" MODIFIED="1668293953957" TEXT="danach kann man den Z&#xe4;hler noch limitieren"/>
<node CREATED="1668293939617" ID="ID_1509248321" MODIFIED="1668293997256" TEXT="das verf&#xe4;lscht dann zwar die Ergebnisse ">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...aber ein Z&#228;hler &gt; INT_MAX / Time::SCALE kann unm&#246;glich sinnvoll weiterverarbeitet werden, und au&#223;erdem sollte er f&#252;r eine Metrik gar nicht auftreten k&#246;nnen, weil die Metrik ja relativ stark in der Gr&#246;&#223;e beschr&#228;nkt ist
@ -52753,13 +52725,12 @@
</node>
<node CREATED="1732220536045" ID="ID_1165298197" MODIFIED="1732220565132" TEXT="implementiert die Produkt-Operationen durch Delegieren"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732221642486" ID="ID_1450873226" MODIFIED="1732233711887" TEXT="neues Problem: expander-Kollaborations-API weitergeben">
<node COLOR="#435e98" CREATED="1732221642486" ID="ID_1450873226" MODIFIED="1732488888160" 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="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 COLOR="#435e98" CREATED="1732221711745" ID="ID_1004997061" MODIFIED="1732489026963" TEXT="&#x27f9; M&#xf6;glichkeit zur Anpassung des Base-Adapters schaffen">
<arrowlink COLOR="#4129a2" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="-276;-254;" ID="Arrow_ID_125112633" STARTARROW="None" STARTINCLINATION="-524;25;"/>
</node>
</node>
<node CREATED="1732233745033" ID="ID_214181349" MODIFIED="1732233786889" TEXT="daraus das Value-Tuple per Transformer erzeugen">
@ -52833,21 +52804,23 @@
</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 COLOR="#338800" CREATED="1732404219427" FOLDED="true" ID="ID_87985222" MODIFIED="1732489122964" TEXT="Adapter-Generierung neu ordnen">
<linktarget COLOR="#4129a2" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="-276;-254;" ID="Arrow_ID_125112633" SOURCE="ID_1004997061" STARTARROW="None" STARTINCLINATION="-524;25;"/>
<linktarget COLOR="#599ced" DESTINATION="ID_87985222" ENDARROW="Default" ENDINCLINATION="180;171;" ID="Arrow_ID_1403487927" SOURCE="ID_1051749303" STARTARROW="None" STARTINCLINATION="425;-32;"/>
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732404405058" ID="ID_912348266" MODIFIED="1732489063402" TEXT="Feststellungen">
<icon BUILTIN="forward"/>
<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 COLOR="#435e98" CREATED="1732405205696" ID="ID_474793959" MODIFIED="1732489043595" TEXT="ich ziehe hier vor, auf explizite Type-Tags zu setzen">
<icon BUILTIN="yes"/>
<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="1732405282395" ID="ID_1720349507" MODIFIED="1732488878408" TEXT="zwei neue Aufbereitungs-Schritte">
<icon BUILTIN="button_ok"/>
<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">
@ -52872,8 +52845,7 @@
andere Tricks mit der _rawCore()-Zugriffsfunktion scheinen nicht zu gehen
</p>
</body>
</html>
</richcontent>
</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>
@ -52904,6 +52876,7 @@
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732487170847" ID="ID_1262167504" MODIFIED="1732487199877" TEXT="Ergebnis: nun viel schlankere und minimale Typ-Schachtelung">
<linktarget COLOR="#67697e" DESTINATION="ID_1262167504" ENDARROW="Default" ENDINCLINATION="-307;14;" ID="Arrow_ID_1075091501" SOURCE="ID_1811172733" STARTARROW="None" STARTINCLINATION="163;-136;"/>
<icon BUILTIN="forward"/>
<node CREATED="1732487344743" HGAP="31" ID="ID_488136081" MODIFIED="1732487803727" STYLE="bubble" VSHIFT="11">
<richcontent TYPE="NODE"><html>
@ -53135,6 +53108,7 @@
<icon BUILTIN="broken-line"/>
</node>
<node COLOR="#5b280f" CREATED="1732323357278" ID="ID_1689757044" MODIFIED="1732327891664" TEXT="unm&#xf6;glich da wir effektiv nur einen Ausgabepfad haben">
<arrowlink COLOR="#6f141e" DESTINATION="ID_738246140" ENDARROW="Default" ENDINCLINATION="194;-414;" ID="Arrow_ID_768211036" STARTARROW="None" STARTINCLINATION="507;142;"/>
<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"/>
@ -53142,7 +53116,7 @@
<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">
<node CREATED="1732323615259" ID="ID_183489075" MODIFIED="1732499554636" TEXT="wollte man hier flexibel sein, ginge das stets nur an der Au&#xdf;engrenze">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -53176,47 +53150,62 @@
<node COLOR="#435e98" CREATED="1732308679924" ID="ID_762659981" MODIFIED="1732308713186" TEXT="sollte eine For-Schleife zeigen"/>
<node COLOR="#435e98" CREATED="1732308687234" ID="ID_981998183" MODIFIED="1732308713186" TEXT="sollte direkten Gebrauch als Iterator sichtbar machen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235323997" ID="ID_1085200650" MODIFIED="1732235555231" TEXT="Iteratoren verschiedenen Typs">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1732235323997" ID="ID_1085200650" MODIFIED="1732584375034" TEXT="Iteratoren verschiedenen Typs">
<icon BUILTIN="button_ok"/>
<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"/>
<node CREATED="1732313547158" ID="ID_1297222060" MODIFIED="1732313551929" TEXT="STL-Container"/>
<node CREATED="1732313554272" ID="ID_628954162" MODIFIED="1732313557682" TEXT="State-Core"/>
<node CREATED="1732313559148" ID="ID_888513620" MODIFIED="1732313564479" TEXT="IterSource"/>
<node COLOR="#338800" CREATED="1732313524489" ID="ID_824059713" MODIFIED="1732584368643" TEXT="Sequenzen verschiedener L&#xe4;nge">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732313533659" ID="ID_1229132868" MODIFIED="1732584370123" TEXT="verschiedene Quellen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1732313542680" ID="ID_918133774" MODIFIED="1732584373490" TEXT="Lumiera-Iterator"/>
<node COLOR="#435e98" CREATED="1732313547158" ID="ID_1297222060" MODIFIED="1732584373490" TEXT="STL-Container"/>
<node COLOR="#435e98" CREATED="1732313554272" ID="ID_628954162" MODIFIED="1732584373490" TEXT="State-Core"/>
<node COLOR="#435e98" CREATED="1732313559148" ID="ID_888513620" MODIFIED="1732584373489" TEXT="IterSource"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235343138" ID="ID_1943784376" MODIFIED="1732235555231" TEXT="per structured Binding verarbeiten">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1732235343138" ID="ID_1943784376" MODIFIED="1732584376431" TEXT="per structured Binding verarbeiten">
<icon BUILTIN="button_ok"/>
</node>
<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="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1732332677537" ID="ID_800914951" MODIFIED="1732332688213" TEXT="nachgeschaltete Pipeline">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1732332677537" ID="ID_800914951" MODIFIED="1732489241725" TEXT="nachgeschaltete Pipeline">
<icon BUILTIN="button_ok"/>
<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">
<node COLOR="#435e98" CREATED="1732333449943" ID="ID_1811172733" MODIFIED="1732489128888" TEXT="Beobachtung: direkt gegebener IterExplorer wird nochmal gewrapped">
<arrowlink COLOR="#67697e" DESTINATION="ID_1262167504" ENDARROW="Default" ENDINCLINATION="-307;14;" ID="Arrow_ID_1075091501" STARTARROW="None" STARTINCLINATION="163;-136;"/>
<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;"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732333481816" ID="ID_488310307" MODIFIED="1732489228315" TEXT="das ist unsch&#xf6;n">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...auch wenn es normalerweise kein Performance-Problem darstellt, weil der Optimiser redundante Aufrufe problemlos eliminiert, macht es die Typen f&#252;r den Au&#223;enstehend noch viel undurchtringbarer, und belastet auch die Debug-Builds durch den Umfang unn&#246;tiger Typ-Information
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="smily_bad"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732333491869" ID="ID_34490328" MODIFIED="1732489232938" TEXT="...und w&#xfc;rde das Durchreichen eines Child-Expanders verhindern">
<arrowlink COLOR="#7d7a99" DESTINATION="ID_1051749303" ENDARROW="Default" ENDINCLINATION="47;-71;" ID="Arrow_ID_922384929" STARTARROW="None" STARTINCLINATION="-576;25;"/>
<icon BUILTIN="broken-line"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1732332721552" ID="ID_884561005" MODIFIED="1732380040032" TEXT="erstes Ausgabetupel enth&#xe4;lt uninitialisierte Werte">
<node COLOR="#435e98" CREATED="1732332721552" FOLDED="true" 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">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732335037680" ID="ID_883671623" MODIFIED="1732488924547" 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">
<node BACKGROUND_COLOR="#e2ba5e" COLOR="#b70624" CREATED="1732334924952" ID="ID_1746517643" MODIFIED="1732488958484" 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"/>
@ -53261,8 +53250,7 @@
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>
</html></richcontent>
</node>
</node>
<node CREATED="1732336967005" ID="ID_643449650" MODIFIED="1732337008685">
@ -53312,8 +53300,7 @@
<font size="5">das Design hat hier eine </font><font size="5" color="#c20c49">Schwachstelle</font>
</p>
</body>
</html>
</richcontent>
</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>
@ -53324,12 +53311,226 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732235523602" ID="ID_1940842867" MODIFIED="1732235555232" TEXT="Durchgriff auf Child-Expander im Quell-Iterator">
<node COLOR="#338800" CREATED="1732235523602" ID="ID_1940842867" MODIFIED="1732577239677" TEXT="Durchgriff auf Child-Expander im Quell-Iterator">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1732404127247" ID="ID_1051749303" MODIFIED="1732489015844" TEXT="setzt Anpassungen an den Adaptern voraus">
<arrowlink COLOR="#599ced" 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="47;-71;" ID="Arrow_ID_922384929" SOURCE="ID_34490328" STARTARROW="None" STARTINCLINATION="-576;25;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1732489248682" ID="ID_1208683398" MODIFIED="1732489263569" TEXT="BaseAdapter wird nun &#xfc;berhaupt nur einmal pro Pipeline eingef&#xfc;gt"/>
<node CREATED="1732489265869" ID="ID_454730383" MODIFIED="1732489281623" TEXT="und ob er noch eingef&#xfc;gt wird, l&#xe4;&#xdf;t sich &#xfc;ber ein Typ-Tag steuern"/>
<node CREATED="1732489282051" ID="ID_1170202318" MODIFIED="1732489328431" TEXT="eine custom-Core (wie hier) kann also die Rolle eines Base-Adapter explizit &#xfc;bernehmen">
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732489334100" ID="ID_744918133" MODIFIED="1732489351281" TEXT="das eigentliche Weiterleiten der Aufrufe ist trivial einfach zu implementieren">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1732489352034" ID="ID_1389747588" MODIFIED="1732489361393" TEXT="Testen ist m&#xfc;hsam....">
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1732499374948" ID="ID_1694141748" MODIFIED="1732576950165" TEXT="geht schon los mit....">
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1732499382404" ID="ID_298429500" MODIFIED="1732499641690" TEXT="...dem Umstand, da&#xdf; der Expander nicht auf Value-Result funktioniert">
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732499558508" ID="ID_738246140" MODIFIED="1732499660372" TEXT="hatte das schon einmal vor ein paar Tagen erfolglos untersucht">
<linktarget COLOR="#6f141e" DESTINATION="ID_738246140" ENDARROW="Default" ENDINCLINATION="194;-414;" ID="Arrow_ID_768211036" SOURCE="ID_1689757044" STARTARROW="None" STARTINCLINATION="507;142;"/>
<icon BUILTIN="broken-line"/>
</node>
<node CREATED="1732499692888" ID="ID_1624652047" MODIFIED="1732499711525" TEXT="der Expander enth&#xe4;lt eines dieser hart-gecodeten &quot;reference&quot;-Typen">
<node CREATED="1732499718302" ID="ID_1327516976" MODIFIED="1732499730864" TEXT="dabei w&#xfc;rde es hier gehen"/>
<node CREATED="1732499731453" ID="ID_524965988" MODIFIED="1732499744446" TEXT="sofern man sinnvoll auf einen kleinsten gemeinsamen Nenner zur&#xfc;ckf&#xe4;llt"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1732499748626" ID="ID_73007932" MODIFIED="1732576975282" TEXT="nochmal untersuchen: k&#xf6;nnen wir Value-Ergebnisse aus der Pipeline unterst&#xfc;tzen?">
<icon BUILTIN="help"/>
<node COLOR="#435e98" CREATED="1732499767002" ID="ID_1245640841" MODIFIED="1732576658405" TEXT="Problem-1 : der operator-&gt;">
<node CREATED="1732499786605" ID="ID_1510842318" MODIFIED="1732499805038" TEXT="diesen m&#xfc;&#xdf;te man dann per conditional-Definiton entfernen"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732499810538" ID="ID_1382366845" MODIFIED="1732576617138" TEXT="vielleicht ist das akzeptabel (Konsequenzen noch nicht klar...)">
<icon BUILTIN="help"/>
<node COLOR="#435e98" CREATED="1732576620377" ID="ID_801036210" MODIFIED="1732576650829" TEXT="die code-Basis jedenfalls compiliert weiterhin"/>
<node COLOR="#435e98" CREATED="1732576632416" ID="ID_1935979671" MODIFIED="1732576647957" TEXT="noch einen static_assert eingebaut f&#xfc;r bessere Fehlermeldung"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1732499843557" ID="ID_1131882712" MODIFIED="1732576661348" TEXT="Problem-2 : mu&#xdf; zwischen Value/Ref umschalten k&#xf6;nnen">
<node CREATED="1732499861875" ID="ID_297864909" MODIFIED="1732499878292" TEXT="brauche effektiv einen weiteren &#xbb;Ausgabekanal&#xab; &#xfc;ber den Typ"/>
<node CREATED="1732499879180" ID="ID_152140001" MODIFIED="1732576772094" TEXT="denkbar: wenn die R&#xfc;ckgabetypen aufeinander aufbauen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...dann w&#252;rden wir eine ganze Pipeline &#187;flippen&#171; k&#246;nnen, wenn der erste Result-Typ auf Value schwenkt
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1732499895991" ID="ID_1513249083" MODIFIED="1732500014771" TEXT="die Pipeline ist jetzt hinreichend aufger&#xe4;umt">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
habe die mehrfachen Adapter nun allesamt weg; daher w&#228;re es nun doch denkbar, da die Call-Pfade nun von einem Punkt aus aufspalten (n&#228;mlich Core::yield -&gt;&#160;&#160;entweder operator* oder operator-&gt; )
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732576781381" ID="ID_452524052" MODIFIED="1732576819125" TEXT="effektiv l&#xe4;d das das Problem bei konkreten Transformationen und Pr&#xe4;dikaten ab">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1732576832125" ID="ID_443099186" MODIFIED="1732576877954" TEXT="...denn eine Funktion non-const-Referenzen nimmt, scheitert"/>
<node CREATED="1732576887573" ID="ID_687212437" MODIFIED="1732576907676" TEXT="erscheint akzepabel, da das i.d.R Lambdas f&#xfc;r den Einzelfall sind"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732500030252" ID="ID_1233066521" MODIFIED="1732576600199" TEXT="Proof-of-Concept machen">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1732500037694" ID="ID_1099507221" MODIFIED="1732576467794" TEXT="neues Trait: lib::meta::CommonResultYield">
<icon BUILTIN="yes"/>
<node COLOR="#435e98" CREATED="1732500063864" ID="ID_1307133504" MODIFIED="1732576476301" TEXT="mithilfe von std::common_type implementieren">
<icon BUILTIN="idea"/>
<node CREATED="1732576477599" ID="ID_724368575" MODIFIED="1732576484055" TEXT="das hat so seine Schw&#xe4;chen"/>
<node CREATED="1732576490514" ID="ID_43853125" MODIFIED="1732576498906" TEXT="im Besonderen impliziert es std::decay()"/>
</node>
<node COLOR="#338800" CREATED="1732500078558" ID="ID_1560553142" MODIFIED="1732576505729" TEXT="explizit die const-Ness und Referenz steuern">
<icon BUILTIN="button_ok"/>
<node CREATED="1732500096323" ID="ID_295136585" MODIFIED="1732500101720" TEXT="const wenn einer der beiden Typen const"/>
<node CREATED="1732500102266" ID="ID_910645487" MODIFIED="1732500113788" TEXT="(L)Ref nur wenn beider Typen LRef"/>
</node>
<node COLOR="#338800" CREATED="1732500120132" ID="ID_1315885808" MODIFIED="1732576513152" TEXT="saubere Funktionsweise erst mal isoliert testen">
<icon BUILTIN="button_ok"/>
<node CREATED="1732505350051" ID="ID_120652623" MODIFIED="1732505403271">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Booo!&#160;&#160;<font face="Monospaced" color="#582e24">is_const_v&lt;T&amp;&gt;</font>&#160;ist <b><font color="#e00b0b">immer false</font></b>
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1732573450476" ID="ID_1325209644" MODIFIED="1732573474740" TEXT="und X &amp; const &#x2260; X const&amp;"/>
<node CREATED="1732576525640" ID="ID_1638928832" MODIFIED="1732576557732" TEXT="tja">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
ruck-zuck ein paar Stunden weg ... h&#228;tte man doch gleich einen Test geschrieben
</p>
</body>
</html></richcontent>
<icon BUILTIN="smily_bad"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732584495255" ID="ID_910412701" MODIFIED="1732584527089" TEXT="&#x27f6; eigens als Test dokumentieren">
<arrowlink COLOR="#d41c27" DESTINATION="ID_1750877358" ENDARROW="Default" ENDINCLINATION="1071;0;" ID="Arrow_ID_626641268" STARTARROW="None" STARTINCLINATION="364;29;"/>
<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;"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732576300069" ID="ID_1496960816" MODIFIED="1732576458151" TEXT="IterableDecorator flexibel machen : hier Vorgabe (referenz) &#x27f7; tats&#xe4;chliches yield()">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732576329179" ID="ID_67215000" MODIFIED="1732576459743" TEXT="Typ-Logik in iter_explorer::Expander auf CommonResultYield umstellen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1732576979521" ID="ID_193097642" MODIFIED="1732576987652" TEXT="Fazit">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="forward"/>
<node CREATED="1732576989241" ID="ID_597816803" MODIFIED="1732577212565" TEXT="technisch ohne Weiteres m&#xf6;glich">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<ul>
<li>
dediziertes Trait schaffen
</li>
<li>
Propagations-Logik explizit auscoden
</li>
<li>
den operator-&gt; auf Values weglassen bzw mit compile-Fehler unterdr&#252;cken
</li>
</ul>
</body>
</html>
</richcontent>
</node>
<node CREATED="1732576997102" ID="ID_1924173493" MODIFIED="1732577133634" TEXT="bestehendes System dadurch nicht gef&#xe4;hrdet">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...da bisher alles auf R&#252;ckgabe by-ref ausgelegt ist, und dieser Fall deshalb durch die &#196;nderung ohne Modifikation durchgereicht wird
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1732577018219" ID="ID_226679397" MODIFIED="1732577103664" TEXT="man k&#xf6;nnte wagen, diese Variante ebenfalls zuzulassen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
es wird vermutlich auf wenige F&#228;lle beschr&#228;nkt bleiben, in denen es aber durchaus hilfreich ist, da sowohl Generatoren als auch Transformatoren einfacher zu schreiben sind
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1732576921726" ID="ID_23499408" MODIFIED="1732576947137" TEXT="OK &#x27f9; kann nun sehr einfach eine depth-first-exploration demonstrieren">
<icon BUILTIN="ksmiletris"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1732576952252" ID="ID_115461255" MODIFIED="1732577229895" TEXT="der Rest ist gar nicht m&#xfc;hsam sondern funktioniert auf Anhieb">
<icon BUILTIN="smiley-oh"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732577241029" ID="ID_994951030" MODIFIED="1732577657422" TEXT="best&#xe4;tigt: funktioniert">
<icon BUILTIN="button_ok"/>
<node CREATED="1732577251908" ID="ID_313126773" MODIFIED="1732577264497" TEXT="verwende zwei komplett verschieden arbeitende Expander"/>
<node COLOR="#435e98" CREATED="1732577265065" ID="ID_1527782902" MODIFIED="1732577661937" TEXT="Fall-1 : autoExpand unterhalb der zip()-Operation"/>
<node COLOR="#435e98" CREATED="1732577580608" ID="ID_88998768" MODIFIED="1732577661937" TEXT="Fall-2 : autoExpand oberhalb der zip()-Operation erzeugen">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1732577599605" HGAP="27" ID="ID_52497187" MODIFIED="1732577651345" TEXT="&#x27f8; Unterschied: die Sequenz ohne Expander bleibt stehen" VSHIFT="12">
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#338800" CREATED="1732577638050" ID="ID_288695828" MODIFIED="1732577734390" TEXT="das ist korrekt so">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
der auto-Expander kann und darf ja nicht wissen, wo genau unterhalb die Expansion stattfindet; wenn eben gar keine stattfindet, dann bleiben alle durchgereichten expandChildren()-Aufrufe ohne Wirkung, aber ein iterNext() wird dann auch nicht mehr gesendet
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1732584380577" ID="ID_907702003" MODIFIED="1732584406718" TEXT="nebenbei: IterableDecorator ist nun flexibler &#x27f6; Test">
<icon BUILTIN="yes"/>
<node CREATED="1732584408909" ID="ID_1774747868" MODIFIED="1732584416008" TEXT="iter-core-adapter-test.cpp">
<node CREATED="1732584417772" ID="ID_710320129" MODIFIED="1732584430262" TEXT="weil das eigentlich mit dem Thema &#xbb;State Core&#xab; zu tun hat"/>
<node CREATED="1732584430730" ID="ID_1543136731" MODIFIED="1732584440733" TEXT="...wof&#xfc;r es bisher gar keine Tests gab">
<icon BUILTIN="smiley-neutral"/>
</node>
</node>
<node COLOR="#338800" CREATED="1732584446602" ID="ID_72717134" MODIFIED="1732584461134" TEXT="sollte dann auch gleich mal die Grundmuster mit dokumentieren">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1732584463118" ID="ID_1750877358" MODIFIED="1732584522136" TEXT="Testfall mit den Typkonvertierungen extrahieren">
<linktarget COLOR="#d41c27" DESTINATION="ID_1750877358" ENDARROW="Default" ENDINCLINATION="1071;0;" ID="Arrow_ID_626641268" SOURCE="ID_910412701" STARTARROW="None" STARTINCLINATION="364;29;"/>
<icon BUILTIN="flag-pink"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732584616649" ID="ID_1631761913" MODIFIED="1732584728444" TEXT="aufr&#xe4;umen...">
<icon BUILTIN="bell"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732584624472" ID="ID_447849996" MODIFIED="1732584637215" TEXT="Typ-Parameter von IterStateWrapper">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1732584638326" ID="ID_200640906" MODIFIED="1732584651480" TEXT="der default auf dem 2.Parameter macht selten Sinn"/>
<node CREATED="1732584652068" ID="ID_1279596515" MODIFIED="1732584668049" TEXT="kann man den Typ-Parameter deduzierbar machen?"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1732584709076" ID="ID_1502894530" MODIFIED="1732584720741" TEXT="Kommentare in iter-adapter">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>