Library: develop a flattening primitive for IterExplorer
This is a feature I wasn’t sure for a long time how best to tackle. It’s worth noting that an initial attempt at `IterExplorer` was based on the monad pattern, which turned out to be a mistake, since monads are more of an anti-pattern, than being genuinely useful. The actual use-case that made me reconsider such a feature it to build an seamlessly chained sequence from several iterators. It would be simple to develop a suitable utility as a stand-alone helper, yet it seemed worth the effort to integrate this into the `IterExplorer` ecosystem, due to the flexible automatic adaptation to iterable source pipelines provided therein. Going this route incurred some cost however, unveiling several defects related to handling nested iterable types in the generic processing framework.
This commit is contained in:
parent
0326f9e85d
commit
00098dd815
6 changed files with 1023 additions and 33 deletions
|
|
@ -198,7 +198,7 @@ namespace lib {
|
|||
using meta::RefTraits;
|
||||
|
||||
|
||||
/** type binding helper: an iterato's actual result type */
|
||||
/** type binding helper: an iterator's actual result type */
|
||||
template<class IT>
|
||||
using Yield = decltype(std::declval<IT>().operator*());
|
||||
|
||||
|
|
@ -207,15 +207,14 @@ namespace lib {
|
|||
using CoreYield = decltype(std::declval<COR>().yield());
|
||||
|
||||
|
||||
/** some legacy STL type iterators do not strictly fulfil all requirements,
|
||||
* yet were marked by a specialisation of `std::iterator_traits` */
|
||||
template<class IT>
|
||||
concept legacy_traits_marked = requires
|
||||
{
|
||||
typename std::iterator_traits<IT>::value_type;
|
||||
typename std::iterator_traits<IT>::iterator_category;
|
||||
};
|
||||
|
||||
template<class IT>
|
||||
concept stl_iter = std::input_iterator<IT> or legacy_traits_marked<IT>;
|
||||
|
||||
|
||||
/** Iterator-Traits: definitions to level the difference between
|
||||
* Lumiera-Iterators and the STL usage of ranges / iterators.
|
||||
|
|
@ -224,9 +223,11 @@ namespace lib {
|
|||
struct Trait
|
||||
{
|
||||
static constexpr bool is_LumieraIter = can_IterForEach<IT>::value;
|
||||
static constexpr bool is_STLIter = stl_iter<IT>;
|
||||
static constexpr bool is_STLIter = std::input_iterator<IT>;
|
||||
static constexpr bool is_Legacy = legacy_traits_marked<IT>;
|
||||
|
||||
static_assert(is_LumieraIter or is_STLIter, "source type must be an iterator");
|
||||
static_assert(is_LumieraIter or is_STLIter or is_Legacy
|
||||
,"source type must be an iterator (either Lumiera or STL");
|
||||
|
||||
using _ValTrait = std::conditional_t<is_LumieraIter, ValueTypeBinding<IT>
|
||||
, RefTraits<std::iter_reference_t<IT>>>;
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
*/
|
||||
|
||||
/** @file iter-explorer.hpp
|
||||
** Building tree expanding and backtracking evaluations within hierarchical scopes.
|
||||
** Build tree expanding and backtracking evaluations within hierarchical scopes.
|
||||
** Based on the *Lumiera Forward Iterator* concept and using the basic IterAdapter templates,
|
||||
** these components allow to implement typical evaluation strategies, like conditional expanding
|
||||
** or depth-first exploration of a hierarchical structure. Since the access to this structure is
|
||||
** abstracted through the underlying iterator, what we effectively get is a functional datastructure.
|
||||
** The implementation is based on the idea of a "state core", which is wrapped right into the iterator
|
||||
** itself (value semantics) -- similar to the IterStateWrapper, which is one of the basic helper templates
|
||||
** The implementation is based on the idea of a **State Core**, which is wrapped right into the iterator
|
||||
** itself (value semantics) — similar to the IterStateWrapper, which is one of the basic helper templates
|
||||
** provided by iter-adapter.hpp.
|
||||
**
|
||||
** @remark historically, this template, as well as the initial IterExplorer (draft from 2012) can be
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
** calculations with exception handling but also simple data structures like lists or trees). The key point with any
|
||||
** monad is the ability to _bind a function_ into the monad; this function will work on the _contained base values_
|
||||
** and produce a modified new monad instance. In the simple case of a list, "binding" a function basically means
|
||||
** to _map the function onto_ the elements in the list. (strictly speaking, it means the `flatMap` operation)
|
||||
** to _map the function onto_ the elements in the list. (more precisely, this indicates a `flatMap` operation)
|
||||
**
|
||||
** # A Pipeline builder
|
||||
** Based on such concepts, structures and evaluation patterns, the IterExplorer serves the purpose to provide
|
||||
|
|
@ -49,8 +49,9 @@
|
|||
** on each element, rather it is triggered by issuing a dedicated `expandChildren()` call on the processing
|
||||
** pipeline. Thus, binding the expansion functor has augmented the data source with the ability to explore
|
||||
** some part in more detail _when required_.
|
||||
** - the *transform operation* installs a function to be mapped onto each element retrieved from the underlying source
|
||||
** - in a similar vein, the *filter operation* binds a predicate to decide about using or discarding data
|
||||
** - the **transform** operation installs a function to be mapped onto each element retrieved from the underlying source
|
||||
** - in a similar vein, the **filter** operation binds a predicate to decide about using or discarding iterator results
|
||||
** - the **flatten** operation allows to combine a sequence of nested _iterables_ into a single seamless iterator
|
||||
** - in concert, expand- and transform operation allow to build hierarchy evaluation algorithms without exposing
|
||||
** any knowledge regarding the concrete hierarchy used and explored as data source.
|
||||
** - further special convenience adaptors and _terminal functions_ are provided.
|
||||
|
|
@ -273,7 +274,7 @@ namespace lib {
|
|||
template<class SRC>
|
||||
struct _DecoratorTraits<SRC, enable_if<is_StateCore<SRC>>>
|
||||
{
|
||||
using SrcRaw = lib::meta::Strip<SRC>::Type;
|
||||
using SrcRaw = lib::meta::Strip<SRC>::TypeReferred;
|
||||
using SrcVal = meta::RefTraits<iter::CoreYield<SrcRaw>>::value_type;
|
||||
using SrcIter = lib::IterableDecorator<lib::CheckedCore<SrcRaw>>;
|
||||
};
|
||||
|
|
@ -699,7 +700,7 @@ namespace lib {
|
|||
|
||||
/**
|
||||
* @internal extension to the Expander decorator to perform expansion automatically on each iteration step.
|
||||
* @todo as of 12/2017, this is more like a proof-of concept and can be seen as indication, that there might
|
||||
* @todo as of 12/2017, this is more like a proof-of concept and can be seen as indication that there might
|
||||
* be several flavours of child expansion. Unfortunately, most of these conceivable extensions would
|
||||
* require a flexibilisation of Expander's internals and thus increase the complexity of the code.
|
||||
* Thus, if we ever encounter the need of anything beyond the basic expansion pattern, we should
|
||||
|
|
@ -761,6 +762,86 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* @internal Decorator for IterExplorer to expand one level of nested iterables.
|
||||
* This mechanism requires that the _result value_ yielded by the underlying iterator
|
||||
* is itself iterable. Applying this decorator thus has the effect to »flatten« exactly
|
||||
* one level of nesting.
|
||||
* @note The result produced by underlying \a SRC _must be a Lumiera iterator_.
|
||||
* Other kinds of nested iterables can be handled only when adapted accordingly.
|
||||
*/
|
||||
template<class SRC>
|
||||
class Flattener
|
||||
: public SRC
|
||||
{
|
||||
static_assert(can_IterForEach<SRC>::value, "Lumiera Iterator required as source");
|
||||
|
||||
using NestedIT = iter::Yield<SRC>;
|
||||
static_assert(can_IterForEach<NestedIT>::value, "flatten() operation expects nested iterator");
|
||||
|
||||
public:
|
||||
using value_type = meta::ValueTypeBinding<NestedIT>::value_type;
|
||||
using reference = meta::ValueTypeBinding<NestedIT>::reference;
|
||||
using pointer = meta::ValueTypeBinding<NestedIT>::pointer;
|
||||
|
||||
Flattener() =default;
|
||||
// inherited default copy operations
|
||||
|
||||
Flattener (SRC&& dataSrc)
|
||||
: SRC{move (dataSrc)}
|
||||
{
|
||||
pullNested();
|
||||
}
|
||||
|
||||
|
||||
/** refresh state when other layers manipulate the source sequence.
|
||||
* @note possibly pulls pipeline to re-establish the invariant */
|
||||
void
|
||||
expandChildren()
|
||||
{
|
||||
SRC::expandChildren();
|
||||
pullNested();
|
||||
}
|
||||
|
||||
public: /* === Iteration control API for IterableDecorator === */
|
||||
|
||||
bool
|
||||
checkPoint() const
|
||||
{
|
||||
ENSURE (not srcIter() or * srcIter());
|
||||
return bool(srcIter());
|
||||
}
|
||||
|
||||
reference
|
||||
yield() const
|
||||
{
|
||||
return **srcIter();
|
||||
}
|
||||
|
||||
void
|
||||
iterNext()
|
||||
{
|
||||
++ *srcIter();
|
||||
pullNested();
|
||||
}
|
||||
|
||||
protected:
|
||||
SRC&
|
||||
srcIter() const
|
||||
{
|
||||
return unConst(*this);
|
||||
}
|
||||
|
||||
/** @note Invariant: positioned at next nested source element, if any */
|
||||
void
|
||||
pullNested()
|
||||
{
|
||||
while (srcIter() and not * srcIter())
|
||||
++srcIter();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @internal Decorator for IterExplorer to map a transformation function on all results.
|
||||
|
|
@ -768,7 +849,7 @@ namespace lib {
|
|||
* storing the treated result into an universal value holder buffer. The given functor
|
||||
* is adapted in a similar way as the "expand functor", so to detect and convert the
|
||||
* expected input on invocation.
|
||||
* @note the result-type of the #yield() function _must be_ `reference`, even when
|
||||
* @note the result-type of the #yield() function _must be_ a `reference`, even when
|
||||
* the TransformFunctor produces a value; otherwise we can not provide a safe
|
||||
* `operator->` on any iterator downstream. This is also the reason why the
|
||||
* ItemWrapper is necessary, precisely _because we want to support_ functions
|
||||
|
|
@ -1698,8 +1779,23 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
/** adapt this IterExploer to flatten _one level of nested Lumiera Iterators_.
|
||||
* Obviously this processing can only be applied when the underlying pipeline yields a result
|
||||
* that can be handled as being iterable; the resulting pipeline will seamlessly produce all
|
||||
* results from all non-empty nested iterators, in sequence.
|
||||
* @remark when chained behind a suitable [transformer(fun)](\ref transform()), the processing
|
||||
* pattern is similar to the `flatMap(fun)` or `M >= fun` operation known from Monad theory.
|
||||
* @return processing pipeline with attached [flattening](\ref iter_explorer::Flattener) decorator
|
||||
*/
|
||||
auto
|
||||
flatten();
|
||||
flatten()
|
||||
{
|
||||
using ResCore = iter_explorer::Flattener<SRC>;
|
||||
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
|
||||
|
||||
return IterExplorer<ResIter> (ResCore{move(*this)});
|
||||
}
|
||||
|
||||
|
||||
/** adapt this IterExplorer to pipe each result value through a transformation function.
|
||||
* Several "layers" of mapping can be piled on top of each other, possibly mixed with the
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ namespace meta {
|
|||
template<typename T>
|
||||
class is_StateCore
|
||||
{
|
||||
using Type = Strip<T>::Type;
|
||||
using Type = Strip<T>::TypeReferred;
|
||||
|
||||
META_DETECT_FUNCTION_ARGLESS(checkPoint);
|
||||
META_DETECT_FUNCTION_ARGLESS(iterNext);
|
||||
|
|
@ -545,7 +545,7 @@ namespace meta {
|
|||
template<typename T>
|
||||
class can_STL_ForEach
|
||||
{
|
||||
using Type = Strip<T>::Type;
|
||||
using Type = Strip<T>::TypeReferred;
|
||||
|
||||
struct is_iterable
|
||||
{
|
||||
|
|
@ -609,7 +609,7 @@ namespace meta {
|
|||
template<typename T>
|
||||
class can_STL_backIteration
|
||||
{
|
||||
using Type = Strip<T>::Type;
|
||||
using Type = Strip<T>::TypeReferred;
|
||||
|
||||
struct is_backIterable
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
** Within the STL, there is a convention to provide nested typedefs to indicate
|
||||
** type variations in relation to the basic payload type of the container. We
|
||||
** follow this convention and support especially the
|
||||
** - `value_type` (what is conceived to be "in" the container or iterator)
|
||||
** - a simple (LValue) reference to the payload
|
||||
** - a pointer at the payload.
|
||||
** - `value_type` : how to store what is conceived to be "in" the container or iterator)
|
||||
** - a simple (LValue) reference to the payload: how you access some content
|
||||
** - a to form pointer at the payload, which is relevant for `operator->`
|
||||
**
|
||||
** A custom container should likewise provide such type definitions, and the
|
||||
** type rebinding helper template defined in this header makes it easy to
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include <vector>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
|
|
@ -71,6 +72,7 @@ using lib::iter_stl::eachElm;
|
|||
using LERR_(ITER_EXHAUST);
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::array;
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
|
@ -666,6 +668,46 @@ namespace test{
|
|||
|
||||
|
||||
|
||||
/** @test chain the results from a sequence of iterators into a single sequence.
|
||||
* Since this "sequence" of source iterations can itself be treated as iterable,
|
||||
* this amounts to _»flattening«_ a single level of nesting. When linked into the
|
||||
* pipeline behind a transforming function, the combined processing pattern is
|
||||
* similar to the `flatMap(fun)` or `M >= fun` operations known from Monad theory.
|
||||
*/
|
||||
void
|
||||
verify_flattenNestedIterator()
|
||||
{
|
||||
using LumieraIter = _DecoratorTraits<CountDown>::SrcIter;
|
||||
|
||||
// STL-iterable with a sequence of Lumiera iterators
|
||||
auto nested_1 = array{LumieraIter{CountDown{5}}, LumieraIter{CountDown{8,4}}};
|
||||
|
||||
CHECK (materialise (
|
||||
explore(nested_1)
|
||||
.flatten()
|
||||
)
|
||||
== "5-4-3-2-1-8-7-6-5"_expect);
|
||||
|
||||
|
||||
// Investigate the types used for adapting the iterator pipeline....
|
||||
|
||||
auto baseType = [](auto& src){ using BasePipeline = _DecoratorTraits<decltype(src)>::SrcIter;
|
||||
return showType<BasePipeline>();
|
||||
};
|
||||
auto nestedIT = [](auto& src){ using BasePipeline = _DecoratorTraits<decltype(src)>::SrcIter;
|
||||
using NestedResult = iter::Yield<BasePipeline>;
|
||||
return showType<NestedResult>();
|
||||
};
|
||||
|
||||
// the base pipeline fed into the Flattener..
|
||||
CHECK (baseType(nested_1) == "iter_explorer::StlRange<array<IterableDecorator<CheckedCore<CountDown> >, 2ul>&>"_expect );
|
||||
|
||||
// the nested (iterable) result type produced by this base pipeline...
|
||||
CHECK (nestedIT(nested_1) == "IterableDecorator<CheckedCore<CountDown> >&"_expect );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test package elements from the source pipeline into fixed-sized groups.
|
||||
* These groups are implemented as std::array and initialised with the values
|
||||
* yielded consecutively from the underlying source pipeline. The main iterator
|
||||
|
|
|
|||
|
|
@ -51897,7 +51897,7 @@
|
|||
<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 CREATED="1732487124717" ID="ID_287102344" MODIFIED="1732487148843" TEXT="genauer: sogar nur als ein 2.Preprocessing-Schritt auf der freigelegten BaseSrc"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -52622,7 +52622,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1535891065189" FOLDED="true" ID="ID_1233342893" MODIFIED="1774486122123" TEXT="Iterator-Monade">
|
||||
<node COLOR="#338800" CREATED="1535891065189" FOLDED="true" ID="ID_1233342893" MODIFIED="1774633223638" TEXT="Iterator-Monade">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -52914,8 +52914,8 @@
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1536410175049" ID="ID_1439541143" MODIFIED="1536516072058" TEXT="Ergänzungen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#1a474a" COLOR="#71f721" CREATED="1536410175049" ID="ID_1439541143" MODIFIED="1774633309617" TEXT="Ergänzungen">
|
||||
<icon BUILTIN="go"/>
|
||||
<node COLOR="#338800" CREATED="1535894221015" FOLDED="true" ID="ID_977007729" MODIFIED="1573229640628" TEXT="Bug im Filter-Layer">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1535894239308" ID="ID_1809452702" MODIFIED="1535894251655" TEXT="Reihenfolge des Parent-Aufrufes in expandChildren()"/>
|
||||
|
|
@ -53272,13 +53272,107 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1774470739518" ID="ID_1513532591" MODIFIED="1774475574352" TEXT="Typ-Ableitung biegt in den Value-Traits falsch ab">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1774450743106" ID="ID_312759335" MODIFIED="1774450759689" TEXT="»flatten« (wie in flatMap)">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1774450761782" ID="ID_657002637" MODIFIED="1774450812916" TEXT="tritt sporatisch in der Praxis auf ⟵ Beispiel chain-Iterator"/>
|
||||
<node CREATED="1774451196653" ID="ID_217480792" MODIFIED="1774451228472" TEXT="indirekt wäre damit ein Monaden-Pattern (doch wieder) möglich">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1774451234232" ID="ID_1417073949" MODIFIED="1774451277231" TEXT="man könnte nun flatMap() durch zwei Layer darstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ein Transform-Layer gefolgt von einem Flatten
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774451292536" ID="ID_1570078692" MODIFIED="1774454167519" TEXT="Abgrenzung: konzeptionell baut das Design nicht auf dem Monaden-Pattern auf">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Zur Erinnerung: diesem Ansatz war ich zunächst verfallen, habe dann aber erkannt, daß Monaden sehr oft ein Anti-Pattern sein können. In meinem Fall war das Design dadurch von Grund auf verdorben, so daß ich die nun erfolgreiche Variante komplett neu bauen mußte. Das leitende Prinzip ist jetzt ein Pipeline-Builder, und nicht mehr eine funktionale Kapsel. Indem ich nun aber ein einfaches »flatten« nachrüste, wären auch Monaden-artige Verarbeitungsmuster <i>darstellbar</i>, wenn man sich auf eine Teilmenge der Funktionalität beschränkt. Meiner Erfahrung zufolge dürfte das aber seltener auftreten, als die Suggestiv-Kraft der Monaden-Idee vermuten ließe; typischerweise muß man die Nützlichkeit von Monaden mit speziell ausgewählten Beispielen belegen, was eben grade gegen eine Universallität spricht.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Der konkrete Anlaß, warum ich jetzt eine »flatten«-Operation einbaue, ist auch etwas anderes: eine Folge von Iteratoren nahtlos verbinden. Man <i>kann</i>  zwar behaupten, das <i>sei</i> der Beleg für eine Monaden-Struktur, aber das verfehlt den Kern der Sache, denn es ist nicht konstituierend für diesen Vorgang, man kann ihn genauso gut als Coroutine deuten.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774453329538" ID="ID_131297170" MODIFIED="1774453332998" TEXT="Implementierung">
|
||||
<node CREATED="1774453338177" ID="ID_1984582817" MODIFIED="1774453369433" TEXT="zentrale Frage: wo ist die Storage für den verschachtelten Iterator?">
|
||||
<node CREATED="1774453491549" ID="ID_1813207885" MODIFIED="1774454086106" TEXT="Klar ist: keine dynamische Rekursion notwendig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Monaden leben in der Welt der Typen, deshalb kann man damit auch nicht direkt eine Such-Auswertung bauen (nur indirekt, indem ein Funktionsaufruf einen leeren Iterator liefert). Dem entsprechend ist auch das flatMap-Baumuster an den konkreten Ergebnistyp gebunden, man kann auch eine flatMap-Operation nicht generisch rekursiv anwenden, sondern nur, wenn die gegebenen Typen bereits verschachtelt sind. Hier liegt auch der entscheidene Unterschied zu einer <i>pure functional language:</i> dort gibt es keine Unterscheidung zwischen Typ und Wert, und entsprechend kann auch eine Typ-Auswertung dann doch zur laufzeit rekursiv sein und nicht terminieren. Was jedoch ehr ein Zeiten dafür ist, daß diese »reinen« Begriffe an der gegebenen Sache vorbeigehen.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774453505842" ID="ID_1871980985" MODIFIED="1774453517621" TEXT="also kann die Storage auf jeden Fall »inline« liegen"/>
|
||||
<node CREATED="1774454091533" ID="ID_1089755564" MODIFIED="1774454127186" TEXT="im besten Fall liegt die Storage im Quell-Iterator"/>
|
||||
<node CREATED="1774454133138" ID="ID_750611609" MODIFIED="1774454157576" TEXT="das geht aber nur, wenn der Quell-Iterator einen Iterator-»wert« per Referenz liefert"/>
|
||||
</node>
|
||||
<node CREATED="1774454273364" ID="ID_283722071" MODIFIED="1774454299237" TEXT="mit dieser Einsicht: relativ einfach als StateCore-Adapter zu realisieren">
|
||||
<node CREATED="1774456032054" ID="ID_1379189388" MODIFIED="1774456053876" TEXT="wichtiger Hinweis: auf diese Grundstruktur aufbauen und adaptieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1774456058870" ID="ID_1180777676" MODIFIED="1774456067453" TEXT="es kann komplexere Fälle geben">
|
||||
<node CREATED="1774456093681" ID="ID_1748395369" MODIFIED="1774456105468" TEXT="wenn der Quell-Iterator als Value geliefert wird"/>
|
||||
<node CREATED="1774456106258" ID="ID_945956785" MODIFIED="1774456121106" TEXT="wenn der Quell-Iterator kein Lumiera-Iterator ist"/>
|
||||
</node>
|
||||
<node CREATED="1774456069677" ID="ID_960299336" MODIFIED="1774456170813" TEXT="dann muß die Builder-Funktion geeignet adaptieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
diese zweischichtige Struktur im Quellcode hat sich schrittweise herausgebildet und inzwischen gut bewährt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774470631894" ID="ID_586901779" MODIFIED="1774470636091" TEXT="Basisfall">
|
||||
<node CREATED="1774470643122" ID="ID_1020522529" MODIFIED="1774470661867" TEXT="nested Lumiera-Iterator als Quelle geliefert"/>
|
||||
<node CREATED="1774470664229" ID="ID_1294085123" MODIFIED="1774470671593" TEXT="konstruieren komplett analog zu Filter">
|
||||
<node CREATED="1774470673268" ID="ID_1520761184" MODIFIED="1774470689646" TEXT="Invariante: beide verschachtelten Iteratoren stehen auf dem nächsten Element"/>
|
||||
<node CREATED="1774470692342" ID="ID_217842235" MODIFIED="1774470715218" TEXT="sonst pull ⟹ wenn innerer Iterator leer, dann äußeren iterieren"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774645685915" ID="ID_1637864454" MODIFIED="1774645696083" TEXT="Erweiterung: allgemeines »Iterable«">
|
||||
<node CREATED="1774656959677" ID="ID_1616144534" MODIFIED="1774656968996" TEXT="muß in dem Fall einen Transformer vorschalten"/>
|
||||
<node CREATED="1774656977650" ID="ID_1110089705" MODIFIED="1774656988301" TEXT="brauche dafür einen Adapter-Iterator-Typ">
|
||||
<node CREATED="1774657006975" ID="ID_633121575" MODIFIED="1774657027031" TEXT="mit den DecoratorTraits konstruieren">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774657044528" ID="ID_881902324" MODIFIED="1774657081713" TEXT="Redundanz vermeiden ⟹ λ">
|
||||
<node COLOR="#5b280f" CREATED="1774657087315" ID="ID_514811912" MODIFIED="1774657098557" TEXT="Versuch: das Ende der Verpackungs-Pipeline">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1774657102834" HGAP="21" ID="ID_1115849426" MODIFIED="1774657125002" TEXT="problematisch: die richtigen Typen abgreifen" VSHIFT="3">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774657127572" ID="ID_923516148" MODIFIED="1774657139361" TEXT="Versuch: nur den finalen Einpack-Schritt">
|
||||
<node CREATED="1774657142069" ID="ID_782762772" MODIFIED="1774657153160" TEXT="muß entweder den SRC-Layer durchreichen (falls Lumiera-Iter)"/>
|
||||
<node CREATED="1774657153857" ID="ID_1172695368" MODIFIED="1774657160078" TEXT="oder einen Transformer darauf setzen"/>
|
||||
<node CREATED="1774657163509" ID="ID_843406645" MODIFIED="1774657170779" TEXT="davon den decltype abgreifen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774470727877" ID="ID_886855220" MODIFIED="1774470737912" TEXT="Schwierigkeiten beim Adaptieren">
|
||||
<node COLOR="#435e98" CREATED="1774470739518" ID="ID_1513532591" MODIFIED="1774645576498" TEXT="Typ-Ableitung biegt in den Value-Traits falsch ab">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e1b4a0" COLOR="#690f14" CREATED="1774470739518" ID="ID_1029964723" MODIFIED="1774473599797" TEXT="unsere Value-Traits sind vermutlich nicht auf nested Iterators ausgelegt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Wobei mir nicht klar ist, ob das Problem grundsätzlicher Natur ist.
|
||||
|
|
@ -53482,9 +53576,766 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774476573574" ID="ID_1375774056" MODIFIED="1774485015348" TEXT="Mit diesem Fix: viel besser — aber noch ein überschüssiger Pointer">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1774476614705" ID="ID_1278550682" MODIFIED="1774476638141" TEXT="jetzt tritt das Problem zuerst auf in den DecoratorTraits<IT>"/>
|
||||
<node CREATED="1774476665790" ID="ID_82721045" MODIFIED="1774476763587">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
konkret:
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced" size="2">iter_explorer::StlRange<array<IterableDecorator<CheckedCore<CountDown> > </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced" size="2">                              , 3ul </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced" size="2">                              >& </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced" size="2">                       ></font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689102663805" ID="ID_1911278306" MODIFIED="1689182022572" TEXT="Ausbau der Teminal-Ausdrücke">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#3f0f69" CREATED="1774476892116" ID="ID_423296674" MODIFIED="1774485009332" TEXT="funktioniert der Fix wirklich schon richtig?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1774476915673" ID="ID_17580519" MODIFIED="1774483351837" TEXT="nein..."/>
|
||||
<node COLOR="#435e98" CREATED="1774483352483" ID="ID_1150219005" MODIFIED="1774485095578" TEXT="erst mal: isLumiera spricht an">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1774483365817" ID="ID_262798398" MODIFIED="1774483377564" TEXT="liegt daran, daß ich im Trait ein meta::Strip eingebaut habe"/>
|
||||
<node CREATED="1774483399965" ID="ID_1705325393" MODIFIED="1774483416774" TEXT="müßte man also zusätzlich mit not is_pointer<IT> guarden"/>
|
||||
<node COLOR="#338800" CREATED="1774483417602" ID="ID_1725870527" MODIFIED="1774645519854" TEXT="oder den Trait entsprechend reparieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1774483439879" ID="ID_686398995" MODIFIED="1774483448114" TEXT="immer das gleiche Argument!"/>
|
||||
<node CREATED="1774483451878" ID="ID_360291049" MODIFIED="1774483461034" TEXT="nicht zu viel Convenience einbauen"/>
|
||||
<node CREATED="1774483461913" ID="ID_938635716" MODIFIED="1774483473350" TEXT="Ref strippen ist OK"/>
|
||||
<node CREATED="1774483474006" ID="ID_311302310" MODIFIED="1774483477222" TEXT="const nicht"/>
|
||||
<node CREATED="1774483477730" ID="ID_1555108802" MODIFIED="1774483485350" TEXT="und pointer gleich gar nicht!!!">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774483496407" ID="ID_146836280" MODIFIED="1774485095579" TEXT="weiteres Problem: ValueTypeBinding biegt dann eben doch ab">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1774483584260" ID="ID_1961418463" MODIFIED="1774483641104" TEXT="brauche es aber, da sonst kein einheitlicher Typ-Ausdruck möglich ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn ich habe im ValueTypeBinding die binding-Typen benannt wie in der STL, aber in RefTraits mein eigenes Schema verwendet
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1774483645487" ID="ID_1313355327" MODIFIED="1774483935712" TEXT="man kann das »Abbiegen« unterbinden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
indem man explizit festlegt, daß die Standard-Instanz des Template gewünscht ist
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1774483936773" ID="ID_1820530982" MODIFIED="1774483940076" TEXT="klappt nicht"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774484424763" ID="ID_1813845821" MODIFIED="1774484981665" TEXT="naja ... eigentlich sollten die type-Bindings auch immer gleich heißen">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774485034192" ID="ID_418957044" MODIFIED="1774485083401" TEXT="dann kann nämlich der STTL-Fall direkt auf die RefTraits gehen">
|
||||
<arrowlink COLOR="#2ba0b8" DESTINATION="ID_1311705886" ENDARROW="Default" ENDINCLINATION="316;29;" ID="Arrow_ID_174256041" STARTARROW="None" STARTINCLINATION="-428;19;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774484970260" ID="ID_500702578" MODIFIED="1774484979686" TEXT="(gesägt getan)">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774484988707" ID="ID_1311705886" MODIFIED="1774485083401" TEXT="und nun funktioniert der Fix">
|
||||
<linktarget COLOR="#2ba0b8" DESTINATION="ID_1311705886" ENDARROW="Default" ENDINCLINATION="316;29;" ID="Arrow_ID_174256041" SOURCE="ID_418957044" STARTARROW="None" STARTINCLINATION="-428;19;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774485113783" ID="ID_695277235" MODIFIED="1774633346583" TEXT="Code allgemein glattziehen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1774485136300" FOLDED="true" ID="ID_662491929" MODIFIED="1774633351605" TEXT="separates Trait-Template zu RangeIter extrahieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1774485160233" HGAP="18" ID="ID_59467062" MODIFIED="1774485184635" TEXT="dann kann man nämlich besser dokumentieren worum es geht" VSHIFT="-9"/>
|
||||
<node CREATED="1774555108768" ID="ID_1209527443" MODIFIED="1774555121830" TEXT="sollte auch nochmal die std::iterator_traits einbeziehen">
|
||||
<node CREATED="1774560421105" ID="ID_1710877874" MODIFIED="1774560433963" TEXT="diese decken automatisch auch reine Pointer mit ab"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774560434645" ID="ID_1763126432" MODIFIED="1774563296761" TEXT="ABER: seit C++20 decken Concepts das besser ab...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und damit werden iterator_traits unzuverlässig — wenn sie jemals zuverlässig waren.<br />Denn diese ganze Idee mit den Iteratoren in C++ war von Anfang an eigentlich ein Concept. All die Iterator-Tags und die iterator_traits waren nur Krücken und Workarounds, und außerdem wenig bekannt (und too long didnt read, gilt auch für mich selber!!!). Insofern konnte man sich bei Iteratoren sowiso auf nix verlassen, jenseits der STL. Somit wird die Situation durch die Concepts jetzt deutlich verbessert
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node CREATED="1774563027307" ID="ID_389716197" MODIFIED="1774563657284" TEXT="sollte die Iterator-Concepts einbeziehen">
|
||||
<arrowlink COLOR="#4c86e5" DESTINATION="ID_1581229318" ENDARROW="Default" ENDINCLINATION="-2159;523;" ID="Arrow_ID_58259000" STARTARROW="None" STARTINCLINATION="-1280;85;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1774563314105" HGAP="23" ID="ID_333431530" MODIFIED="1774563358476" TEXT="damit kann ich meinen Conditional-Typ nun korrekt schreiben" VSHIFT="11"/>
|
||||
<node CREATED="1774563338257" ID="ID_464561407" MODIFIED="1774563560208" TEXT="und auch gleich das Problem mit dem (const) value_type aushebeln">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das war sowiso (partiell) ein Mißverständnis von mir.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
was der Iterator liefert ⟹ reference
|
||||
</li>
|
||||
<li>
|
||||
in was ich diesen »Wert« dann speichere ⟹ value_type
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1774563509883" ID="ID_85048082" MODIFIED="1774563539531" TEXT="std::iter_reference_t<IT>">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<div style="background-color: #eee0b5; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
||||
<div style="color: #202020; background-color: #eee0b5; font-family: DejaVu Sans Mono; font-size: 9pt; white-space: pre">
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a1a65"><b>template</b></font><font color="#65533c"><</font><font color="#535773">__detail</font><font color="#65533c">::</font><font color="#3a1f18">__dereferenceable </font><font color="#a34649"><b><u>_Tp</u></b></font><font color="#65533c">></font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a1a65"><b>using</b></font><font color="#3a1f18"> </font><font color="#8c505c"><b>iter_reference_t</b></font><font color="#3a1f18"> </font><font color="#65533c">=</font><font color="#3a1f18">  </font><font color="#4a1a65"><b>decltype</b></font><font color="#11123a">(</font><font color="#65533c">*</font><font color="#535773">std</font><font color="#65533c">::</font><font color="#000000">declval</font><font color="#65533c"><</font><font color="#a34649"><b><u>_Tp</u></b></font><font color="#65533c">&></font><font color="#11123a">())</font><font color="#65533c">;</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Es ist einfach schön....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774570577572" ID="ID_1555255783" MODIFIED="1774574222500" TEXT="Altlast-Problem: iter-adapter-stl">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1774570610832" ID="ID_539929857" MODIFIED="1774570628794" TEXT="die Hilfsklasse WrappedStlIter">
|
||||
<node CREATED="1774570631946" ID="ID_680899267" MODIFIED="1774570861868" TEXT="ist kein Lumiera-Iterator (korrekt)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Auch wenn es <i>auf den ersten Blick so aussieht</i> — war es offensichtlich nicht so gemeint: Und zwar fehlt der bool-Check auf das Iterations-Ende; den leistet nämlich erst der im nächsten Schritt darüber gelegte RangeIter
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Klar, heute würde ich das anders machen: im Grunde ist das eine Transformer-Pipeline, die ich hier mit sehr einfachen Mitteln (noch vor C++11) realisiert habe. Es funktioniert, indem ein STL-Iterator dekoriert wird, und dabei die Zugriffsfunktion jeweils speziell andgepaßt ist.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#a4060f" CREATED="1774570642763" ID="ID_1007316252" MODIFIED="1774570687039" TEXT="qualifiziert sich nicht als STL-Iterator (soll sie aber)">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774571474647" ID="ID_25395946" MODIFIED="1774571479641" TEXT="praktische Untersuchung">
|
||||
<node CREATED="1774571480731" ID="ID_196906751" MODIFIED="1774571602639" TEXT="baue mir ein Beispiel, analog zu PlacementIndex::remove_all_from_scope()">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
an der Stelle ist es aufgefallen, weil die static-Assertion getriggert hat; nachdem ich die Assertion auskommentiert habe, lief der Build durch ⟹ es muß sich um einen Formalismus handeln, und wahrscheinlich daran liegen, daß das Concept für input_iterator nicht erfüllt wird (denn ein Lumiera-Iterator soll es ja nicht sein)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774571680280" ID="ID_1696413550" MODIFIED="1774571726069" TEXT="bestätigt: lib::iter_stl::_MapIterT<Pos>::PickValIter ist kein Lumiera-Iter und kein STL-Iter">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node CREATED="1774571604553" ID="ID_731079399" MODIFIED="1774571634520" TEXT="definiere eine Funktion, deren Argument mit dem Concept std::input_iterator qualifiziert wird">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1774571638822" ID="ID_1624251593" MODIFIED="1774571647816" TEXT="klappt ⟹ schöne Fehlermeldungen"/>
|
||||
<node COLOR="#435e98" CREATED="1774571650148" ID="ID_1721889887" MODIFIED="1774574867304" TEXT="Lumiera-Iterator scheitert (korrekt) ⟵ hat keinen postfix-inkrement">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<div style="background-color: #f5f8c6; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
||||
<div style="color: #202020; background-color: #f5f8c6; font-family: DejaVu Sans Mono; font-size: 9pt; white-space: pre-wrap">
|
||||
<p style="background-color: #f3cfc3; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#ff0000">/usr/include/c++/14/bits/iterator_concepts.h:633:13: required for the satisfaction of 'weakly_incrementable<_Iter>' [with _Iter = lib::iter_stl::IterSnapshot<long unsigned int>]</font>
|
||||
</p>
|
||||
<p style="background-color: #f3cfc3; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">/usr/include/c++/14/bits/iterator_concepts.h:647:13: required for the satisfaction of 'input_or_output_iterator<_Iter>' [with _Iter = lib::iter_stl::IterSnapshot<long unsigned int>]</font>
|
||||
</p>
|
||||
<p style="background-color: #f3cfc3; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">/usr/include/c++/14/bits/iterator_concepts.h:669:13: required for the satisfaction of 'input_iterator<auto:47>' [with auto:47 = lib::iter_stl::IterSnapshot<long unsigned int>]</font>
|
||||
</p>
|
||||
<p style="background-color: #f3cfc3; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">/usr/include/c++/14/bits/iterator_concepts.h:634:10: in requirements with '_Iter __i' [with _Iter = lib::iter_stl::IterSnapshot<long unsigned int>]</font>
|
||||
</p>
|
||||
<p style="background-color: #f4f7fe; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">/usr/include/c++/14/bits/iterator_concepts.h:637:18: note: nested requirement '__is_signed_integer_like<typename std::__detail::__iter_traits_impl<typename std::remove_cvref<_Tp>::type, std::incrementable_traits<typename std::remove_cvref<_Tp>::type> >::type::difference_type>' is not satisfied</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">637 | requires __detail::__is_signed_integer_like<iter_difference_t<_Iter>>;</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font>
|
||||
</p>
|
||||
<p style="background-color: #f4f7fe; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">/usr/include/c++/14/bits/iterator_concepts.h:639:12: note: the required expression '(__i ++)' is invalid</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
<font color="#4a2626">639 | __i++;</font>
|
||||
</p>
|
||||
<p style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#5fbf8a" DESTINATION="ID_1721889887" ENDARROW="Default" ENDINCLINATION="-511;22;" ID="Arrow_ID_886924805" SOURCE="ID_1923510525" STARTARROW="None" STARTINCLINATION="2722;133;"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774571876818" ID="ID_1646300105" MODIFIED="1774573461346" TEXT="der WrappedStlIter scheitert am gleichen Kriterium">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774573438931" ID="ID_1024929309" MODIFIED="1774573461347" TEXT="und zudem brauchen wir auch noch einen difference_t">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774573478325" ID="ID_356575590" MODIFIED="1774574232930" TEXT="zwei Dummy-Definitionen in WrappedStlIter">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1774573490343" ID="ID_1876521282" MODIFIED="1774573505271" TEXT="einen postfix-inkrement ⟼ NOTREACHED"/>
|
||||
<node CREATED="1774573507914" ID="ID_1390391761" MODIFIED="1774573518308" TEXT="using difference_t = ptrdiff_t"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774573541526" ID="ID_1484466520" MODIFIED="1774574216107" TEXT="Bewertung">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1774573546689" ID="ID_1416847324" MODIFIED="1774573554664" TEXT="das ist ein Implementierungs-Konstrukt"/>
|
||||
<node CREATED="1774573555412" ID="ID_1781686716" MODIFIED="1774573647962" TEXT="insofern nicht gefährlich">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es ist m.E. <i>offensichtlich daß man das nicht näher anschauen soll</i>. Dafür sprechen bereits die komplex eingefädelten Hilfs-Traits, und die davor geschalteten Builder-Funktionen. Sogar wenn mal jemand hier was repariert und erweitert, sehe ich keine Gefahr
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774573649143" ID="ID_742278940" MODIFIED="1774573678099" TEXT="Design ist »verbesserbar«">
|
||||
<icon BUILTIN="smiley-neutral"/>
|
||||
<node CREATED="1774573798803" ID="ID_659729974" MODIFIED="1774573863061" TEXT="das ist eine typische »kohäsive« Implementierung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
„Ich hab genau verstanden wie es funktioniert, und kann deshalb gezielt an zwei Stellen manipulieren, und hab dann bereits mein Ergebnis“
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774573919794" ID="ID_1775829137" MODIFIED="1774574188892" TEXT="schöner (aver vielleicht auf ineffizienter) wäre...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...wenn man den IterExplorer (Pipeline-Builder) verwendet, ihn den jeweiligen Container automatisch adaptieren läßt, und dann nur noch ein passendes Transformer-λ darübersetzt. Dadurch würde der Code sehr viel knapper und auch sofort verständlich....
|
||||
</p>
|
||||
<p>
|
||||
Allerdings
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
den Header habe ich noch vor C++11 geschrieben (und den Iter-Explorer gab es auch lange Zeit danach noch nicht)
|
||||
</li>
|
||||
<li>
|
||||
die vom IterExplorer generierten Typen sind monströs. Da ist der hier erzeugte RangeIter<Wrapped-irgendwas... vermutlich verständlicher
|
||||
</li>
|
||||
<li>
|
||||
auch ist die Frage, ob der Optimiser so gut mit IterExplorer klarkommt. Das hab ich nämlich noch nie genau überprüft; wohingegen das hier aufgebaute Konstrukt ganz offensichtlich komplett herunteroptimiert werden kann
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774574241616" ID="ID_768965113" MODIFIED="1774574520943" TEXT="was ich jetzt hier mache um RangeIter zu befriedigen, ist auch »kohäsiv«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...man könnte auch sagen, linke Tasche ↷ rechte Tasche. Ich weiß jetzt (weil ich es gard eben gebaut habe), daß der RangeIter mit den Typdefinitionen verzweigt, wenn er einen Lumiera-Iterator sieht. Außerdem finde ich die Assertion (daß der Typ-Parameter ein Iterator sein muß) insgesamt hilfreich. Und drittens »sehe« ich, daß der volle Umfang des STL-Konzepts gar nicht gebraucht wird für einen Lumiera-Iterator. <i><font color="#930210">Trotzdem übel, hier ein </font><font color="#d40448"><b>lügendes Concept</b></font><font color="#930210"> zu verwenden</font></i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#f50e0e" DESTINATION="ID_764079350" ENDARROW="Default" ENDINCLINATION="27;-62;" ID="Arrow_ID_1627890832" STARTARROW="None" STARTINCLINATION="-173;7;"/>
|
||||
</node>
|
||||
<node CREATED="1774574191430" ID="ID_9214379" MODIFIED="1774574211410" TEXT="der Header wird pervasiv verwendet; insofern könnte man das mal anschauen..."/>
|
||||
</node>
|
||||
<node COLOR="#242471" CREATED="1774574679692" ID="ID_401546883" MODIFIED="1774574722891" TEXT="trotz allem gut, jetzt die iter::Traits auf das STL-Concept aufgesetzt zu haben">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774574440618" ID="ID_764079350" MODIFIED="1774574666534" TEXT="fühle mich in meinem Design für den »Lumiera Forward Iterator« bestätigt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Umso mehr, nachdem ich mir jetzt etwas die Implementierung der STL-concepts angeschaut habe....
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Fazit: die Idee, einen Iterator als »abstrahierten Pointer« zu definieren, ist auf den ersten Blick cool, und hat auch ihren Nutzen. Aber es ist und bleibt schechtes Design, weil man dadruch lediglich Implementierungs-Eigenschaften in eine formale Spezifikaiton mappt. Ich bleibe dabei: die STL-Iteratoren können viel zu viel, um eine gute Abstraktion zu sein. Daher war es angemessen, für Lumiera ein eigenes Konzept aufzubauen, und dafür den größten Teil aller Fähigkeiten und Möglichkeiten der STL-Iteratoren zu opfern
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#f50e0e" DESTINATION="ID_764079350" ENDARROW="Default" ENDINCLINATION="27;-62;" ID="Arrow_ID_1627890832" SOURCE="ID_768965113" STARTARROW="None" STARTINCLINATION="-173;7;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774485124039" ID="ID_1597506196" MODIFIED="1774574884483" TEXT="meta::Strip aus IterForEach entfernen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774569458307" FOLDED="true" ID="ID_233381529" MODIFIED="1774630651400" TEXT="dafür hier auch explizit typedef reference verlangen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
bisher verlangt der Lumiera-Iterator-Detektor nur eine Typedef <font color="#563f3f" face="Monospaced">value_type</font>  ;
|
||||
</p>
|
||||
<p>
|
||||
das ist zwar korrekt, und genügt i.d.R. zur Erkennung. Allerdings ist <font color="#563f3f" face="Monospaced">value_type</font>  nicht das Wichtigste (wie ich früher meinte), sondern die Typedef <font color="#563f3f" face="Monospaced">reference</font>, denn diese beschreibt, was der Iterator konkret liefert
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1774579136412" FOLDED="true" ID="ID_123251836" MODIFIED="1774630644131" TEXT="bricht lib::diff:Record::operator string()">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774579184258" ID="ID_189508374" MODIFIED="1774630488319" STYLE="fork" TEXT="util::join biegt falsch ab">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1774579200014" ID="ID_1786574388" MODIFIED="1774630482944" TEXT="verwendet nicht die Spezialisierung für Lumiera-Iterator"/>
|
||||
<node CREATED="1774579218219" ID="ID_1337571916" MODIFIED="1774630510905">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
läßt sich zurückführen auf den Typ <font face="Monospaced" color="#5f3939"><b>Record::scopeIter</b></font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#3c0f69" CREATED="1774579265083" ID="ID_1792093205" MODIFIED="1774630472929" TEXT="Untersuchung im Test-_Setup">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1774579288641" ID="ID_591921649" MODIFIED="1774579293901" TEXT="baue die Typen in try.cpp nach">
|
||||
<node CREATED="1774579308567" ID="ID_832332658" MODIFIED="1774579309789" TEXT="using Storage = std::vector<int>"/>
|
||||
<node CREATED="1774579321048" ID="ID_30406163" MODIFIED="1774579322265" TEXT="using scopeIter = lib::iter_stl::_SeqT<const Storage>::Range;"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774579912309" ID="ID_1034144598" MODIFIED="1774630435137" TEXT="Ha! ein ganz generischer Fehler im Duck-Detector-Template">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1774579957452" ID="ID_1258668487" MODIFIED="1774579958555" TEXT="META_DETECT_NESTED(reference)"/>
|
||||
<node CREATED="1774579972606" ID="ID_1766088848" MODIFIED="1774579983848" TEXT="das erzeugt den Typ TY::reference *"/>
|
||||
<node CREATED="1774579985982" ID="ID_1894605513" MODIFIED="1774580166317">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und das ist hier int& *  ⟹ ↯ <font color="#cc0a0a">UNGÜLTIG</font>  ⟹ SFINAE-fail
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774580189824" ID="ID_357832913" MODIFIED="1774630433166" TEXT="kann man den Check durch die void_t<T> - Technik ersetzen?">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1774630532103" ID="ID_1394354807" MODIFIED="1774630546525" TEXT="vorerst aber noch nicht umstellen auf Concept">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1774630550996" ID="ID_801681034" MODIFIED="1774630560375" TEXT="das ist dann doch nicht ganz trivial"/>
|
||||
<node CREATED="1774630561037" ID="ID_608706434" MODIFIED="1774630573991" TEXT="sollte nämlich dann auch die StateCore mit einbeziehen"/>
|
||||
<node CREATED="1774630574948" ID="ID_1892948077" MODIFIED="1774630586403" TEXT="und die STL-Iterierbarkeit durch Standard-Concepts abdecken"/>
|
||||
<node CREATED="1774630587229" ID="ID_1155797573" MODIFIED="1774630605556" TEXT="�� sollte dafür einen eigenen Header schaffen"/>
|
||||
<node COLOR="#008874" CREATED="1774630611335" ID="ID_1788133693" MODIFIED="1774630633817" TEXT="drängt jetzt nicht, tut ja alles"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774574800549" ID="ID_1923510525" MODIFIED="1774574867304" TEXT="habe bei der Gelegenheit auch die Trennschärfe bestätigt">
|
||||
<arrowlink COLOR="#5fbf8a" DESTINATION="ID_1721889887" ENDARROW="Default" ENDINCLINATION="-511;22;" ID="Arrow_ID_886924805" STARTARROW="None" STARTINCLINATION="2722;133;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774645548832" ID="ID_1656634709" MODIFIED="1774645573149" TEXT="Value-Traits nun korrekt ⟹ Flattener funktioniert im einfachsten Fall">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774645596829" ID="ID_1108333109" MODIFIED="1774645625805" TEXT="muß aber auch nested-Iterable wrappen/adaptieren">
|
||||
<node CREATED="1774645611931" ID="ID_1847373113" MODIFIED="1774645645970" TEXT="ein nested-Iterable allgemein muß nicht ein Lumiera-Iterator sein"/>
|
||||
<node CREATED="1774645647248" ID="ID_1783118750" MODIFIED="1774645656609" TEXT="in dem Fall brauchen wir einen Adapter-Transformer dazwischen"/>
|
||||
<node CREATED="1774645659013" ID="ID_163397201" MODIFIED="1774645671791" TEXT="das sollte erst im Builder so konfiguriert werden (hält den Code klarer)"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1774661629241" ID="ID_1366447416" MODIFIED="1774661656900" TEXT="Konsistenzproblem bzgl Wrappen vs Adaptieren">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1774661707569" ID="ID_1342544444" MODIFIED="1774661727932" TEXT="alle unsere Adapter betten die Quelle ein"/>
|
||||
<node CREATED="1774661815728" ID="ID_352915720" MODIFIED="1774661993182">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
so wie jetzt gebaut mit dem Transformer ⟹ Selbstmord <font color="#e8106a" size="6">☠</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Der Transformer enthält einen ItemWrapper, in den das Ergebnis der Transformation <b>by value</b> abgelegt wird. Wir machen also entweder eine Kopie der ganzen Quell-Pipeline, oder, noch schlimmer, wir moven die Quell-Pipeline dorthin, und dann beim nächsten Pull rufen wir die Zombie-Quell-Pipeline aus dem Transformer auf.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1774664657373" ID="ID_623577442" MODIFIED="1774665522868" TEXT="Analyse — Fallunterscheidung">
|
||||
<node CREATED="1774665499721" ID="ID_364650146" MODIFIED="1774665531147" TEXT="Verhalten der DecoratorTraits">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das Thema »Dekoration« ist zentral gelöst ⟹ Struktur der<font color="#5d4343">  </font><font color="#552b2b" face="Monospaced">_DecoratorTraits</font>  befolgen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="list"/>
|
||||
<node COLOR="#338800" CREATED="1774664674549" ID="ID_282985153" MODIFIED="1774664702803" TEXT="Lumiera-Iterator ⟹ nichts zu tun">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1774664845336" ID="ID_1139397074" MODIFIED="1774664877029" TEXT="StateCore ⟹ brauche IterableDecorator<CheckedCore<COR>>">
|
||||
<node CREATED="1774665154791" ID="ID_988207721" MODIFIED="1774665169407" TEXT="sizeof(wrapped) ≡ raw-Core"/>
|
||||
</node>
|
||||
<node CREATED="1774664903856" ID="ID_1550446713" MODIFIED="1774664910907" TEXT="STL-iterierbarer Container...">
|
||||
<node CREATED="1774664912514" ID="ID_1956232632" MODIFIED="1774664934248" TEXT="muß per LValue-Ref gegeben sein ⟹ StlRange">
|
||||
<node CREATED="1774665205923" ID="ID_740091937" MODIFIED="1774665220153" TEXT="das ist letztlich ein RangeIter"/>
|
||||
<node CREATED="1774665220910" ID="ID_986715529" MODIFIED="1774665232544" TEXT="speichert 2 x einen Container-Iterator"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1774665259441" ID="ID_1344873857" MODIFIED="1774665476796" TEXT="damit definitiv > sizeof(void*)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774664936384" ID="ID_1216923819" MODIFIED="1774664943830" TEXT="RValue ⟹ compile failure"/>
|
||||
</node>
|
||||
<node CREATED="1774665057858" ID="ID_1626986192" MODIFIED="1774665060583" TEXT="IterSource">
|
||||
<node CREATED="1774665061736" ID="ID_75451297" MODIFIED="1774665072126" TEXT="nur unterstützt als Pointer oder Ref"/>
|
||||
<node CREATED="1774665072858" ID="ID_145216670" MODIFIED="1774665091799" TEXT="⟹ wrap with IterSourceIter">
|
||||
<node CREATED="1774665310562" ID="ID_161339050" MODIFIED="1774665316165" TEXT="baut einen IterSource::iterator">
|
||||
<node CREATED="1774665382105" ID="ID_950855463" MODIFIED="1774665388340" TEXT="das ist ein IterAdapter"/>
|
||||
<node CREATED="1774665388968" ID="ID_605228130" MODIFIED="1774665407116" TEXT="hält einen Pos* + einen shared-ptr auf die Quelle"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1774665259441" ID="ID_72955686" MODIFIED="1774665470704" TEXT="somit > sizeof(void*)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1774665097567" ID="ID_122424436" MODIFIED="1774665106442" TEXT="sonst ⟹ static fail">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774665540676" ID="ID_881315879" MODIFIED="1774665551182" TEXT="es gibt also drei Fälle zu unterscheiden">
|
||||
<node CREATED="1774665553934" ID="ID_794674450" MODIFIED="1774665562056" TEXT="Lumiera / StateCore">
|
||||
<node CREATED="1774665563498" ID="ID_1495786271" MODIFIED="1774665724443" TEXT="direkt verwenden bzw. ein Downcast auf Typ-Ebene">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Das bedeutet:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
die Quelle wird per Value genommen und <i>in die Pipeline verschoben....</i>
|
||||
</li>
|
||||
<li>
|
||||
Effektiv verändert sich die Storage nicht; die Wrapper-Typen sind nur eine logische Dekoration ohne zusätzliche Storage
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774665727890" ID="ID_1196621650" MODIFIED="1774665738213" TEXT="Referenz auf »andere Quelle«">
|
||||
<node CREATED="1774665742059" ID="ID_1490822941" MODIFIED="1774665758274" TEXT="in der Pipeline wird ein Handle-Typ abgelegt"/>
|
||||
<node CREATED="1774665759622" ID="ID_1126587550" MODIFIED="1774665781863" TEXT="dessen Storage ist definitiv größer als der ursprünglich gegebene (Referenz)Typ"/>
|
||||
</node>
|
||||
<node CREATED="1774665917361" ID="ID_1570916564" MODIFIED="1774665933753" TEXT="sonstiger Container oder Quelle by-value">
|
||||
<node CREATED="1774665935618" ID="ID_1662941602" MODIFIED="1774666628453" TEXT="für die Pipeline nicht unterstützt (da zu gefährlich)"/>
|
||||
<node CREATED="1774665953652" ID="ID_1470972168" MODIFIED="1774665968790" TEXT="wenn man das will ⟹ in ContainerCore einwickeln"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1774666042718" ID="ID_1311935400" MODIFIED="1774667309335" TEXT="Lösungansatz entwickeln">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#5b280f" CREATED="1774666053791" ID="ID_54434179" MODIFIED="1774666112545" TEXT="der Transformer ist keine sinnvolle Lösung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Ich hatte ihn ja nur gewählt, weil er wie ein <i>billiger Fix</i>  aussah, mit dem man den Haupt-Fall (Lumiera-Iterator) noch etwas erweitern könnte
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1774666152505" ID="ID_970274323" MODIFIED="1774666169551" TEXT="ein spezieller Adapter-Layer ist notwendig">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1774666177230" ID="ID_476791551" MODIFIED="1774666762719" TEXT="er muß unter allen Umständen die Funktionsfähigkeit des Quell-Iterators erhalten">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1774666199163" ID="ID_624634257" MODIFIED="1774666213976" TEXT="Anpassungs-Fälle">
|
||||
<node CREATED="1774666215760" ID="ID_471378651" MODIFIED="1774667303914" TEXT="Quelle durchreichen / casten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Wenn letztlich nur eine Referenz auf die Quelle durchgereicht werden muß, ggfs. mit Cast in einen anderen Typ, dann kann das direkt in einer yield-Operation erfolgen. Konkret ist das etwas trickreicher, da im einen Fall noch der Quell-Typ (virtuell)recastet werden muß; letztlich überdeckt der Adapter dann aber nur noch den operator* — ohne Implementierungsskizze ist nicht klar, ob sich das in einen einzigen Adapter-Typ zusammenfassen läßt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1774666845740" ID="ID_1330744788" MODIFIED="1774666859582" TEXT="speziell hier wichtig: Quelle muß per Referenz gegeben sein"/>
|
||||
<node CREATED="1774666866523" ID="ID_962856134" MODIFIED="1774666894692">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wird sie dagegen per Value gegeben, ist sie <b>generiert</b> ⟹ wie Container behandeln
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774666302637" ID="ID_24645211" MODIFIED="1774666413066" TEXT="Handle-Typ ⟹ braucht jeweils eine re-Dekoration">
|
||||
<node CREATED="1774666416006" ID="ID_1224304357" MODIFIED="1774666619651" TEXT="ändert sich mit den Schritten des top-Level iterators">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Um das explizit klarzustellen:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
wir haben einen top-level Iterationsmechanismus, der mit jedem Step einen Iterierbaren Wert sichtbar macht, und zwar stets per Referenz (Referenz auf einen Container, bzw. auf ein IterSource-Interface)
|
||||
</li>
|
||||
<li>
|
||||
jedesmal wenn dieser top-Level einen Step macht, muß in einem <i>daneben liegenden inline-Buffer</i> ein neuer Handle-Typ erzeugt (und der alte zerstört) werden.
|
||||
</li>
|
||||
<li>
|
||||
während dann aber der flatten()-Mechanismus diesen nested-Iterator traversiert, bleibt dieses Handle an Ort und Stelle liegen
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774666641351" ID="ID_287267373" MODIFIED="1774666671361" TEXT="Container-by-Value könnte man wie ein Handle behandeln">
|
||||
<node CREATED="1774666683466" ID="ID_1194053201" MODIFIED="1774666710940">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
bedeutet ja, in der Pipeline liegt ein Iterator / eine Quelle, die den Container <b>generiert</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1774666712798" ID="ID_811972261" MODIFIED="1774666733359" TEXT="diesen Container-Value könnte man in einer Container-Core schieben..."/>
|
||||
<node CREATED="1774666734055" ID="ID_1811306623" MODIFIED="1774666745325" TEXT="diese liegt dann genau wie das Handle »daneben«"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774666914091" ID="ID_449870076" MODIFIED="1774666919474" TEXT="Spar-Variante">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1774666920826" ID="ID_210700855" MODIFIED="1774666947419" TEXT="nur Lumiera-Iterator und State-Core per Referenz unterstützen"/>
|
||||
<node CREATED="1774666948262" ID="ID_1832071317" MODIFIED="1774709423740" TEXT="dann wären das ganz einfach zu schreibende Adaptoren"/>
|
||||
</node>
|
||||
<node CREATED="1774709426313" ID="ID_1525744834" MODIFIED="1774709429255" TEXT="Beschluß">
|
||||
<node CREATED="1774709430054" ID="ID_912776044" MODIFIED="1774709438555" TEXT="baue zwei generische Adapter">
|
||||
<node CREATED="1774709804673" ID="ID_969333386" MODIFIED="1774709861157" TEXT="RedressAdapter">
|
||||
<node CREATED="1774709885131" ID="ID_801076314" MODIFIED="1774709900357" TEXT="dekoriert einen Lumiera-Iterator"/>
|
||||
<node CREATED="1774709901137" ID="ID_919308916" MODIFIED="1774709914396" TEXT="macht beim Zugriff einen reinterpret-cast"/>
|
||||
<node CREATED="1774709921111" ID="ID_1586230087" MODIFIED="1774709983338" TEXT="setzt zwingend einen Referenz-Quellwert voraus">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn sonst wäre es kein virtuelles redressing mehr, sondern die Konstruktion eines Wrappers
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774709864725" ID="ID_238153661" MODIFIED="1774709872674" TEXT="WrapperAdapter">
|
||||
<node CREATED="1774709996692" ID="ID_1695770853" MODIFIED="1774710058046" TEXT="ist ein vereinfachter / spezialisierter Transformer">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...der keine Operationen und Funktionen anwendet, sondern nur jeden Wert in einen neu-konstruierten Wrapper überführt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1774710061788" ID="ID_908839654" MODIFIED="1774710069599" TEXT="dekoriert einen Lumiera-Iterator"/>
|
||||
<node CREATED="1774710079276" ID="ID_1703742511" MODIFIED="1774710093211" TEXT="verwendet einen ItemWrapper als inline-Storage"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774710223103" ID="ID_492034668" MODIFIED="1774710285676" TEXT="der Builder macht eine eigenständige Fallunterscheidung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn die Analyse hat gezeigt, daß die DecoratorTraits zwar grundsätzlich das Feld richtig strukturieren, aber einige Differenzierungen nicht unterstützen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e1b4a0" COLOR="#690f14" CREATED="1774656919925" ID="ID_1646281580" MODIFIED="1774656946253" STYLE="fork" TEXT="auch der Transformer ist nicht auf nested Iterators ausgelegt">
|
||||
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node COLOR="#435e98" CREATED="1774657302055" ID="ID_789812720" MODIFIED="1774659939214" TEXT="⟹ das stellt das Schema mit dem ValueTypeBinding in Frage">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1774657328740" ID="ID_1402836149" MODIFIED="1774657358881" TEXT="warum ist da überhaupt dieses rekrusive Abgreifen einer Typedef eingebaut worden?">
|
||||
<node CREATED="1774657455680" ID="ID_514366098" MODIFIED="1774657461798" TEXT="es gibt auch andere Verwendungen"/>
|
||||
<node CREATED="1774657463633" ID="ID_1926724813" MODIFIED="1774657475099" TEXT="die arbeiten auf einem Container"/>
|
||||
<node CREATED="1774657475968" ID="ID_8083433" MODIFIED="1774657545675" TEXT="oder wollen tatsächlich den value_type eines Iterators">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
beispielsweise in stringify() ⟶ für welchen »wert«-Typ brauchen wir einen String-Konverter?
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774657428926" ID="ID_1704958302" MODIFIED="1774657492098" TEXT="also: nicht grundsätzlich — aber für Iterator-Pipelines">
|
||||
<node CREATED="1774657900271" ID="ID_1699849252" MODIFIED="1774657912582" TEXT="also : alle verwendungen durchsehen (ca 30)"/>
|
||||
<node COLOR="#435e98" CREATED="1774657913643" ID="ID_506237061" MODIFIED="1774657997027" TEXT="IterCursor ⟶ sollte die neuen iter::Traits verwenden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
da hier stets ein anderer Iterator eingewickelt wird (i.d.R. ein STL-Iterator); also brauchen wir die spezielle Logik, die STL-Iteratoren und Pointer korrekt behandelt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1774657998138" ID="ID_733523241" MODIFIED="1774658216456" TEXT="Itertools-Transformer ⟶ fehlerhaft — korrekt wären direkt die RefTraits">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1774658163972" ID="ID_1376599845" MODIFIED="1774658311373" TEXT="ScopePath : hat eine explizite Spezialisierung — das ist dann wohl sinnvoll">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Möglicherweise überflüssig durch die neue Logik, aber so eine explizite Spezialisierung direkt im Scope ist trotzdem vorteilhaft, weil man sie sieht, und die lokal vorhandenen Bedingungen explizit und fest berücksichtigt werden, ohne eine ggfs. fragile allgemeine Typ-Selektor-Logik einzubeziehen.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1774658332725" ID="ID_1972593986" MODIFIED="1774658354844" TEXT="IterExplorer-Transformer ⟶ fehlerhaft, analog zu Itertools">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774658412673" ID="ID_51319654" MODIFIED="1774658480912" TEXT="Itertools-GroupAggregator : korrekt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
schaut sich an, in was für einen Typ man Werte des unterliegenden, zu gruppierenden Iterators speichern kann — so soll das verwendet werden!
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774658506517" ID="ID_234360994" MODIFIED="1774658529696" TEXT="IterExplorer - top-Level — gleiche situation; korrekt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774658552959" ID="ID_823622776" MODIFIED="1774658604911" TEXT="IterExplorer-Builder: grouped(), groupedBy(), asPtr(), derefPrt(), deduplicate() — dto">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774659918584" ID="ID_1977782904" MODIFIED="1774659933329" TEXT="gefixt — funktioniert damit">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774659951194" ID="ID_369619908" MODIFIED="1774660011071" TEXT="Einfügen des Adapters unter dem Flattener schließt den unterliegenden IterExplorer mit ein">
|
||||
<node CREATED="1774660013562" ID="ID_596802349" MODIFIED="1774660038154" TEXT="das ist zwar harmlos, aber bläht den Pipeline-Typ unnötig auf"/>
|
||||
<node CREATED="1774660040017" ID="ID_1062014937" LINK="#ID_1720349507" MODIFIED="1774660392132" TEXT="so ein ähnliches Problem gab es doch schon mal beim iter-zip?">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1774660415777" ID="ID_1874366994" MODIFIED="1774660433102" TEXT="tatsächlich hinterläßt IterExplorer bereits ein Marker-Type-Tag">
|
||||
<node CREATED="1774660443001" ID="ID_884871958" MODIFIED="1774660447305" TEXT="dazu gibt es den _PipelineDetector"/>
|
||||
<node CREATED="1774660455664" ID="ID_647473304" MODIFIED="1774660467362" TEXT="der extrahiert den gestrippten Base-Iterator"/>
|
||||
<node CREATED="1774660486231" ID="ID_1351650503" MODIFIED="1774660526723" TEXT="und strippt auch gleich noch eine CheckedCore">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
weil die in einer solchen Situation, in der eine Pipeline erneut erweitert wird, i.d.R. redundant ist
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774660584342" ID="ID_1456209556" MODIFIED="1774660600528" TEXT="wird bisher nur in der top-Level-explore()-Funktion verwendet"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689102663805" ID="ID_1911278306" MODIFIED="1774633336499" TEXT="Ausbau der Teminal-Ausdrücke">
|
||||
<icon BUILTIN="edit"/>
|
||||
<node COLOR="#338800" CREATED="1689102690854" FOLDED="true" ID="ID_590768203" MODIFIED="1689182022574" TEXT="Terminal: effuse()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1689102718230" ID="ID_369108561" MODIFIED="1689182022601" TEXT="»materialisieren« in einen STL-kompatiblen Container">
|
||||
|
|
@ -53563,7 +54414,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1536409170928" ID="ID_1850744645" MODIFIED="1536515953937" TEXT="Design-Probleme">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1536409170928" ID="ID_1850744645" MODIFIED="1536515953937" TEXT="Design-Probleme">
|
||||
<icon BUILTIN="go"/>
|
||||
<node COLOR="#338800" CREATED="1535919506060" FOLDED="true" ID="ID_1587572708" MODIFIED="1573229614688" TEXT="heterogene Prädikat-Typen">
|
||||
<linktarget COLOR="#616f95" DESTINATION="ID_1587572708" ENDARROW="Default" ENDINCLINATION="49;-142;" ID="Arrow_ID_346491515" SOURCE="ID_1859852045" STARTARROW="None" STARTINCLINATION="-143;0;"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue