Invocation: develop an abbreviated node spec
showing the Node-symbol and a reduced rendering of either the predecessor or a collection of source nodes. For this we need functionality to traverse the node graph depth-first and collect all leaf nodes (which are the source nodes without predecessor); such can be implemented with the help of the expandAll() functionality of `lib::IterExplorer`. In addition we need to collect, sort and deduplicate all the source-node specs; since this is a common requirement, a new convenience builder was added to `lib::IterExplorer`
This commit is contained in:
parent
85e2966975
commit
a84dbd7bfb
9 changed files with 321 additions and 53 deletions
|
|
@ -240,7 +240,7 @@ namespace util {
|
|||
return join (stringify (args...), "-");
|
||||
}
|
||||
|
||||
/** shortcut: join directly with dashes */
|
||||
/** shortcut: join directly with dots */
|
||||
template<typename...ARGS>
|
||||
inline string
|
||||
joinDot (ARGS const& ...args)
|
||||
|
|
|
|||
|
|
@ -578,6 +578,52 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to »piggy-back« a STL iterable container inline and expose it as »state core«.
|
||||
* @warning be sure to understand the implications of this setup
|
||||
* - when initialised by reference, the container's contents will be copied
|
||||
* - when move-initialised, the container will be destroyed with this iterator
|
||||
* - the container API remains visible (baseclass), which could confuse trait detection
|
||||
*/
|
||||
template<class CON>
|
||||
class ContainerCore
|
||||
: public CON
|
||||
{
|
||||
using Iter = typename CON::iterator;
|
||||
|
||||
Iter p_;
|
||||
|
||||
public:
|
||||
ContainerCore (CON&& container)
|
||||
: CON(std::forward<CON>(container))
|
||||
, p_{CON::begin()}
|
||||
{ }
|
||||
|
||||
// copy and assignment acceptable (warning!)
|
||||
|
||||
|
||||
/* === »state core« protocol API === */
|
||||
bool
|
||||
checkPoint() const
|
||||
{
|
||||
return p_ != CON::end();
|
||||
}
|
||||
|
||||
decltype(auto)
|
||||
yield() const
|
||||
{
|
||||
return *p_;
|
||||
}
|
||||
|
||||
void
|
||||
iterNext()
|
||||
{
|
||||
++p_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decorator-Adapter to make a »state core« iterable as Lumiera Forward Iterator.
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@
|
|||
//Forward declaration to allow a default result container for IterExplorer::effuse
|
||||
namespace std {
|
||||
template<typename T, class A> class vector;
|
||||
template<typename K, typename CMP, class A> class set;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1881,6 +1882,24 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
/** preconfigured decorator to materialise, sort and deduplicate all source elements.
|
||||
* @warning uses heap storage to effuse the source pipeline immediately
|
||||
*/
|
||||
template<template<typename> class SET =std::set>
|
||||
auto
|
||||
deduplicate()
|
||||
{
|
||||
using Value = typename meta::ValueTypeBinding<SRC>::value_type;
|
||||
using ResCore = ContainerCore<SET<Value>>;
|
||||
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
|
||||
SET<Value> buffer;
|
||||
for (auto& val : *this)
|
||||
buffer.emplace (val);
|
||||
// »piggiy-back« the collected data into the result iterator
|
||||
return IterExplorer<ResIter>{ResCore{move (buffer)}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** _terminal builder_ to package the processing pipeline as IterSource.
|
||||
* Invoking this function moves the whole iterator compound, as assembled by the preceding
|
||||
|
|
|
|||
|
|
@ -40,8 +40,9 @@
|
|||
#define ENGINE_PROC_ID_H
|
||||
|
||||
|
||||
#include "lib/hash-standard.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/hash-standard.hpp"
|
||||
#include "lib/several.hpp"
|
||||
//#include "steam/streamtype.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -55,6 +56,7 @@ namespace engine {
|
|||
using std::string;
|
||||
using StrView = std::string_view;
|
||||
|
||||
class ProcNode;
|
||||
|
||||
class ProcID
|
||||
{
|
||||
|
|
@ -64,14 +66,20 @@ namespace engine {
|
|||
|
||||
ProcID (StrView nodeSymb, StrView portQual, StrView argLists);
|
||||
|
||||
using ProcNodeRef = std::reference_wrapper<ProcNode>;
|
||||
using Leads = lib::Several<ProcNodeRef>;
|
||||
|
||||
public:
|
||||
/** build and register a processing ID descriptor */
|
||||
static ProcID& describe (StrView nodeSymb, StrView portSpec);
|
||||
|
||||
/* === symbolic descriptors === */
|
||||
|
||||
string genProcSpec(); ///< render a descriptor for the operation (without predecessors)
|
||||
|
||||
string genProcName();
|
||||
string genProcSpec(); ///< render a descriptor for the operation (without predecessors)
|
||||
string genNodeName();
|
||||
string genNodeSpec(Leads&);
|
||||
string genSrcSpec (Leads&); ///< transitively enumerate all unique source nodes
|
||||
|
||||
friend bool
|
||||
operator== (ProcID const& l, ProcID const& r)
|
||||
|
|
|
|||
|
|
@ -30,27 +30,32 @@
|
|||
|
||||
#include "steam/engine/proc-id.hpp"
|
||||
#include "steam/engine/proc-node.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/format-util.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace steam {
|
||||
namespace engine {
|
||||
|
||||
using lib::explore;
|
||||
using util::_Fmt;
|
||||
using util::isnil;
|
||||
using util::unConst;
|
||||
using util::contains;
|
||||
using boost::hash_combine;
|
||||
|
||||
namespace { // Details...
|
||||
namespace {// Details: registration and symbol table for node spec data...
|
||||
|
||||
std::unordered_set<ProcID> procRegistry;
|
||||
std::unordered_set<string> symbRegistry;
|
||||
|
||||
/** deduplicate and re-link to the entry in the symbol table */
|
||||
void inline
|
||||
dedupSymbol (StrView& symbol)
|
||||
{
|
||||
|
|
@ -60,7 +65,6 @@ namespace engine {
|
|||
} // (END) Details...
|
||||
|
||||
|
||||
// using mobject::Placement;
|
||||
|
||||
Port::~Port() { } ///< @remark VTables for the Port-Turnout hierarchy emitted from \ref proc-node.cpp
|
||||
|
||||
|
|
@ -96,14 +100,15 @@ namespace engine {
|
|||
|
||||
/** @internal */
|
||||
ProcID::ProcID (StrView nodeSymb, StrView portQual, StrView argLists)
|
||||
: nodeSymb_{nodeSymb} /////////////////////////////////////////////////////////OOO intern these strings!!
|
||||
: nodeSymb_{nodeSymb}
|
||||
, portQual_{portQual}
|
||||
, argLists_{argLists}
|
||||
{ }
|
||||
|
||||
/** generate registry hash value based on the distinct data in ProcID.
|
||||
* This function is intended to be picked up by ADL, and should be usable
|
||||
* both with `std::hash` and `<boost/functional/hash.hpp>`.
|
||||
/**
|
||||
* generate registry hash value based on the distinct data in ProcID.
|
||||
* This function is intended to be picked up by ADL, and should be usable
|
||||
* both with `std::hash` and `<boost/functional/hash.hpp>`.
|
||||
*/
|
||||
HashVal
|
||||
hash_value (ProcID const& procID)
|
||||
|
|
@ -115,6 +120,16 @@ namespace engine {
|
|||
return hash;
|
||||
}
|
||||
|
||||
string
|
||||
ProcID::genProcName()
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
buffer << nodeSymb_;
|
||||
if (not isnil(portQual_))
|
||||
buffer << '.' << portQual_;
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
string
|
||||
ProcID::genProcSpec()
|
||||
{
|
||||
|
|
@ -126,12 +141,65 @@ namespace engine {
|
|||
return buffer.str();
|
||||
}
|
||||
|
||||
string
|
||||
ProcID::genNodeName()
|
||||
{
|
||||
return string{nodeSymb_};
|
||||
}
|
||||
|
||||
|
||||
namespace { // Helper to access ProcID recursively
|
||||
ProcID&
|
||||
procID (ProcNode& node)
|
||||
{
|
||||
REQUIRE (not isnil(watch(node).ports()));
|
||||
return watch(node).ports().front().procID;
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
ProcID::genNodeSpec (Leads& leads)
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
buffer << nodeSymb_;
|
||||
if (1 != leads.size())
|
||||
buffer << genSrcSpec(leads);
|
||||
else
|
||||
{ // single chain....
|
||||
ProcNode& p{leads.front().get()};
|
||||
buffer << "◁—"
|
||||
<< procID(p).genNodeName() // show immediate predecessor
|
||||
<< procID(p).genSrcSpec(leads); // and behind that recursively the source(s)
|
||||
}
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
string
|
||||
ProcID::genSrcSpec (Leads& leads)
|
||||
{
|
||||
return isnil(leads)? string{"-◎"} // no leads => starting point itself is a source node
|
||||
: "┉┉{"
|
||||
+ util::join(
|
||||
explore(leads)
|
||||
.expandAll([](ProcNode& n){ return explore(watch(n).leads()); }) // depth-first expand all predecessors
|
||||
.filter ([](ProcNode& n){ return watch(n).isSrc(); }) // but retain only leafs (≙ source nodes)
|
||||
.transform([](ProcNode& n){ return procID(n).nodeSymb_;}) // render the node-symbol of each src
|
||||
.deduplicate()) // sort and deduplicate
|
||||
+ "}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return symbolic string with format `NodeSymb--<predecessorSpec>`
|
||||
* @remark connectivity information is abbreviated and foremost
|
||||
* indicates the data source(s)
|
||||
*/
|
||||
string
|
||||
ProcNodeDiagnostic::getNodeSpec()
|
||||
{
|
||||
UNIMPLEMENTED ("generate a descriptive Spec of this ProcNode for diagnostics");
|
||||
REQUIRE (not isnil(ports()));
|
||||
return ports().front().procID.genNodeSpec (leads());
|
||||
}
|
||||
|
||||
HashVal
|
||||
|
|
|
|||
|
|
@ -239,6 +239,8 @@ namespace engine {
|
|||
auto& leads() { return n_.wiring_.leads; }
|
||||
auto& ports() { return n_.wiring_.ports; }
|
||||
|
||||
bool isSrc() { return n_.wiring_.leads.empty(); }
|
||||
|
||||
bool
|
||||
isValid()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,10 +85,9 @@ namespace test {
|
|||
CHECK (watch(n1).isValid());
|
||||
CHECK (watch(n1).leads().empty());
|
||||
CHECK (watch(n1).ports().size() == 1);
|
||||
SHOW_EXPR(watch(n1).getPortSpec(0))
|
||||
|
||||
// can generate a symbolic spec to describe the Port's processing functionality...
|
||||
CHECK (watch(n1).getPortSpec(0) == "Test:Src.dummyFun(TestFrame)"_expect);
|
||||
SHOW_EXPR(watch(n1).getPortSpec(1))
|
||||
CHECK (watch(n1).getPortSpec(1) == "↯"_expect);
|
||||
|
||||
// such a symbolic spec is actually generated by a deduplicated metadata descriptor
|
||||
|
|
@ -103,15 +102,19 @@ SHOW_EXPR(watch(n1).getPortSpec(1))
|
|||
CHECK (hash_value(meta1) != hash_value(meta2));
|
||||
CHECK (hash_value(meta1) != hash_value(meta3));
|
||||
|
||||
SHOW_EXPR(meta1.genProcSpec());
|
||||
CHECK (meta1.genProcSpec() == "N1(arg)"_expect);
|
||||
SHOW_EXPR(meta2.genProcSpec());
|
||||
CHECK (meta2.genProcSpec() == "N2(arg)"_expect);
|
||||
SHOW_EXPR(meta3.genProcSpec());
|
||||
CHECK (meta3.genProcSpec() == "N1.uga()"_expect);
|
||||
|
||||
// re-generate the descriptor for the source node (n1)
|
||||
auto& metaN1 = ProcID::describe("Test:Src",DUMMY_FUN_ID);
|
||||
SHOW_EXPR(metaN1.genProcSpec());
|
||||
CHECK (metaN1.genProcSpec() == "Test:Src.dummyFun(TestFrame)"_expect);
|
||||
SHOW_EXPR(metaN1.genProcName())
|
||||
CHECK (metaN1.genProcName() == "Test:Src.dummyFun"_expect);
|
||||
SHOW_EXPR(metaN1.genNodeName())
|
||||
CHECK (metaN1.genNodeName() == "Test:Src"_expect);
|
||||
SHOW_EXPR(metaN1.genNodeSpec(con.leads))
|
||||
CHECK (metaN1.genNodeSpec(con.leads) == "Test:Src-◎"_expect);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
#include <string>
|
||||
#include <tuple>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -291,6 +292,7 @@ namespace test{
|
|||
verify_IterSource();
|
||||
verify_reduceVal();
|
||||
verify_effuse();
|
||||
verify_dedup();
|
||||
|
||||
verify_depthFirstExploration();
|
||||
demonstrate_LayeredEvaluation();
|
||||
|
|
@ -1234,6 +1236,20 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
/** @test verify to deduplicate the iterator's results into a std::set
|
||||
*/
|
||||
void
|
||||
verify_dedup()
|
||||
{
|
||||
CHECK (materialise (
|
||||
explore(CountDown{23})
|
||||
.transform([](uint j){ return j % 5; })
|
||||
.deduplicate()
|
||||
)
|
||||
== "0-1-2-3-4"_expect); // note: values were also sorted ascending by std::set
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** @test package the resulting Iterator as automatically managed,
|
||||
|
|
|
|||
|
|
@ -13732,9 +13732,7 @@
|
|||
<node CREATED="1518660033466" ID="ID_1879301424" MODIFIED="1518660044053" TEXT="jede Klausel wird vorbehandelt"/>
|
||||
<node CREATED="1518660206867" ID="ID_1357657997" MODIFIED="1518660237412">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
technische Lösug <i>diskutierbar</i>
|
||||
|
|
@ -14814,9 +14812,7 @@
|
|||
</node>
|
||||
<node CREATED="1509142651113" ID="ID_99734013" MODIFIED="1512926191818">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Spezialbehandlung
|
||||
|
|
@ -16536,9 +16532,7 @@
|
|||
</node>
|
||||
<node COLOR="#435e98" CREATED="1539302481080" ID="ID_126724611" MODIFIED="1576282358105" TEXT="static_assertion">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...damit es nicht versehentlich über einen anderen Layer gelegt wird,
|
||||
|
|
@ -18963,9 +18957,7 @@
|
|||
<font BOLD="true" NAME="SansSerif" SIZE="15"/>
|
||||
<node COLOR="#33565a" CREATED="1664723420339" HGAP="38" ID="ID_1605718107" MODIFIED="1664727861369" TEXT="Handlungsbedarf?" VSHIFT="39">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
BEDINGUNG: Constraint < Vollgröße
|
||||
|
|
@ -46855,9 +46847,7 @@
|
|||
<node CREATED="1451177573108" ID="ID_1154342108" MODIFIED="1518487921086" TEXT="wenn dieser true zurückgibt, ist der Zustand persistent"/>
|
||||
<node CREATED="1451177584435" ID="ID_1792154974" MODIFIED="1518487921086">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dann wird eine <i>state mark</i> ausgesendet
|
||||
|
|
@ -47601,9 +47591,7 @@
|
|||
</node>
|
||||
<node CREATED="1455913785555" ID="ID_1777441123" MODIFIED="1575133325785" TEXT="transparenter Filter">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
schlechter....
|
||||
|
|
@ -47994,9 +47982,7 @@
|
|||
<node CREATED="1455928440366" ID="ID_33734026" MODIFIED="1457190669578" TEXT="just pop mutator"/>
|
||||
<node CREATED="1457190670069" ID="ID_242879400" MODIFIED="1575133327206" TEXT="abandon mutator">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<b>NOTE</b>: mutator need to be written in such a way
|
||||
|
|
@ -48272,9 +48258,7 @@
|
|||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1456424237672" ID="ID_811857290" MODIFIED="1575133328443" TEXT="zu Fuß programmieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
was man konventionellerweise auch macht.
|
||||
|
|
@ -48423,9 +48407,7 @@
|
|||
</node>
|
||||
<node CREATED="1456426322482" ID="ID_1330880148" MODIFIED="1456437520773" TEXT="irreduzibel">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
man kann versuchen, die beiden Elemente der Duplikation aufzulösen.
|
||||
|
|
@ -91373,8 +91355,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728785840998" ID="ID_663732870" MODIFIED="1728785852800" TEXT="Funktions-ID generieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1728785840998" ID="ID_663732870" MODIFIED="1730774373893" TEXT="Funktions-ID generieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1730426912428" ID="ID_1568293923" LINK="#ID_1347337581" MODIFIED="1730682010119" TEXT="tatsächlich kann hier einfach die symbolische Spec aus dem im Turnout durchgereicht werden"/>
|
||||
<node COLOR="#338800" CREATED="1730427234835" ID="ID_1719129337" MODIFIED="1730681997339" TEXT="diese Information muß durchgefädelt werden">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -91392,15 +91374,138 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728785867907" ID="ID_394739045" MODIFIED="1730682037506" TEXT="Spec generieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728785876033" ID="ID_424140873" MODIFIED="1728785881465" TEXT="Spec der Funktion">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1728785876033" ID="ID_424140873" MODIFIED="1730774363553" TEXT="Name der Funktion">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1728785882504" ID="ID_607531791" MODIFIED="1730682058719" TEXT="Spec aus dem Turnout">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1729986405645" ID="ID_1710935234" MODIFIED="1729986440374" TEXT="Spec der umschließenden ProcNode">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1729986405645" ID="ID_1710935234" MODIFIED="1730774358145" TEXT="Spec der umschließenden ProcNode">
|
||||
<arrowlink COLOR="#666a8d" DESTINATION="ID_1032840307" ENDARROW="Default" ENDINCLINATION="312;27;" ID="Arrow_ID_1338984517" STARTARROW="None" STARTINCLINATION="158;-13;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1730762304054" HGAP="25" ID="ID_1617701375" MODIFIED="1730774167902" VSHIFT="10">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<u>Wunsch</u>: abgekürzte Darstellung der Vorläufer
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1730762334184" ID="ID_1202353548" MODIFIED="1730762346559" TEXT="wenn Einzel-Node: dann deren Namen und Quell-Spec"/>
|
||||
<node CREATED="1730762347685" ID="ID_609608264" MODIFIED="1730762353185" TEXT="sonst direkt die Quell-Spec"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1730772678964" ID="ID_1510545208" MODIFIED="1730774144647" TEXT="brauche depth-first alle Quell-Nodes">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1730772719839" ID="ID_1652819533" MODIFIED="1730772733330" TEXT="das ist kein reines flatMap(), da rekursiv">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1730772701546" ID="ID_666196583" MODIFIED="1730772714108" TEXT="könnte man mit lib::explore() + expand machen"/>
|
||||
<node CREATED="1730773128936" ID="ID_1794250437" MODIFIED="1730773147814" TEXT="muß dann aber innere Knoten eigens ausfiltern">
|
||||
<node CREATED="1730773150469" ID="ID_1989703053" MODIFIED="1730773743409" TEXT="der IterExplorer kann das bisher nicht....">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...darüber hab ich damals viel nachgedacht: eine generische Implementierung der Blatt-Iteration ist nicht so einfach zu realisieren, da man einem Element nicht anhand generischer Eigenschaften ansehen kann, ob es ein Blatt ist oder noch weiter expandiert werden kann. Ein Ausweg wäre, das Element versuchsweise zu expandieren und es selber nur zurückzuliefern, wenn die Expansion leer ist. Davon habe ich damals aber Abstand genommen, da es (a) erfordert, den Aufwand für die Expansion stets und für jedes Element zu leisten und (b) dann irgendwie eine Interaktion mit dem internen Stack stattfinden muß, und das dann auch noch rekursiv oder repretitiv  (und das wurde mir dann alles zu kompliziert)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1730773167011" ID="ID_114695925" MODIFIED="1730773887545" TEXT="aber wir wissen: keine Leads ⟹ ist Quell-Node">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und deshalb können wir erst expandAll() machen, und dann die inneren Blattknoten einfach nachträglich wegfiltern, woduch automatisch weiter repetitiv konsumiert wird.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1730773892379" ID="ID_1873949719" MODIFIED="1730774151857" TEXT="möchte aber auch noch deduplizieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1730773903961" ID="ID_578892742" MODIFIED="1730773916259" TEXT="das könnte man aber definitiv in IterExplorer einbauen"/>
|
||||
<node CREATED="1730773917301" ID="ID_1998930932" MODIFIED="1730773929478" TEXT="das ist wie ein effuse() in eine std::map">
|
||||
<node CREATED="1730773931686" ID="ID_686657925" MODIFIED="1730773941216" TEXT="geht nicht direkt mit effuse()"/>
|
||||
<node CREATED="1730773942228" ID="ID_708017506" MODIFIED="1730773961826" TEXT="weil std::map kein push_back kennt, sondern nur insert bzw. emplace"/>
|
||||
</node>
|
||||
<node CREATED="1730773968577" ID="ID_1309038873" MODIFIED="1730773982723" TEXT="der resultierende Container wäre wieder iterable"/>
|
||||
<node CREATED="1730773983921" ID="ID_525211889" MODIFIED="1730774038666" TEXT="Problem: IterExplorer nimmt Container bisher nur per Referenz">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....aus Sicherheits-Gründen: der Container soll irgendwo „daneben“ in sicherer Storage liegen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1730774040094" ID="ID_361668791" MODIFIED="1730774051846" TEXT="Man könnte aber den Container in eine »state-core« packen">
|
||||
<node COLOR="#435e98" CREATED="1730774059450" ID="ID_1347191239" MODIFIED="1730774091567" TEXT="da müßte er per move(con) rein">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774068251" ID="ID_1062996816" MODIFIED="1730774094301" TEXT="neuer Iter-Adapter: ContainerCore">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774112045" ID="ID_1339216059" MODIFIED="1730774121428" TEXT="IterExplorer::deduplicate()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1730774572424" ID="ID_1656589011" MODIFIED="1730774586813" TEXT="Abhängigkeit auf std::set">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1730774588254" ID="ID_189433789" MODIFIED="1730774753080" TEXT="wieder den Trick mit Forward-Deklaration">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Der Trick ist: die Funktion nimmt ein Template-Argument, das aber als Default den forward-deklarierten STL-Container hat. Scheint mit meinem GCC zu klappen .... ich bin da aber sehr skeptisch, denn die Signatur mit den Template-Parametern könnte sich in Zukunft schon noch erweitern.....
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1730774727731" ID="ID_150671538" MODIFIED="1730774857648" TEXT="bin erst kürzlich mit Yoshimi und Clang mit etwas ähnlichem in Probleme geraten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
auch da wollte ich einen pervasiven #include <map> vermeiden. Dann kam aber ein Defekt-Report von einem Clang-User auf BSD (und zwar der neueste Clang). Dort war der neue C++17 polymorphic-Allocator anders deklariert, so daß es zu einer <i>ambiguity</i> gekommen ist.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774125353" ID="ID_457256918" MODIFIED="1730774132853" TEXT="Testfall dazu...">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774185740" ID="ID_173460273" MODIFIED="1730774327276" TEXT="Darstellung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1730774195978" ID="ID_506214252" MODIFIED="1730774325674" TEXT="erst mal stets das Node-Symbol selber">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774207472" ID="ID_1605389357" MODIFIED="1730774325673" TEXT="gefolgt von der neuen »SrcSpec«">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1730774277791" ID="ID_506373939" MODIFIED="1730774290283" TEXT="die soeben entwickelte deduplizierte Pipeline"/>
|
||||
<node CREATED="1730774291308" ID="ID_1583882759" MODIFIED="1730774306623" TEXT="per util::join() kommasepariert und in geschweifte Klammern"/>
|
||||
<node CREATED="1730774308601" ID="ID_388580554" MODIFIED="1730774321664" TEXT="oder ein direkter Quell-Marker wenn die Leads leer sind"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1730774235517" ID="ID_675649088" MODIFIED="1730774325673" TEXT="Spezialfall Single-Link">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1730774248763" ID="ID_518275033" MODIFIED="1730774259392" TEXT="dann erst diesen einzigen Vorgänger auch anzeigen"/>
|
||||
<node CREATED="1730774260378" ID="ID_1141098746" MODIFIED="1730774271710" TEXT="und erst auf diesen getSrcSpec() anwenden"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1730774330224" ID="ID_1021456970" MODIFIED="1730774355189" TEXT="mit komplexem Node-Tree testen">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -91665,6 +91770,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#fbfeda" DESTINATION="ID_241387326" ENDARROW="Default" ENDINCLINATION="-379;-27;" ID="Arrow_ID_1982618460" STARTARROW="None" STARTINCLINATION="-161;5;"/>
|
||||
<linktarget COLOR="#c7dcf5" DESTINATION="ID_423678075" ENDARROW="Default" ENDINCLINATION="461;-17;" ID="Arrow_ID_268382631" SOURCE="ID_519915836" STARTARROW="None" STARTINCLINATION="409;26;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
|
|
@ -91749,7 +91855,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
<node CREATED="1730598198960" ID="ID_1268799308" MODIFIED="1730598217841" TEXT="⟹ halbwegs sinnvolle Aufrufstruktur">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730598219853" ID="ID_241387326" MODIFIED="1730598252076" TEXT="ProcID ≙ separater Metadaten-Record">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730598219853" ID="ID_241387326" MODIFIED="1730733979784" TEXT="ProcID ≙ separater Metadaten-Record">
|
||||
<linktarget COLOR="#fbfeda" DESTINATION="ID_241387326" ENDARROW="Default" ENDINCLINATION="-379;-27;" ID="Arrow_ID_1982618460" SOURCE="ID_423678075" STARTARROW="None" STARTINCLINATION="-161;5;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1730598396950" ID="ID_1069190015" MODIFIED="1730598409561" TEXT="soll nur die semantisch relevanten Infos enthalten"/>
|
||||
<node CREATED="1730598414787" ID="ID_423504615" MODIFIED="1730598421854" TEXT="und zwar aufgebrochen in einzelne Felder">
|
||||
|
|
@ -91847,8 +91954,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue