diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index f739198ea..9e2d54716 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -92,11 +92,14 @@ #define ENGINE_NODE_BUILDER_H +#include "lib/error.hpp" +#include "lib/nocopy.hpp" #include "steam/engine/weaving-pattern-builder.hpp" #include "steam/engine/proc-node.hpp" #include "steam/engine/turnout.hpp" #include "lib/several-builder.hpp" -#include "lib/nocopy.hpp" +#include "lib/format-string.hpp" +#include "lib/iter-index.hpp" #include "lib/test/test-helper.hpp"/////////////////////TODO TOD-oh #include @@ -105,9 +108,11 @@ namespace steam { namespace engine { + namespace err = lumiera::error; - using std::move; + using util::_Fmt; using std::forward; + using std::move; namespace { // default policy configuration to use heap allocator @@ -299,38 +304,56 @@ namespace engine { return move(*this); } + /** connect the next input slot to existing lead-node given by index */ PortBuilder connectLead (uint idx) { - UNIMPLEMENTED ("connect the next input slot to existing lead-node given by index"); - return move(*this); + return connectLeadPort (idx, this->defaultPort_); } + /** connect the next input slot to either existing or new lead-node" */ PortBuilder conectLead (ProcNode& leadNode) { - UNIMPLEMENTED ("connect the next input slot to either existing or new lead-node"); - return move(*this); + return connectLeadPort (leadNode, this->defaultPort_); } + /** connect next input to lead-node, using a specific port-number */ PortBuilder connectLeadPort (uint idx, uint port) { - UNIMPLEMENTED ("connect next input to lead-node, using a specific port-number"); + if (idx >= _Par::leads_.size()) + throw err::Logic{_Fmt{"Builder refers to lead-node #%d, yet only %d are currently defined."} + % idx % _Par::leads_.size() + ,LERR_(INDEX_BOUNDS) + }; + weavingBuilder_.attachToLeadPort (_Par::leads_[idx], port); return move(*this); } + /** connect next input to existing or new lead-node, with given port-number */ PortBuilder connectLeadPort (ProcNode& leadNode, uint port) { - UNIMPLEMENTED ("connect next input to existing or new lead-node, with given port-number"); + uint knownEntry{0}; + for (auto& lead : lib::IterIndex{_Par::leads_}) + if (util::isSameObject (leadNode, lead)) + break; + else + ++knownEntry; + if (knownEntry == _Par::leads_.size()) + _Par::addLead (leadNode); + + ENSURE (knownEntry < _Par::leads_.size()); + weavingBuilder_.attachToLeadPort (knownEntry, port); return move(*this); } + /** use given port-index as default for all following connections */ PortBuilder useLeadPort (uint defaultPort) { - UNIMPLEMENTED ("use given port-index as default for all following connections"); + this->defaultPort_ = defaultPort; return move(*this); } @@ -341,7 +364,7 @@ namespace engine { auto completePort() { - //////////////////////////////////////////////////////////OOO need to provide all links to lead nodes here + weavingBuilder_.connectRemainingInputs (_Par::leads_, this->defaultPort_); weavingBuilder_.fillRemainingBufferTypes(); return NodeBuilder{static_cast&&> (*this) // slice away PortBulder subclass data ,weavingBuilder_.sizMark @@ -353,7 +376,7 @@ namespace engine { PortBuilder(_Par&& base, FUN&& fun) : _Par{move(base)} , weavingBuilder_{forward (fun), _Par::leads_.policyConnect()} - , defaultPort_{0} ////////////////////////////////////////////////////////////////OOO brauche separaten Zähler! wo? + , defaultPort_{_Par::patternData_.size()} { } friend class PortBuilderRoot; diff --git a/src/steam/engine/proc-node.hpp b/src/steam/engine/proc-node.hpp index 8e8ad3f7e..e0cffe2e2 100644 --- a/src/steam/engine/proc-node.hpp +++ b/src/steam/engine/proc-node.hpp @@ -53,6 +53,7 @@ #include "steam/engine/turnout-system.hpp" #include "lib/frameid.hpp" #include "lib/ref-array.hpp" /////////////////////OOO phase out +#include "lib/format-string.hpp" #include "lib/several.hpp" #include @@ -62,10 +63,12 @@ namespace steam { namespace engine { + namespace err = lumiera::error; using std::move; using std::vector; //////////////TODO; using lumiera::NodeID; + using util::_Fmt; /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation class ProcNode; @@ -180,7 +183,11 @@ namespace engine { Port& getPort (uint portIdx) { - REQUIRE (portIdx <= wiring_.ports.size()); + if (portIdx >= wiring_.ports.size()) + throw err::Logic{_Fmt{"Accessing node-port #%d, while only %d ports are defined."} + % portIdx % wiring_.ports.size() + ,LERR_(INDEX_BOUNDS) + }; return wiring_.ports[portIdx]; } diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index 8686c60c4..c912eecc4 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -310,6 +310,8 @@ namespace engine { { BUILD buildEntry; + uint size() { return 1 + PAR::size(); } + template void collectEntries (DAB& dataBuilder, uint cntElm =0, uint maxSiz =0) @@ -331,6 +333,8 @@ namespace engine { */ struct PatternDataAnchor { + uint size() { return 0; } + template void collectEntries (DAB& dataBuilder, uint cntElm, uint maxSiz) @@ -373,18 +377,18 @@ namespace engine { , fun_{move(init)} { } - WeavingBuilder - attachToLeadPort(ProcNode& lead, uint portNr) + WeavingBuilder&& + attachToLeadPort (ProcNode& lead, uint portNr) { PortRef portRef{lead.getPort (portNr)}; leadPorts.append (portRef); - ENSURE (leadPorts.size() <= N); + ENSURE (leadPorts.size() <= N); /////////////////////////////////////OOO must throw exception here, since bounds can be violated by API usage return move(*this); } template - WeavingBuilder - appendBufferTypes(uint cnt) + WeavingBuilder&& + appendBufferTypes (uint cnt) { while (cnt--) buffTypes.emplace_back([](BufferProvider& provider) @@ -393,7 +397,7 @@ namespace engine { return move(*this); } - WeavingBuilder + WeavingBuilder&& fillRemainingBufferTypes() { auto constexpr FAN_O = FunSpec::FAN_O; @@ -402,8 +406,20 @@ namespace engine { return appendBufferTypes(cnt); } - WeavingBuilder - selectResultSlot(uint idx) + WeavingBuilder&& + connectRemainingInputs (DataBuilder& knownLeads, uint defaultPort) + { + auto constexpr FAN_I = FunSpec::FAN_I; + REQUIRE (leadPorts.size() <= FAN_I); + uint cnt = FAN_I - leadPorts.size(); + REQUIRE (leadPorts.size() + cnt <= knownLeads.size()); ////////////////////OOO determine if this should also be rather an exception? + while (cnt--) + attachToLeadPort (knownLeads[leadPorts.size()], defaultPort); + return move(*this); + } + + WeavingBuilder&& + selectResultSlot (uint idx) { this->resultSlot = idx; return move(*this); diff --git a/tests/library/iter-index-test.cpp b/tests/library/iter-index-test.cpp index 42b18e10b..93543e7bb 100644 --- a/tests/library/iter-index-test.cpp +++ b/tests/library/iter-index-test.cpp @@ -78,9 +78,9 @@ namespace test{ - /*****************************************************************//** - * @test demonstrate and cover the properties of IterCursor. - * This wrapper allows to change between iterating forward and backwards. + /************************************************************************//** + * @test verify adapter to iterate and navigate over array-like content, + * that can be accessed through subscript operator and `size()` function. * * @see iter-cursor.hpp * @see iter-adapter.hpp diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index bdae6d649..23a99ed8b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -9322,9 +9322,7 @@ - - - +

