From e46ff7a8a7784148c90dc211304ead8fb9c664b1 Mon Sep 17 00:00:00 2001
From: Ichthyostega
Date: Sun, 1 Dec 2024 05:24:12 +0100
Subject: [PATCH] Invocation: switch `WeavingPattern` and Level-1 builder to
the reworked `FeedManifold`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After the complete makeover of the `FeedManifold` structure,
which among other entails a switch from ''buffer arrays'' to tuples
and the ''introduction of a parameter tuple'', this changeset now
switches the „downstream code“ of the builder and node invocation,
relying on an largely identical invocation API.
The partially finished NodeLink_test now **runs as before**
but on top of a drastically more flexible and open infrastructure.
Quite a feat.
---
src/steam/engine/feed-manifold.hpp | 36 +-
src/steam/engine/node-builder.hpp | 2 +-
src/steam/engine/turnout.hpp | 8 +-
src/steam/engine/weaving-pattern-builder.hpp | 80 ++-
src/steam/engine/weaving-pattern.hpp | 62 +-
tests/core/steam/engine/node-base-test.cpp | 12 +-
tests/core/steam/engine/node-link-test.cpp | 4 +-
wiki/thinkPad.ichthyo.mm | 655 ++++++++++++++++---
8 files changed, 728 insertions(+), 131 deletions(-)
diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp
index 8f1f034e0..8869295a8 100644
--- a/src/steam/engine/feed-manifold.hpp
+++ b/src/steam/engine/feed-manifold.hpp
@@ -216,6 +216,10 @@ namespace engine {
using ArgO = typename ElmTypes::Seq;
using ArgP = typename ElmTypes::Seq;
+ // Metaprogramming helper for Buffer types (sans pointer)
+ using ElmsI = ElmTypes::template Apply>;
+ using ElmsO = ElmTypes::template Apply>;
+
enum{ FAN_I = ElmTypes::SIZ
, FAN_O = ElmTypes::SIZ
, FAN_P = ElmTypes::SIZ
@@ -457,6 +461,7 @@ namespace engine {
struct FeedManifold
: _StorageSetup::Storage
{
+ using _T = _ProcFun;
using _S = _StorageSetup;
using _F = typename _S::Storage;
@@ -493,8 +498,8 @@ namespace engine {
return arg;
}
- using TupI = typename ElmTypes::Tup;
- using TupO = typename ElmTypes::Tup;
+ using TupI = typename _T::ElmsI::Tup;
+ using TupO = typename _T::ElmsO::Tup;
void
@@ -504,7 +509,7 @@ namespace engine {
{
forEachIDX ([&](auto i)
{
- using BuffI = remove_pointer_t>;
+ using BuffI = tuple_element_t;
accessArg (_F::inArgs) = & _F::inBuff[i].template accessAs();
});
}
@@ -512,7 +517,7 @@ namespace engine {
{
forEachIDX ([&](auto i)
{
- using BuffO = remove_pointer_t>;
+ using BuffO = tuple_element_t;
accessArg (_F::outArgs) = & _F::outBuff[i].template accessAs();
});
}
@@ -552,7 +557,7 @@ namespace engine {
* parameter-functor with the **cross-builder-API**, a _new instance_ of the prototype
* is created _as a replacement_ of the old one (note: we move the processing functor).
* This adds a parameter-functor to the configuration, which will then be invoked
- * _whenever a new FeedManifold instance_ [is created](\ref #createFeed); the result of
+ * _whenever a new FeedManifold instance_ [is created](\ref #buildFeed); the result of
* this parameter-functor invocation should be a parameter value, which can be passed
* into the constructor of FeedManifold, together with a copy of the proc-functor.
* @see NodeBase_test::verify_FeedPrototype()
@@ -561,13 +566,26 @@ namespace engine {
class FeedPrototype
: util::MoveOnly
{
+ using _Proc = _ProcFun;
using _Trait = _ParamFun;
- using Feed = FeedManifold;
FUN procFun_;
PAM paramFun_;
public:
+ using Feed = FeedManifold;
+ enum{ FAN_I = Feed::FAN_I
+ , FAN_O = Feed::FAN_O
+ , FAN_P = Feed::FAN_P
+ };
+ using ElmsI = typename _Proc::ElmsI;
+ using ElmsO = typename _Proc::ElmsO;
+
+ template class META>
+ using OutTypesApply = typename ElmsO::template Apply;
+
+
+ /** setup with processing-functor only */
FeedPrototype (FUN&& proc)
: procFun_{move (proc)}
, paramFun_{}
@@ -583,16 +601,16 @@ namespace engine {
static constexpr bool hasParamFun() { return _Trait::template isParamFun(); }
static constexpr bool canActivate() { return _Trait::template canActivate(); }
- /** @return runtime test: there is actually usable parameter-functor to invoke? */
+ /** @return runtime test: actually usable parameter-functor available to invoke? */
bool isActivated() const { return _Trait::isActivated(paramFun_); }
/************************************************************//**
- * build suitable Feed(Manifold) for processing a Node invocation
+ * create suitable Feed(Manifold) for processing a Node invocation
*/
Feed
- createFeed (TurnoutSystem& turnoutSys)
+ buildFeed (TurnoutSystem& turnoutSys)
{
if constexpr (hasParamFun())
if (isActivated())
diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp
index f3c4b2dc3..81c86e79c 100644
--- a/src/steam/engine/node-builder.hpp
+++ b/src/steam/engine/node-builder.hpp
@@ -361,7 +361,7 @@ namespace engine {
completePort()
{
weavingBuilder_.connectRemainingInputs (_Par::leads_, this->defaultPort_);
- weavingBuilder_.fillRemainingBufferTypes();
+ weavingBuilder_.fillRemainingBufferTypes(); ////////////////////////////////////////////////////////////////////OOO Nein! sollte gleich zu Beginn (automatisch) passieren
return NodeBuilder{static_cast&&> (*this) // slice away PortBulder subclass data
,weavingBuilder_.sizMark
,weavingBuilder_.build()};
diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp
index c648b0862..2ec2fb055 100644
--- a/src/steam/engine/turnout.hpp
+++ b/src/steam/engine/turnout.hpp
@@ -76,7 +76,9 @@ namespace engine {
constexpr bool
_verify_usable_as_InvocationAdapter()
{
- ASSERT_MEMBER_FUNCTOR (&ADA::connect, void(uint, uint));
+ // also: array-like outBuff
+ // optionally array-like inBuff
+ ASSERT_MEMBER_FUNCTOR (&ADA::connect, void());
ASSERT_MEMBER_FUNCTOR (&ADA::invoke, void());
return sizeof(ADA);
}
@@ -87,7 +89,7 @@ namespace engine {
_verify_usable_as_WeavingPattern()
{
using Feed = typename PAT::Feed;
- ASSERT_MEMBER_FUNCTOR (&PAT::mount, Feed());
+ ASSERT_MEMBER_FUNCTOR (&PAT::mount, Feed(TurnoutSystem&));
ASSERT_MEMBER_FUNCTOR (&PAT::pull, void(Feed&, TurnoutSystem&));
ASSERT_MEMBER_FUNCTOR (&PAT::shed, void(Feed&, OptionalBuff));
ASSERT_MEMBER_FUNCTOR (&PAT::weft, void(Feed&));
@@ -129,7 +131,7 @@ namespace engine {
BuffHandle
weave (TurnoutSystem& turnoutSys, OptionalBuff outBuff =std::nullopt) override
{
- Feed feed = PAT::mount();
+ Feed feed = PAT::mount(turnoutSys);
PAT::pull(feed, turnoutSys);
PAT::shed(feed, outBuff);
PAT::weft(feed);
diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp
index 5362e5565..69ae81e17 100644
--- a/src/steam/engine/weaving-pattern-builder.hpp
+++ b/src/steam/engine/weaving-pattern-builder.hpp
@@ -101,6 +101,7 @@
#include "steam/engine/weaving-pattern.hpp"
#include "steam/engine/buffer-provider.hpp"
#include "steam/engine/buffhandle-attach.hpp" /////////////////OOO why do we need to include this? we need the accessAs() template function
+#include "lib/meta/tuple-helper.hpp"
#include "lib/test/test-helper.hpp" ////////////////////////////OOO TODO added for test
#include "lib/format-string.hpp"
#include "lib/iter-zip.hpp"
@@ -225,8 +226,8 @@ namespace engine {
- template
- using SimpleDirectInvoke = MediaWeavingPattern>;
+// template
+// using SimpleDirectInvoke = MediaWeavingPattern>;
/**
@@ -246,11 +247,13 @@ namespace engine {
struct WeavingBuilder
: util::MoveOnly
{
- using FunSpec = _ProcFun;
- using TurnoutWeaving = Turnout>;
+ using FunSpec = _ProcFun; ///////////////////////////////////TODO remove this!!!
+ using Prototype = typename FeedManifold::Prototype;
+ using WeavingPattern = MediaWeavingPattern;
+ using TurnoutWeaving = Turnout;
static constexpr SizMark sizMark{};
- static constexpr uint FAN_I = FunSpec::FAN_I;
- static constexpr uint FAN_O = FunSpec::FAN_O;
+ static constexpr uint FAN_I = Prototype::FAN_I;
+ static constexpr uint FAN_O = Prototype::FAN_O;
using TypeMarker = std::function;
@@ -271,6 +274,7 @@ namespace engine {
template
WeavingBuilder(FUN&& init, StrView nodeSymb, StrView portSpec, INIT&& ...alloInit)
: leadPorts{forward (alloInit)...}
+ , buffTypes{fillDefaultBufferTypes()}
, nodeSymb_{nodeSymb}
, portSpec_{portSpec}
, fun_{move(init)}
@@ -305,11 +309,16 @@ namespace engine {
return move(*this);
}
+ /** @deprecated handling of output buffer configuration should be "the other way round":
+ * Instead of filling-in, a default should be established at start,
+ * which can then arbitrarily be refined
+ */
WeavingBuilder&&
- fillRemainingBufferTypes()
+ fillRemainingBufferTypes() ///////////////////////////////////////////////////OOO Buffer-Typen gleich zu Beginn default-belegen
{
using BuffO = typename FunSpec::BuffO;
uint cnt = FAN_O - buffTypes.size();
+ENSURE (cnt == 0); ///////////////////////////////////////////////////////////////////OOO already filled in constructor now -- remove this code
return appendBufferTypes(cnt);
}
@@ -352,8 +361,8 @@ namespace engine {
outTypes.append (
typeConstructor (providers[i]));
- ENSURE (leadPorts.size() == FunSpec::FAN_I);
- ENSURE (outTypes.size() == FunSpec::FAN_O);
+ ENSURE (leadPorts.size() == FAN_I);
+ ENSURE (outTypes.size() == FAN_O);
using PortDataBuilder = DataBuilder;
// provide a free-standing functor to build a suitable Port impl (≙Turnout)
@@ -381,6 +390,59 @@ namespace engine {
for (uint i=providers.size(); i < maxSlots; ++i)
providers.emplace_back (ctx().mem);
}
+
+ /**
+ * @internal configuration builder for buffer descriptors
+ * @tparam BU target type of the buffer (without pointer)
+ * The FeedPrototype can generate for the given \a FUN a
+ * type sequence of output buffer types, which are used
+ * to instantiate this template and then later to work
+ * on specific output buffer slots.
+ */
+ template
+ struct BufferDescriptor
+ {
+ /**
+ * Setup the constructor function for the default BufferDescriptors.
+ * @return a functor that can be applied to the actual BufferProviders
+ * at the point when everything for this port is configured.
+ */
+ TypeMarker
+ makeBufferDescriptor() const
+ {
+ return [](BufferProvider& provider)
+ { return provider.getDescriptor(); };
+ }
+ };
+
+ using OutTypesDescriptors = typename Prototype::template OutTypesApply;
+ using OutDescriptorTup = lib::meta::Tuple;
+
+ /** A tuple of BufferDescriptor instances for all output buffer types */
+ static constexpr OutDescriptorTup outDescriptors{};
+
+ /** @internal pre-initialise the buffTypes vector with a default configuration.
+ * @remarks In the _terminal step,_ the buffTypes will be transformed into a
+ * sequence of BufferDescriptor entries, which can later be used
+ * by the node invocation to prepare a set of output buffers.
+ * - each slot holds a function
+ * - these can be used to configure specific setup for some buffers
+ * - the default BufferDescriptor will just default-construct the
+ * designated «output slot» of the media processing-function.
+ */
+ static auto
+ fillDefaultBufferTypes()
+ {
+ std::vector defaultBufferTypes;
+ defaultBufferTypes.reserve (std::tuple_size_v);
+ lib::meta::forEach(outDescriptors
+ ,[&](auto& desc)
+ {
+ defaultBufferTypes.emplace_back(
+ desc.makeBufferDescriptor());
+ });
+ return defaultBufferTypes;
+ }
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : (End)Prototyping: how to assemble a Turnout
diff --git a/src/steam/engine/weaving-pattern.hpp b/src/steam/engine/weaving-pattern.hpp
index cfe80ce53..84fea30b5 100644
--- a/src/steam/engine/weaving-pattern.hpp
+++ b/src/steam/engine/weaving-pattern.hpp
@@ -85,10 +85,12 @@ namespace engine {
* @note assumptions made regarding the overall structure
* - `INVO::Feed` defines an _invocation adapter_ for the processing function
* - `INVO::buildFeed()` is a functor to (repeatedly) build `Feed` instances
- * - the _invocation adapter_ in turn embeds a `FeedManifold` to hold
- * + an array of input buffer pointers
- * + an array of output buffer pointers
- * + `INVO::MAX_SIZ` limits both arrays
+ * - the _invocation adapter_ in turn embeds a `FeedManifold` to hold
+ * + a setup of output buffer pointers (single, tuple or array)
+ * + (optionally) a similar setup for input buffer pointers
+ * + (optionally) a parameter or parameter tuple
+ * + storage to configure BuffHandle entries for each «slot»
+ * + storage to hold the actual processing functor
*/
template
struct MediaWeavingPattern
@@ -117,32 +119,35 @@ namespace engine {
Feed
- mount()
+ mount (TurnoutSystem& turnoutSys)
{
- return INVO::buildFeed();
+ ENSURE (leadPort.size() <= INVO::FAN_I);
+ ENSURE (outTypes.size() <= INVO::FAN_O);
+ return INVO::buildFeed (turnoutSys);
}
void
pull (Feed& feed, TurnoutSystem& turnoutSys)
{
- for (uint i=0; i() == -55);
@@ -370,7 +370,7 @@ namespace test {
CHECK (not P1x::canActivate());
P1x p1x = p1.moveAdapted (move(fun_paramSimple));
- M1 m1x = p1x.createFeed(turSys); // ◁————————— param-functor invoked here
+ M1 m1x = p1x.buildFeed(turSys); // ◁————————— param-functor invoked here
CHECK (rr == m1x.param); // ...as indicated by the side-effect
short r1 = m1x.param;
@@ -387,7 +387,7 @@ namespace test {
CHECK (calcResult == r1 - 1); // as does m1x, without invoking the param-functor
// create yet another instance from the prototype...
- M1 m1y = p1x.createFeed(turSys); // ◁————————— param-functor invoked here
+ M1 m1y = p1x.buildFeed(turSys); // ◁————————— param-functor invoked here
CHECK (rr == m1y.param);
CHECK (r1 < m1y.param); // ...note again the side-effect
m1y.outBuff.createAt(0, buff);
@@ -423,18 +423,18 @@ namespace test {
CHECK (not p1f.isActivated()); // yet in current runtime configuration, the function is empty
// create a FeedManifold instance from this prototype
- M1 m1f1 = p1f.createFeed(turSys); // no param-functor invoked,
+ M1 m1f1 = p1f.buildFeed(turSys); // no param-functor invoked,
CHECK (m1f1.param == short{}); // so this FeedManifold will use the default-constructed parameter
// but since std::function is assignable, we can activate it...
CHECK (not p1f.isActivated());
p1f.assignParamFun ([](TurnoutSystem&){ return 47; });
CHECK ( p1f.isActivated());
- M1 m1f2 = p1f.createFeed(turSys); // ◁————————— param-functor invoked here
+ M1 m1f2 = p1f.buildFeed(turSys); // ◁————————— param-functor invoked here
CHECK (m1f2.param == 47); // ...surprise: we got number 47...
p1f.assignParamFun();
CHECK (not p1f.isActivated()); // can /deactivate/ it again...
- M1 m1f3 = p1f.createFeed(turSys); // so no param-functor invoked here
+ M1 m1f3 = p1f.buildFeed(turSys); // so no param-functor invoked here
CHECK (m1f3.param == short{});
// done with buffer
diff --git a/tests/core/steam/engine/node-link-test.cpp b/tests/core/steam/engine/node-link-test.cpp
index 86edfbc00..2d4bcea91 100644
--- a/tests/core/steam/engine/node-link-test.cpp
+++ b/tests/core/steam/engine/node-link-test.cpp
@@ -112,7 +112,7 @@ SHOW_EXPR(metaN1.genNodeSpec(con.leads))
/** @test TODO Use existing node connectivity to generate a TurnoutSystem
- * @todo WIP 7/24 🔁 define ⟶ implement
+ * @todo WIP 12/24 🔁 define ⟶ implement
*/
void
generate_turnout_system()
@@ -122,7 +122,7 @@ SHOW_EXPR(metaN1.genNodeSpec(con.leads))
/** @test TODO Invoke some render nodes as linked together
- * @todo WIP 7/24 🔁 define ⟶ implement
+ * @todo WIP 12/24 🔁 define ⟶ implement
*/
void
trigger_node_port_invocation()
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index fbfd0a054..f616fad8a 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -1,6 +1,6 @@
-
-
+
@@ -92460,8 +92442,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
prototype.clone() ⟶ Kopie falls beide Funktoren das erlauben
-
-
+
@@ -92480,7 +92461,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -92707,8 +92688,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
>;
-
-
+
@@ -92752,8 +92732,21 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+ ...das war der Name im Prototyping-Entwurf, und der ist viel besser!
+
+
+
+
+
+
-
+
+
@@ -92786,6 +92779,26 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+ FeedPrototype wird zur Gelenkstelle zum WeavingPatternBuilder
+
+
+
+
+
+
+
+
+
+
+
+
@@ -92794,7 +92807,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -92841,8 +92854,174 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+
+ FeedPrototype wird zentraler Konfigurationspunkt
+
+
+
+
+
+
-
+
+
+
+
+
+ «InvocationAdapter» ist nun stets die FeedManifold
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Output-Buffer-Typ-Default
+
+
+ muß von unten kommen
+
+
+
+
+
+
+
+
+
+
+ hatte im Juli 24 noch keinerlei Durchblick und ging außerdem davon aus, direkt auf den Ergebnis-Daten in lib::SeveralBuilder zu arbeiten; daher der Ansatz mit "Einfüllen"
+
+
+
+
+
+
+
+
+
+ Im Gegensatz zur Konfiguration der Lead-Ports ist diese ganze Buffer-Belegungs-Thematik weitgehend undifferenziert — es ist nur klar daß wir von irgendwoher einen Buffer brauchen, und daß es typisierte BufferDeskcriptoren gibt. Also hatte ich seinerzeit (Juli 24) die Behandlung symmetrisch zur Eingangs-Seite aufgezogen, und erst mal eine default-Konfiguration für jeden »Slot« gemacht. Dann, mit dem Umbau der FeedManifold (Dezember 24) ergab sich Möglichkeit (und Notwendigkeit), jeden Ausgabe-Slot individuell zu konfigurieren
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diese Schachtel möchte ich nicht nach außen aufmachen...
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ich möchte definitiv nicht
+
+
+ -
+ daß auch nur der WeavingBuilder noch direkt mit der Typ-Repräsentation der FeedManifold herumfummelt
+
+ -
+ ich möchte aber auch nicht, daß der FeedPrototype nun maßgeschneiderte Daten für die Interna eines WeavingBuilders liefert
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lösung: Iteration über ein Buffer-Descriptor-Tupel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hat noch so einige Tücken, wiewohl es im Prinzip einfach ist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -92860,8 +93039,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
die interne Logik ist so aufgebaut, daß sie sich dann durchgehend korrekt verhält, ohne daß dafür viel getan werden müßte; es muß lediglich eine Funktion sein, und kein brauchbares Ergebnis liefern
-
-
+
@@ -92903,6 +93081,17 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+
+
+
+
@@ -92924,7 +93113,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -93143,7 +93332,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -93302,7 +93491,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -93448,6 +93637,285 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+ Strategie: während des Umbaues den alten downstream-Code compilierbar gehalten
+
+
+
+
+
+
+
+
+ und zwar, indem ich zunächst die Type-Traits umgestellt habe, und dann den alten Code auf das neue Traits-Inteface portiert. Damit konnte ich die alte Implementierung der FeedManifold (als "FoldManifeed" ☺) im Code erhalten — und alles was darunter hängt...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Haha! Nur ist das jetzt eines der zentralen Gelenkstellen im FeedPrototype geworden — oh oh oh wenn das alles bloß nicht so spannend wäre, könnte man ja glatt anderen Leuten davon erzählen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ich habe die Einbindung in ein fixed-size-Array der Größe N komplett aufgegeben, zugunsten einer flexiblen, Tuple-basierten Storage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alle Argumente ab dem 4.Argument gehen pauschal durch an INVO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ der Prototype kann uns einen Tupel-Typ der Output-Buffer-Typen konstruieren
+
+ -
+ zusätzlich können wir ElmTypes<TUP>::Apply verwenden
+
+ -
+ damit kann man lokal im WeavingPatternBuilder ein »Handler-Template« für jeden Buffer-Typ instantiieren
+
+ -
+ in dieses könen wir die lokale Builder-Logik einbauen
+
+ -
+ und darauf auch laufzeit-indiziert zugreifen
+
+ -
+ oder statisch iterieren
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -93709,7 +94177,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
+
@@ -93735,6 +94204,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
@@ -93893,7 +94363,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -94831,6 +95301,43 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ im WeavingBuilder:
+
+
+ using TypeMarker = std::function<BuffDescr(BufferProvider&)>;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -96216,7 +96723,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -99166,6 +99673,10 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
@@ -144581,8 +145092,7 @@ std::cout << tmpl.render({"what", "World"}) << s
entscheiden
-
-
+
@@ -144610,8 +145120,7 @@ std::cout << tmpl.render({"what", "World"}) << s
Das bedeutet: ein Funktionspointer mit passender Signatur kann von einem λ initialisiert werden und kann dann die dahinter stehende Funktion aufrufen. Vermutlich als Kompatibilität zu C-Callbacks gedacht....
-
-
+