...setzt eigentliche Expand-Operation darunter voraus @@ -9503,9 +9501,7 @@ - - - +

das IterStateWrapper-API ist optimal @@ -9575,9 +9571,7 @@ - - - +

ganz anders als bei IterAdapter, wo das Sinn macht... @@ -9692,9 +9686,7 @@ - - - +

  • @@ -10027,9 +10019,7 @@ - - - +

    ...dort wird einfach on-demand in der Basisklasse nachgeschaut. @@ -10049,9 +10039,7 @@ - - - +

    Allerdings genügt es, dies an einer Stelle in der Kette zu ergänzen @@ -10059,9 +10047,7 @@ - - - +

    ...und zwar genau dort, wo erstmals ein Basis-Objekt akzeptiert wird. @@ -10077,9 +10063,7 @@ - - - +

    übrigens ist es im IterSource<T>::iterator nicht  notwendig @@ -10154,9 +10138,7 @@ - - - +

    Ticket machen: #1125 @@ -10501,9 +10483,7 @@ - - - +

    rein ein Problem mit der Test-Fixture. @@ -10663,9 +10643,7 @@ - - - +

    siehe std::shuffle @@ -11133,9 +11111,7 @@ - - - +

    ...weil es mutmaßlich @@ -11167,9 +11143,7 @@ - - - +

    Expand-Funktor hat einen Rückgabe-Typ @@ -11307,9 +11281,7 @@ - - - +

    ...will sagen @@ -11407,9 +11379,7 @@ - - - +

    ...mal sehen, ob wir jemals daran anstoßen... @@ -11422,9 +11392,7 @@ - - - +

    gemeint ist, @@ -11501,9 +11469,7 @@ - - - +

    IterSource muß insgesamt besser erweiterbar werden.... @@ -11519,9 +11485,7 @@ - - - +

    der Expander sitzt nun doch dahinter, in der Implementierung @@ -11544,9 +11508,7 @@ - - - +

    das Ergebnis ist der konkrete Iterator-Typ @@ -11632,9 +11594,7 @@ - - - +

    Wire-Tap-Implementierung @@ -11657,9 +11617,7 @@ - - - +

    das heißt, depth ist aktuelle Tiefe! @@ -11756,9 +11714,7 @@ - - - +

    ist partielle Lösung @@ -11778,9 +11734,7 @@ - - - +

    Ergebnis-Ausgabe ist die jeweilige mögliche Coverage @@ -11832,9 +11786,7 @@ - - - +

    ...insofern wir nur eine (partielle) Lösung signalisieren, @@ -12015,9 +11967,7 @@ - - - +

    YAGNI @@ -12079,9 +12029,7 @@ - - - +

    ...und nicht den möglichen Zustand. @@ -12205,9 +12153,7 @@ - - - +

    kann jedoch demonstrieren, @@ -12345,9 +12291,7 @@ - - - +

    ...das heißt: keine Wildcards, keine pseudo-Specs (currentWindow) @@ -12363,9 +12307,7 @@ - - - +

    Zweck ist vor allem, meta-Specs wie firstWindow, currentWindow aufzulösen @@ -12388,9 +12330,7 @@ - - - +

    ...verwendet einen GenNode-Tree @@ -12405,9 +12345,7 @@ - - - +

    Integration ViewLocator @@ -12430,9 +12368,7 @@ - - - +

    aber auch: Resolver @@ -12459,9 +12395,7 @@ - - - +

    die Regel ist: @@ -12485,9 +12419,7 @@ - - - +

    implementiert LocationQuery @@ -12520,9 +12452,7 @@ - - - +

    ...als Namespace-globale Variable mit externer Linkage @@ -12532,9 +12462,7 @@ - - - +

    Ein Lookup-Vorgang ist schon ehr aufwendig, @@ -12585,9 +12513,7 @@ - - - +

    ...welcher wiederum von ViewLocator betrieben @@ -12679,9 +12605,7 @@ - - - +

    existing() sollte default sein und create() explizit anzufordern @@ -12689,9 +12613,7 @@ - - - +

    weil der größte Teil aller real anzugebenden Regel-Klauseln @@ -12717,9 +12639,7 @@ - - - +

    komplett definierter Pfad incl Zielobjekt @@ -12729,9 +12649,7 @@ - - - +

    ggfs wird höchstes ein abschließendes Element hinzugefügt @@ -12741,9 +12659,7 @@ - - - +

    dieser Pfad ist stets anchored und partially covered @@ -12768,9 +12684,7 @@ - - - +

    zwar könnte es (später mal) sein, @@ -12802,9 +12716,7 @@ - - - +

    ...und zwar genau dann, wenn bereits die nächste Komponente unterhalb der Perspektive, @@ -12840,9 +12752,7 @@ - - - +

    ...sofern es stets eine Perspektive geben muß @@ -12884,9 +12794,7 @@ - - - +

    "muß" ist relativ, denn mit den bisherigen Anforderungen @@ -12905,9 +12813,7 @@ - - - +

    Die korrekte Semantik fällt uns hier wirklich in den Schoß, @@ -12923,9 +12829,7 @@ - - - +

    wobei einer, nämlich '*' sehr offensichtlich und bekannt ist, @@ -12938,9 +12842,7 @@ - - - +

    ...weil es eigentlich ein Wildcard ist, @@ -12956,9 +12858,7 @@ - - - +

    Korrekter Gebrauch setzt eigentlich voraus, @@ -13002,9 +12902,7 @@ - - - +

    bloß würde sich die Signatur der DSL-Bausteine ändern: @@ -13033,9 +12931,7 @@ - - - +

    Der Punkt ist: das ist eine reine Lauzeit/Effzienz-Überlegung. @@ -13074,9 +12970,7 @@ - - - +

    das ist der klassische Fall, wo man wegen einer solchen Optimierung @@ -13105,9 +12999,7 @@ - - - +

    ...insofern auch dort @@ -13153,9 +13045,7 @@ - - - +

    das ist eine typische, rein lokale Optimierung (Speicher vs CPU) @@ -13186,9 +13076,7 @@ - - - +

    es gibt nur einen "Locator" @@ -13246,9 +13134,7 @@ - - - +

    ein LocationSolver @@ -13259,9 +13145,7 @@ - - - +

    LocationQuery qua Navigator @@ -13272,9 +13156,7 @@ - - - +

    ...die es hinten herum bekommt @@ -13287,9 +13169,7 @@ - - - +

    sehen ViewLocator-API @@ -48665,9 +48545,7 @@ - - - +

    damit das DOM ein echtes DOM ist, muß es die relevanten real-Daten duplizieren, @@ -49393,9 +49271,7 @@ - - - +

    anfangs hatte ich da eine implizite Konvertierung. Man konnte schreiben ID{xyz}. Das war cool; und verwirrend; und hat jede Menge Ärger gemacht, wie immer @@ -49906,9 +49782,7 @@ - - - +

    Bus-Design is selbstähnlich @@ -50079,9 +49953,7 @@ - - - +

    Mechanismus, der es erlaubt @@ -50358,9 +50230,7 @@ - - - +

    wir verwenden die Basis-VTable @@ -88400,8 +88270,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    ...denn es sind noch die flexiblen Strategy-Templates darüber gelegt, und außerdem hatte ich den eigentlichen Allocator nur als protected-Mix-in eingebettet — und deshalb wird der für einen normalen (generierten) copy-Konstruktor nicht in sichtbar; kopiert würde ja auf dem gesamten (zusammengesetzten) Strategy-Template, und das hängt nominell durchaus vom Element-Typ ab, der aber in diesem Fall, beim Weitergeben einer Initialisierung, durchaus variabel sein kann (nur der Basis-Allokator ist stets kompatibel)

    - -
    +
    @@ -88430,8 +88299,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    damit man von einem existierenden SeveralBuilder ausgehend weiter verdrahten kann

    - - + @@ -88445,8 +88313,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    Konzeptionell ist das Strategy-Template offen angelegt, aber in der tatsächlichen Implementierung dürfte seine Rolle inzwischen weitgehend festgelegt sein. Und in diesem aktuellen Gebrauch spielt der Element-Typ nur eine Rolle zur Ansteuerung des Allocators, und auch die Konstruktor-Argumente werden komplett von oben bis auf die Basis-Ebene durchgereicht. Da zudem der Basis-Allocator an den C++-Standard angelehnt ist, kann man unterstellen, daß sich praktisch immer ein passender Alocator für einen anderen als den gegebenen Element-Typ konstruieren läßt.

    - - +
    @@ -90505,19 +90372,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    weil nur der PortBuilder seine eigene Position erschließen kann (weil er auf den geerbten DataBuilder zugreifen kann)

    - - + - + - + - + @@ -90525,10 +90391,58 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    d.h. der Default würde mit hochgezählt, kann aber per Setter auf andere Werte gesetzt werden

    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +

    + PRECONDITION: weaving-pattern-builder.hpp:415: thread_1: connectRemainingInputs: (leadPorts.size() + cnt <= knownLeads.size()) +

    +
    +
    + + + + + + +
    + + + + + + + +