diff --git a/src/lib/itertools.hpp b/src/lib/itertools.hpp index ea30f1077..d20e53a69 100644 --- a/src/lib/itertools.hpp +++ b/src/lib/itertools.hpp @@ -78,6 +78,7 @@ #include "lib/iter-adapter.hpp" +#include "lib/meta/value-type-binding.hpp" #include "lib/meta/function.hpp" #include "lib/meta/trait.hpp" #include "lib/wrapper.hpp" @@ -94,7 +95,7 @@ namespace lib { using std::function; using util::unConst; - using lib::meta::RefTraits; + using lib::meta::TypeBinding; @@ -753,9 +754,9 @@ namespace lib { return bool(source_); } - typedef typename RefTraits::pointer pointer; - typedef typename RefTraits::reference reference; - typedef typename RefTraits::value_type value_type; + typedef typename TypeBinding::pointer pointer; + typedef typename TypeBinding::reference reference; + typedef typename TypeBinding::value_type value_type; }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9f64c40c5..e7c350cb3 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -54030,7 +54030,3310 @@ + + + + + + +

+ Diff-basiertes Δ-Binding +

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

+ schmerzloses C++ API +

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

+ Performance: guter Schnitt (etw. besser als boost spirit) +

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

+ hat ein DOM-API und ein SAX-artiges API +

+ +
+ +
+ + + + + + +

+ das heißt: nicht einmal abhängig von der STL +

+ +
+
+ + + + + + + +

+ wie gson +

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

+ vjson war Google Code; +

+

+ nach dem Umzug auf Github heißt es gason +

+ +
+ + + + + + +

+ lt. eigenen Benchmakrs deutlich schneller als rapidjson, welches eigentlich immer als der "schnelle" JSON-Parser gilt. +

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

+ d.h. das Parsen schreibt den Eingabepuffer um, und Strings bleiben einfach liegen +

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

+ kein Repo auffindbar +

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

+ ich will nicht noch ein Objekt-System +

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

+ man hätte genausogut std::future und std::async verwenden können. +

+

+ Vorteil von unseren Framework: +

+
    +
  • + wir haben es schon, und wir werden es verwenden, wegen den Thradpools +
  • +
  • + man baut ein Objekt für einen Thread. Das ist explizit und sauber +
  • +
  • + wir haben eine eingebaute Barriere und können unseren Objekt-Monitor nutzen +
  • +
+ +
+ +
+ + + + + + + + + + + + +

+ habe einen usleep(1000) getimed +

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

+ daher messen wir die Loop als Ganzes. +

+

+ Es gibt daher keine Möglichkeit, den Loop-Overhead selber zu messen. +

+

+ Er sollte sich aber bei einer Wiederholung im Millionenbereich gut amortisieren +

+

+ +

+

+ Außerdem ist ja auch noch der Aufruf des Funktors mit im Spiel, wenngleich der auch typischerweise geinlined wird +

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

+ volatile Variable außen, im Aufrufkontext +

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

+ ...was sehr schön beweist, +

+

+ daß x86_64 tatsächlich cache-kohärent ist +

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

+ das ist der wichtigste Part: ich grenze mich hier explizit von der STL ab;  ein »Lumiera Forward Iterator« ist nicht eine besondere Art von Pointer — wir wissen sonst wirklich nichts, und wir verzichten auf ein absolut optimale Performance. Und wir bieten keinerlei  weitere Features, wie Rückwärts-Iteration, random-access, Löschen und Einfügen. Einen einmal verbrauchten Iterator kann man nur noch wegwerfen. +

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

+ offensichtlich habe ich das gleiche Problem hier mehrfach gelöst und das dann wieder vergessen +

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

+ Das Sandwich-Design tritt durchaus häufig auf, wenn man einen Builder hat, oder eine Pipeline mit einem terminalen Adapter. Aber beim TreeExplorer habe ich das viel klarer gelöst, indem der Kern im Sandwich selbst wieder ein »Lumiera Forward Iterator« ist, nach dem »State Core«-Modell. Im Grunde laufen die »Itertools« auf den gleichen Ansatz hinaus, nur habe ich das damals noch nicht erkannt und stattdessen ein privates Protokoll entwickelt, wodurch die gesamte Implementierung relativ schwer zu verstehen ist, und dennoch weder kompakter, noch performanter wird. +

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

+ seit längerer Zeit ein Thema, +

+

+ für das ich verschiedene Lösungen ausprobiere +

+
    +
  • + IterExplorer : erster Anlauf, etwas schief +
  • +
  • + TreeExplorer : Pipeline-Builder, vielversprechend +
  • +
+ +
+ + + + + + + +

+ Thema: Monaden +

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

+ sind Monaden +

+

+ wirklich hilfreich? +

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

+ »AboutMonads« : das könnte mal eine Seite im Theorieteil werden ("more about...") +

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

+ ...bindet die Betrachtung auf einen technischen Level, +

+

+ und führt dazu, daß die Abstraktion undicht wird +

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

+ genau der Umstand, +

+

+ daß funktionale Sprachen von einer Zustands-Phobie getrieben sind, +

+

+ macht Monaden nützlich, um inhärenten Zustand wegzuabstrahieren. +

+

+ Das kann genutzt werden, um den Zustand einer Wechselwirkung +

+

+ nach einer Seite der Glieder auszukoppeln. +

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

+ gehört zu dem Themenkomplex "itertools" +

+

+ Python hat das auch, Java neuerdings auch +

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

+ ...will sagen, es ist klar, wie man sowas machen kann. +

+

+ Seinerzeit war mir das auch klar, aber ich wollte es nicht gleich ausprogrammieren. +

+

+ Inzwischen kam dann das Thema UI-Coordinaten, und dort habe ich es ausprogrammiert, +

+

+ und zwar direkt in die Low-Level-Schicht integriert, was nicht schlecht ist, +

+

+ da eine Abstraktion hier sehr technisch werden würde +

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

+ ...von der entsprechenden Methode im Transformer +

+ +
+ +
+ + + + + + +

+ ...hatte die Notwendigkeit hierfür seinerzeit während der Tests entdeckt, +

+

+ und im Unit-Test nur für die Kombination Transformer + Explorer abgedeckt.... +

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

+ sofern längerfristig Itertools durch TreeExplorer abgelöst werden könnte +

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

+ ...und das hängt an einem hauchdünnen Faden, +

+

+ und ist subtil bis zum geht nicht mehr.... +

+

+ +

+

+ Wenn man das Lambda einfach per [=] schreibt, und das Feld this->predicate_ verwendet, +

+

+ dann wird this gecaptured (und das ist effektiv per Referenz). Wenn ich dann den +

+

+ konstruierten Funktor an this->predicate_ zuweise, haben wir eine Endlos-Rekursion. +

+

+ +

+

+ Lösung: man muß im lokalen Frame eine Referenz auf this->predicate definieren und binden. +

+

+ Diese wird dann per Value gecaptured, was die gewünschte Kopie bewirkt. +

+ +
+
+ + + + + + +

+ ...muß den Chain-Funktor aus dem Template-Argument erzeugen, +

+

+ und ihn dann in die per-Value-Closure des erzeugten neuen Lambda binden (=Kopie). +

+

+ +

+

+ Erst ab C++17 kann man Lambda-Captures pre move machen +

+

+ (und auch dafür ist die Syntax grausam) +

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

+ ...es soll bloß einfach funktionieren!!!!!!!!!!! +

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

+ keine gute Idee. +

+

+ Dann verwenden wir im einen Funktor-Framework eine Filter-Komponente +

+

+ aus dem anderen Framework, obwohl es direkt hier auch eine Filter-Komponente gäbe. +

+

+ +

+

+ Außerdem habe ich immer noch die Hoffnung, irgendwann mal +

+

+ die Itertools komplett durch den TreeExplorer ablösen zu können +

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

+ Name: mutableFilter() +

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

+ ...sieht gut aus. +

+

+ +

+

+ Folgendes habe ich gesehen +

+
    +
  • + zu Beginn zeigt das eingebettete Funktor-Objekt auf eine Position auf dem Stack +
  • +
  • + beim Aufrufen der andFilter()-Funktion werden diverse Funktoren kopiert,
    wobei nacheinander die (zu erwartenden) Argumente als Quelle auftauchen
    +
  • +
  • + danach hat sich der Funktor geändert: er zeigt nun auf eine Position auf dem Heap
    +
  • +
  • + der bisherige Funktor wurde mit der Closure des zusammengesetzten Funktors kollabiert (hat gleiche Addresse)
    +
  • +
  • + der Chain-Funktor hat eine Closure bekommen, die ebenfalls Heap-alloziert ist.
    das deutet darauf hin, daß das capturen per copy funktioniert hat
    +
  • +
  • + Beim Aufruf steppen wir nacheinander erst in den kombinierten Funktor,
    und von dort wie erwartet in die beiden Lambdas. +
  • +
  • +
    +
  • +
+ +
+ +
+
+
+
+ + + + + + + + + + + + + +

+ ...für das dort hineingereichte Funktor-Objekt wird der Argument-Accessor ausgewählt (Metaprogrammierung). +

+

+ Er ist dann im Typ des Wrappers == _Traits::Functor codiert. +

+

+ +

+

+ Wir können zwar den im Wrapper enthaltenen Funktor neu zuweisen (in gewissen Grenzen), +

+

+ aber er wird stets den zu Beginn gewählten Argument-Accessor nehmen. +

+

+ Typischerweise wird dieser ja sogar beim Aufruf des getemplateteten Funtions-Operators geInlined +

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

+ Problem: std::function in FilterPredicate +

+ +
+ + + + + + +

+ entweder Val -> bool oder Iter -> bool +

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

+ ...ist einfach und offensichtlich; +

+

+ ohnehin laufen schon ziemlich alle konkreten Layer-Builder nach einem Schema-F +

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

+ ...für das dort hineingereichte Funktor-Objekt wird der Argument-Accessor ausgewählt (Metaprogrammierung). +

+

+ Er ist dann im Typ des Wrappers == _Traits::Functor codiert. +

+

+ +

+

+ Wir können zwar den im Wrapper enthaltenen Funktor neu zuweisen (in gewissen Grenzen), +

+

+ aber er wird stets den zu Beginn gewählten Argument-Accessor nehmen. +

+

+ Typischerweise wird dieser ja sogar beim Aufruf des getemplateteten Funtions-Operators geInlined +

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

+ der Aufruf vom äußeren in den inneren Wrapper ist 1:1 und sollte vom Compiler wegoptimiert werden +

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

+ ...ich verbrenne Stunden beim Debuggen von neuem Code +

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

+ Konsequenz: brauche Template Funktions-Operator +

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

+ der Funktor für den Expander wird explizit als Sonderfall  aufgefaßt +

+ +
+ + + + + +

+ das eigentliche Problem mit der bestehenden Lösung ist, +

+

+ daß ich ausgerechnet mit diesem Sonderfall angefangen habe. +

+

+ Daher ist jetzt das gesamte Design "anders herum" +

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

+ ...wo der volle Typ des Funktors FUN bekannt ist +

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

+ ...und in dem besonders wichtigen Fall, +

+

+ in dem der Funktor direkt den SRC-Iterator akzeptiert, +

+

+ wird er ohne Weiteres durchgereicht. +

+

+ In dem Fall dann keine doppelte Verpackung mehr! +

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

+ da sich die Iteratoren wirklich unterscheiden können dürfen +

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

+ ...wobei der konkrete Overhead noch nicht wirklich klar ist; +

+

+ hängt davon ab, wie geschickt der Optimizer ist, und was man konkret als Funktoren angibt. +

+

+ +

+

+ Vermutlich haben wir hier +

+
    +
  • + zwingend eine Indirektion durch einen Funktions-Pointer (weil eine Type Erasure stattfindet) +
  • +
  • + möglicherweise eine zusätzliche Heap-Allocation (es sei denn, der Optimizer ist wirklich clever) +
  • +
+ +
+ +
+ + + + + + +

+ und das ist das Argument, das sticht +

+ +
+ +
+ + + + + + +

+ ...will sagen, wenn schon eine neue Lösung, dann von A bis Z +

+ +
+ +
+
+ + + +
+
+ + + + + + + + + +
+ + + + + + + + +
    +
  • + Suche wird geleitet durch die ViewSpecDSL +
  • +
  • + hinter dem (opaquen) TreeExplorer steckt die konkrete UI-Topologie +
  • +
+ +
+
+ + + + + + +

+ EventLog ist ein Test-Hilfsmittel, +

+

+ um Unit-Tests über UI-Bus-Interaktionen schreiben zu können. +

+

+ Es gibt hierzu Test-Varianten, die jeden Aufruf in ein internes Log notieren. +

+

+ Im Test verwendet man dann eine Pattern-Such-DSL, +

+

+ hinter der sich eine verkettete Suche mit Backtracking verbirgt +

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

+ ...so daß es nur noch wenige Zugangs-Punkte zum unterliegenden Iterator gibt +

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

+ TreeExplorer macht das Wrappen für uns automatisch, +

+

+ und außerdem haben wir nun ein direktes API für die Laufrichtung +

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

+ ...denn durch das Backtracking +

+

+ würde man nun ziemlich undurchsichtige Misch-Zustände bekommen. +

+

+ Und: jeder direkt gesetzte Filter könnte die Invariante im Expander verletzen +

+

+ (weil er einen Kind-Iterator leer machen könnte, ohne daß dieser gePOPpt wird) +

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

+ ...um "Hängenbleiben" auf dem gleichen Element auszuschließen. +

+

+ Vorsicht: um sauber genau einen Schritt machen zu können, müssen wir explizit vorübergehend den Filter abschalten +

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

+ weil wir uns bisher bei allen vorausgegangenen Bedingungen +

+

+ auf den ersten Match "festgebissen" haben, und nur über den Iterator mit der +

+

+ zuletzt gesetzen Bedingung weiter iteriert haben. +

+

+ +

+

+ +

+

+ Künftig gibt es nach jedem Fail ein Backtracking. +

+ +
+ + + + + + + +

+ ...d.h es findet zwar ein Backtracking statt, aber wenn alle konjunktiven Klauseln gesetzt sind, +

+

+ sollte sich erneut ein FAIL ergeben +

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

+ est-event-log-test.cpp:228:  verify_callLogging: (log.ensureNot("fun").after("fun").after("fun2")) +

+ +
+ + + + + + + + +

+ Verdacht: Negation +

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

+ fun after fun matcht auf den immer gleichen Record +

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

+ und zwar mit abgeschaltetem Filter +

+ +
+ + + + + +

+ für diesen einen Schritt +

+

+ muß die Filter-Funktion vorübergehend deaktiviert werden, +

+

+ damit wir exakt das nächste / vorhergehende Element bekommen +

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

+ die Search-Engine bläht die Debug-Infos gewaltig auf +

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

+ geht gar nicht anders, denn diese sind templates +

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

+ Invariante: pullMatch() +

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

+ ...d.h. die einzelnen Steps in der Pipeline direkt wrappen. +

+

+ Dann ist außen herum keine Anpassung der Argumente mehr notwendig, +

+

+ und man kann die Expand-Funktion direkt als std::function-Objekt durchgeben +

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

+ ...um den Expand-Funktor zu zwingen, eine Kopie zu machen; +

+

+ es sollte die Filter-Konfiguration auf der Kopie manipuliert werden, +

+

+ während das Original auf dem Auswertungs-Stack liegen bleibt, +

+

+ für späteres Backtracking... +

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

+ ...damit man stets weitere Builder-Funktionen auf der Pipeline aufrufen kann +

+ +
+
+ + + + + + +

+ weil wir diesen manipulieren +

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

+ ...nach der »reinen Lehre« +

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

+ ...insofern wir nämlich zwingend auf den jeweilign Kind-Iterator zugreifen müssen. +

+

+ Nicht nur auf den aktuellen Wert (=dereferenzierter Iterator, d.h. die Funktion yield()) +

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

+ wir müssen hier eine Festlegung treffen +

+ +
+ + + + + +

+ ...weil die Ergebnisse der einzelnen Schritt-Funktoren, +

+

+ jeweils in den Auswertungs-Stack gepackt werden sollen. +

+

+ +

+

+ Daher müssen sie untereinander kompatibel sein. +

+ +
+ +
+ + + + + + +

+ im typischen Fall kopiert man den Basis-Iterator, +

+

+ und manipuliert dann einige Einstellungen auf diesem. +

+

+ +

+

+ Wir könnten diese Kopie-Semantik sogar erzwingen, +

+

+ indem wir als Argument-Typ des Schritt-Funktors eine const& vorgeben +

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

+ ...den ich mache, um den Adapter in jedem Einzelfall zu bekommen +

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

+ ....und fällt dann beim Instantiieren des Template auf die Schnautze +

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

+ sofern eine Initialisierung ausidem Source-Iterator möglich ist +

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

+ und sonst ist das nicht wirklich "kniffelig" +

+ +
+ + + + + +

+ ...bloß sind die zig-fach geschachtelten Template-Typen, +

+

+ die dann die Intantiierungs-Call-Hierarchie bevölkern, +

+

+ nahezu unlesbar.... +

+

+ +

+

+ +

+

+ AAber ... wenn es erst mal duch den Compiler ist, +

+

+ dann sollte der Optimizer diese gesamten x-fachen Wrapper nahezu restlos entfernen +

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

+ Konsequenz: jede Argument-Funktion wird nochmal gewrappt +

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

+ wir sind irgendwo im Baum, nicht auf dem Basis-Layer. +

+

+ Und der Basis-Layer steht irgendwo, nicht an der aktuellen Position. +

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

+ ...denn +

+
    +
  • + es ist praktisch, zunächst "leer" zu konstruieren +
  • +
  • + es ist verständlicher, wenn alle Bedingungen symmetrisch angegeben werden +
  • +
  • + es ist natürlich, daß ein "leerer" Filter alles durchläßt +
  • +
+ +
+
+ + + + + + +

+ Filter leer == alles durchlassen +

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

+ ...d.h. direkt das Prädikat, und nicht eine Funktion, die den Filter konfiguriert +

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

+ ...habe ich noch gar nicht gemerkt, daß das geht, +

+

+ und manchen komischen Workaround implementiert. +

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

+ weil ich dann auf dem IterChainSearch unmittelbar die builder-Funktionen definieren kann +

+ +
+
+
+ + + + + + +

+ denn: TreeExplorer == IterableDecorator< Pipeline > +

+ +
+ + + + + + + +

+ der oberste Layer, also hier IterChainSearch +

+

+ ist selbst ein StateCore. Also brauche ich noch einen Dekocator +

+

+ Wenn der fehlt, wird der nächste darunterliegende Decorator gepullt, +

+

+ und der wickellt direkt den Expander ein +

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

+ konfiguriert danach direkt den Filter +

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

+ ...weil der Basis-Iterator (also der Template-Parameter SRC) +

+

+ explizit und absichtlich einen anderen Typ haben könnte, als der expandierte Kind-Iterator. +

+

+ Das ist ein wesentliches Feature dieses Expander-Designs, würde aber leider eine +

+

+ komplett generische Accessor-Funktion unmöglich machen (das Template würde in +

+

+ einem Solchen Fall insgesamt vom Compiler zurückgewiesen) +

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

+ sausage-bacon-tomato-and-sausage-spam-spam-bacon-spam-tomato-and-spam-spam-bacon-tomato-and-spam-bacon-tomato-and-spam-tomato-and-spam +

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

+ sausage-bacon-tomato-and-spam-spam-bacon-spam-tomato-and-spam-bacon-tomato-and-bacon-tomato-and-tomato-and +

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

+ ...wie bekommt man dann den konvertierten Wert 'raus. +

+

+ Visitor ist entweder void, oder bool +

+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
  • + kein allgemeines Such-Framework bauen! +
  • +
  • + den Begriff des "Containers" knapp halten: was keine const_reference bietet, ist kein Container +
  • +
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Man würde also neben das Standard-Format ein toleriertes zweites Format stellen, welches dann ein Bürger zweiter Klasse wäre, aber auf allen wichtien APIs als 2.Alternative mit auftaucht. Zudem würde man gewisse Abkürzungs-Pfade schaffen, auf denen die alternative Spec dann verlustfrei durchgereicht werden kann. +

+
    +
  • + es ist überhaupt nicht klar, welches Format dann der Standardfall sein sollte +
  • +
  • + das läuft vor allem auf eine Performance-Betrachtung hinaus, und einen trade-off, wo man ggfs Fehler durch andere Programmierer akzeptiert +
  • +
+ +
+
+
+
+ + + + + + + + + +

+ wenn man zum µ-Grid eine eindeutige Rundungs-Regel hinzufügt, +

+

+ kann es praktisch auch Sound-Samples korrekt addressieren:

1/96000 ≙ 10,41666666666666666667 µTicks +

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

+ im Besonderen bei den pragmatischen Lösungen +

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

+ und ganz im Besonderen: wir stützen uns für die Zeitbehandlung nicht auf libGavl ab +

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

+ FSecs durch einen neuen Wrapper RSec ersetzen +

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

+ nicht implizit konstruierbar aus int64_t +

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

+ ...seinerzeit fand ich diese Art »Offenheit« noch gut; auch weil ich mir erhoffte, damit mehr Contributors zu bekommen. Die Erfahrungen sprechen dagegen; klar, die Leute mögen erst einmal gerne „move fast and break things“ — aber wenn dann Aufräumen oder anstrengende Konzeptions-Arbeit notwendig würde, bleibt alles liegen und man verschwindet aus dem Projekt. +

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

+ Begründung: sie entstehen als Delta aus validen Zeitpunkten +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -61034,3200 +64337,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- schmerzloses C++ API -

- -
-
- - - - - - - - - -

- Performance: guter Schnitt (etw. besser als boost spirit) -

- -
-
- - - - - - - - - - - -

- hat ein DOM-API und ein SAX-artiges API -

- -
- -
- - - - - - -

- das heißt: nicht einmal abhängig von der STL -

- -
-
- - - - - - - -

- wie gson -

- -
-
- - - - - - - - - -

- vjson war Google Code; -

-

- nach dem Umzug auf Github heißt es gason -

- -
- - - - - - -

- lt. eigenen Benchmakrs deutlich schneller als rapidjson, welches eigentlich immer als der "schnelle" JSON-Parser gilt. -

- -
-
- - - - - - - - -

- d.h. das Parsen schreibt den Eingabepuffer um, und Strings bleiben einfach liegen -

- -
-
- - - - - - - - - - - - - - - - - -

- kein Repo auffindbar -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - -

- ich will nicht noch ein Objekt-System -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- man hätte genausogut std::future und std::async verwenden können. -

-

- Vorteil von unseren Framework: -

-
    -
  • - wir haben es schon, und wir werden es verwenden, wegen den Thradpools -
  • -
  • - man baut ein Objekt für einen Thread. Das ist explizit und sauber -
  • -
  • - wir haben eine eingebaute Barriere und können unseren Objekt-Monitor nutzen -
  • -
- -
- -
- - - - - - - - - - - - -

- habe einen usleep(1000) getimed -

- -
- -
-
- - - - - - - - - - - - - -

- daher messen wir die Loop als Ganzes. -

-

- Es gibt daher keine Möglichkeit, den Loop-Overhead selber zu messen. -

-

- Er sollte sich aber bei einer Wiederholung im Millionenbereich gut amortisieren -

-

- -

-

- Außerdem ist ja auch noch der Aufruf des Funktors mit im Spiel, wenngleich der auch typischerweise geinlined wird -

- -
- - - - - - - -
- - - - - - - - -

- volatile Variable außen, im Aufrufkontext -

- -
-
- - - - - - - - - - -

- ...was sehr schön beweist, -

-

- daß x86_64 tatsächlich cache-kohärent ist -

- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- seit längerer Zeit ein Thema, -

-

- für das ich verschiedene Lösungen ausprobiere -

-
    -
  • - IterExplorer : erster Anlauf, etwas schief -
  • -
  • - TreeExplorer : Pipeline-Builder, vielversprechend -
  • -
- -
- - - - - - - -

- Thema: Monaden -

- -
- - - - - - - - - -

- sind Monaden -

-

- wirklich hilfreich? -

- -
- - - - - - - - - - - - - - - - - - - -

- »AboutMonads« : das könnte mal eine Seite im Theorieteil werden ("more about...") -

- -
- -
-
- - - - - - - - - - - - - - - -

- ...bindet die Betrachtung auf einen technischen Level, -

-

- und führt dazu, daß die Abstraktion undicht wird -

- -
-
- - - - - - - - - - - - -

- genau der Umstand, -

-

- daß funktionale Sprachen von einer Zustands-Phobie getrieben sind, -

-

- macht Monaden nützlich, um inhärenten Zustand wegzuabstrahieren. -

-

- Das kann genutzt werden, um den Zustand einer Wechselwirkung -

-

- nach einer Seite der Glieder auszukoppeln. -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- gehört zu dem Themenkomplex "itertools" -

-

- Python hat das auch, Java neuerdings auch -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...will sagen, es ist klar, wie man sowas machen kann. -

-

- Seinerzeit war mir das auch klar, aber ich wollte es nicht gleich ausprogrammieren. -

-

- Inzwischen kam dann das Thema UI-Coordinaten, und dort habe ich es ausprogrammiert, -

-

- und zwar direkt in die Low-Level-Schicht integriert, was nicht schlecht ist, -

-

- da eine Abstraktion hier sehr technisch werden würde -

- -
-
-
-
- - - - - - - - - - - - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...von der entsprechenden Methode im Transformer -

- -
- -
- - - - - - -

- ...hatte die Notwendigkeit hierfür seinerzeit während der Tests entdeckt, -

-

- und im Unit-Test nur für die Kombination Transformer + Explorer abgedeckt.... -

- -
- -
- - - -
- - - - - - - - - - -

- sofern längerfristig Itertools durch TreeExplorer abgelöst werden könnte -

- -
-
- - - - - - - - - - - - - - -

- ...und das hängt an einem hauchdünnen Faden, -

-

- und ist subtil bis zum geht nicht mehr.... -

-

- -

-

- Wenn man das Lambda einfach per [=] schreibt, und das Feld this->predicate_ verwendet, -

-

- dann wird this gecaptured (und das ist effektiv per Referenz). Wenn ich dann den -

-

- konstruierten Funktor an this->predicate_ zuweise, haben wir eine Endlos-Rekursion. -

-

- -

-

- Lösung: man muß im lokalen Frame eine Referenz auf this->predicate definieren und binden. -

-

- Diese wird dann per Value gecaptured, was die gewünschte Kopie bewirkt. -

- -
-
- - - - - - -

- ...muß den Chain-Funktor aus dem Template-Argument erzeugen, -

-

- und ihn dann in die per-Value-Closure des erzeugten neuen Lambda binden (=Kopie). -

-

- -

-

- Erst ab C++17 kann man Lambda-Captures pre move machen -

-

- (und auch dafür ist die Syntax grausam) -

- -
-
-
- - - - - - - -

- ...es soll bloß einfach funktionieren!!!!!!!!!!! -

- -
- -
- - - - - - - - - -

- keine gute Idee. -

-

- Dann verwenden wir im einen Funktor-Framework eine Filter-Komponente -

-

- aus dem anderen Framework, obwohl es direkt hier auch eine Filter-Komponente gäbe. -

-

- -

-

- Außerdem habe ich immer noch die Hoffnung, irgendwann mal -

-

- die Itertools komplett durch den TreeExplorer ablösen zu können -

- -
- -
-
- - - - - - - - - - - - -

- Name: mutableFilter() -

- -
- -
-
- - - - - - - - - - - - - - - - -

- ...sieht gut aus. -

-

- -

-

- Folgendes habe ich gesehen -

-
    -
  • - zu Beginn zeigt das eingebettete Funktor-Objekt auf eine Position auf dem Stack -
  • -
  • - beim Aufrufen der andFilter()-Funktion werden diverse Funktoren kopiert,
    wobei nacheinander die (zu erwartenden) Argumente als Quelle auftauchen
    -
  • -
  • - danach hat sich der Funktor geändert: er zeigt nun auf eine Position auf dem Heap
    -
  • -
  • - der bisherige Funktor wurde mit der Closure des zusammengesetzten Funktors kollabiert (hat gleiche Addresse)
    -
  • -
  • - der Chain-Funktor hat eine Closure bekommen, die ebenfalls Heap-alloziert ist.
    das deutet darauf hin, daß das capturen per copy funktioniert hat
    -
  • -
  • - Beim Aufruf steppen wir nacheinander erst in den kombinierten Funktor,
    und von dort wie erwartet in die beiden Lambdas. -
  • -
  • -
    -
  • -
- -
- -
-
-
-
- - - - - - - - - - - - - -

- ...für das dort hineingereichte Funktor-Objekt wird der Argument-Accessor ausgewählt (Metaprogrammierung). -

-

- Er ist dann im Typ des Wrappers == _Traits::Functor codiert. -

-

- -

-

- Wir können zwar den im Wrapper enthaltenen Funktor neu zuweisen (in gewissen Grenzen), -

-

- aber er wird stets den zu Beginn gewählten Argument-Accessor nehmen. -

-

- Typischerweise wird dieser ja sogar beim Aufruf des getemplateteten Funtions-Operators geInlined -

- -
-
- - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Problem: std::function in FilterPredicate -

- -
- - - - - - -

- entweder Val -> bool oder Iter -> bool -

- -
- -
-
- - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - -

- ...ist einfach und offensichtlich; -

-

- ohnehin laufen schon ziemlich alle konkreten Layer-Builder nach einem Schema-F -

- -
- -
- - - - - - - - - - - - - - - -
-
- - - - - - - - - - - -

- ...für das dort hineingereichte Funktor-Objekt wird der Argument-Accessor ausgewählt (Metaprogrammierung). -

-

- Er ist dann im Typ des Wrappers == _Traits::Functor codiert. -

-

- -

-

- Wir können zwar den im Wrapper enthaltenen Funktor neu zuweisen (in gewissen Grenzen), -

-

- aber er wird stets den zu Beginn gewählten Argument-Accessor nehmen. -

-

- Typischerweise wird dieser ja sogar beim Aufruf des getemplateteten Funtions-Operators geInlined -

- -
- -
- - - - - - - - - - -

- der Aufruf vom äußeren in den inneren Wrapper ist 1:1 und sollte vom Compiler wegoptimiert werden -

- -
-
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - -
- - - - - - - - - -

- ...ich verbrenne Stunden beim Debuggen von neuem Code -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Konsequenz: brauche Template Funktions-Operator -

- -
-
-
- - - -
-
-
- - - - - - - - - - - - - -

- der Funktor für den Expander wird explizit als Sonderfall  aufgefaßt -

- -
- - - - - -

- das eigentliche Problem mit der bestehenden Lösung ist, -

-

- daß ich ausgerechnet mit diesem Sonderfall angefangen habe. -

-

- Daher ist jetzt das gesamte Design "anders herum" -

- -
-
- - -
- - - - - - - - - - - - - - - - - - - - -

- ...wo der volle Typ des Funktors FUN bekannt ist -

- -
-
- - - - - - - - -

- ...und in dem besonders wichtigen Fall, -

-

- in dem der Funktor direkt den SRC-Iterator akzeptiert, -

-

- wird er ohne Weiteres durchgereicht. -

-

- In dem Fall dann keine doppelte Verpackung mehr! -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- da sich die Iteratoren wirklich unterscheiden können dürfen -

- -
-
-
- - - - - - - - - - - - - - - - - - - -

- ...wobei der konkrete Overhead noch nicht wirklich klar ist; -

-

- hängt davon ab, wie geschickt der Optimizer ist, und was man konkret als Funktoren angibt. -

-

- -

-

- Vermutlich haben wir hier -

-
    -
  • - zwingend eine Indirektion durch einen Funktions-Pointer (weil eine Type Erasure stattfindet) -
  • -
  • - möglicherweise eine zusätzliche Heap-Allocation (es sei denn, der Optimizer ist wirklich clever) -
  • -
- -
- -
- - - - - - -

- und das ist das Argument, das sticht -

- -
- -
- - - - - - -

- ...will sagen, wenn schon eine neue Lösung, dann von A bis Z -

- -
- -
-
- - - -
-
- - - - - - - - - -
- - - - - - - - -
    -
  • - Suche wird geleitet durch die ViewSpecDSL -
  • -
  • - hinter dem (opaquen) TreeExplorer steckt die konkrete UI-Topologie -
  • -
- -
-
- - - - - - -

- EventLog ist ein Test-Hilfsmittel, -

-

- um Unit-Tests über UI-Bus-Interaktionen schreiben zu können. -

-

- Es gibt hierzu Test-Varianten, die jeden Aufruf in ein internes Log notieren. -

-

- Im Test verwendet man dann eine Pattern-Such-DSL, -

-

- hinter der sich eine verkettete Suche mit Backtracking verbirgt -

- -
- - - - - - - - - - - - - - - - - - - - - - - -

- ...so daß es nur noch wenige Zugangs-Punkte zum unterliegenden Iterator gibt -

- -
- -
- - - - - - - - - -

- TreeExplorer macht das Wrappen für uns automatisch, -

-

- und außerdem haben wir nun ein direktes API für die Laufrichtung -

- -
- -
-
- - - - - - - - - - - - - - - - -

- ...denn durch das Backtracking -

-

- würde man nun ziemlich undurchsichtige Misch-Zustände bekommen. -

-

- Und: jeder direkt gesetzte Filter könnte die Invariante im Expander verletzen -

-

- (weil er einen Kind-Iterator leer machen könnte, ohne daß dieser gePOPpt wird) -

- -
-
-
- - - - - - - - - - - - -

- ...um "Hängenbleiben" auf dem gleichen Element auszuschließen. -

-

- Vorsicht: um sauber genau einen Schritt machen zu können, müssen wir explizit vorübergehend den Filter abschalten -

- -
- -
-
- - - - - - - - - -

- weil wir uns bisher bei allen vorausgegangenen Bedingungen -

-

- auf den ersten Match "festgebissen" haben, und nur über den Iterator mit der -

-

- zuletzt gesetzen Bedingung weiter iteriert haben. -

-

- -

-

- -

-

- Künftig gibt es nach jedem Fail ein Backtracking. -

- -
- - - - - - - -

- ...d.h es findet zwar ein Backtracking statt, aber wenn alle konjunktiven Klauseln gesetzt sind, -

-

- sollte sich erneut ein FAIL ergeben -

- -
-
- - -
-
- - - - - - - - -

- est-event-log-test.cpp:228:  verify_callLogging: (log.ensureNot("fun").after("fun").after("fun2")) -

- -
- - - - - - - - -

- Verdacht: Negation -

- -
- -
- - - - - - - - -

- fun after fun matcht auf den immer gleichen Record -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- und zwar mit abgeschaltetem Filter -

- -
- - - - - -

- für diesen einen Schritt -

-

- muß die Filter-Funktion vorübergehend deaktiviert werden, -

-

- damit wir exakt das nächste / vorhergehende Element bekommen -

- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- die Search-Engine bläht die Debug-Infos gewaltig auf -

- -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- geht gar nicht anders, denn diese sind templates -

- -
- -
-
- - - -
-
-
-
- - - - - - - - - - - - -

- Invariante: pullMatch() -

- -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...d.h. die einzelnen Steps in der Pipeline direkt wrappen. -

-

- Dann ist außen herum keine Anpassung der Argumente mehr notwendig, -

-

- und man kann die Expand-Funktion direkt als std::function-Objekt durchgeben -

- -
- -
-
- - - - - - -

- ...um den Expand-Funktor zu zwingen, eine Kopie zu machen; -

-

- es sollte die Filter-Konfiguration auf der Kopie manipuliert werden, -

-

- während das Original auf dem Auswertungs-Stack liegen bleibt, -

-

- für späteres Backtracking... -

- -
-
- - - - - - - - -

- ...damit man stets weitere Builder-Funktionen auf der Pipeline aufrufen kann -

- -
-
- - - - - - -

- weil wir diesen manipulieren -

- -
-
- - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...nach der »reinen Lehre« -

- -
- - - - - - - - - - - - - - - - - - - - -

- ...insofern wir nämlich zwingend auf den jeweilign Kind-Iterator zugreifen müssen. -

-

- Nicht nur auf den aktuellen Wert (=dereferenzierter Iterator, d.h. die Funktion yield()) -

- -
- - -
-
-
-
-
- - - - - - - - - - - - - - - - -

- wir müssen hier eine Festlegung treffen -

- -
- - - - - -

- ...weil die Ergebnisse der einzelnen Schritt-Funktoren, -

-

- jeweils in den Auswertungs-Stack gepackt werden sollen. -

-

- -

-

- Daher müssen sie untereinander kompatibel sein. -

- -
- -
- - - - - - -

- im typischen Fall kopiert man den Basis-Iterator, -

-

- und manipuliert dann einige Einstellungen auf diesem. -

-

- -

-

- Wir könnten diese Kopie-Semantik sogar erzwingen, -

-

- indem wir als Argument-Typ des Schritt-Funktors eine const& vorgeben -

- -
- -
- - - - - - - - - - - - -

- ...den ich mache, um den Adapter in jedem Einzelfall zu bekommen -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -

- ....und fällt dann beim Instantiieren des Template auf die Schnautze -

- -
-
- - - - -
- - - - - - - - -

- sofern eine Initialisierung ausidem Source-Iterator möglich ist -

- -
-
- - -
- - - - - - -

- und sonst ist das nicht wirklich "kniffelig" -

- -
- - - - - -

- ...bloß sind die zig-fach geschachtelten Template-Typen, -

-

- die dann die Intantiierungs-Call-Hierarchie bevölkern, -

-

- nahezu unlesbar.... -

-

- -

-

- -

-

- AAber ... wenn es erst mal duch den Compiler ist, -

-

- dann sollte der Optimizer diese gesamten x-fachen Wrapper nahezu restlos entfernen -

- -
- -
-
-
- - - - - - - - -

- Konsequenz: jede Argument-Funktion wird nochmal gewrappt -

- -
- -
- - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- wir sind irgendwo im Baum, nicht auf dem Basis-Layer. -

-

- Und der Basis-Layer steht irgendwo, nicht an der aktuellen Position. -

- -
- - -
- - - -
-
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...denn -

-
    -
  • - es ist praktisch, zunächst "leer" zu konstruieren -
  • -
  • - es ist verständlicher, wenn alle Bedingungen symmetrisch angegeben werden -
  • -
  • - es ist natürlich, daß ein "leerer" Filter alles durchläßt -
  • -
- -
-
- - - - - - -

- Filter leer == alles durchlassen -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...d.h. direkt das Prädikat, und nicht eine Funktion, die den Filter konfiguriert -

- -
- - - - - - - - - - - - - - - - - - - - - - -

- ...habe ich noch gar nicht gemerkt, daß das geht, -

-

- und manchen komischen Workaround implementiert. -

- -
-
- - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- weil ich dann auf dem IterChainSearch unmittelbar die builder-Funktionen definieren kann -

- -
-
-
- - - - - - -

- denn: TreeExplorer == IterableDecorator< Pipeline > -

- -
- - - - - - - -

- der oberste Layer, also hier IterChainSearch -

-

- ist selbst ein StateCore. Also brauche ich noch einen Dekocator -

-

- Wenn der fehlt, wird der nächste darunterliegende Decorator gepullt, -

-

- und der wickellt direkt den Expander ein -

- -
- -
- - - - - - -
-
- - - - - - -

- konfiguriert danach direkt den Filter -

- -
- - - - - - - - - - -

- ...weil der Basis-Iterator (also der Template-Parameter SRC) -

-

- explizit und absichtlich einen anderen Typ haben könnte, als der expandierte Kind-Iterator. -

-

- Das ist ein wesentliches Feature dieses Expander-Designs, würde aber leider eine -

-

- komplett generische Accessor-Funktion unmöglich machen (das Template würde in -

-

- einem Solchen Fall insgesamt vom Compiler zurückgewiesen) -

- -
- -
-
-
-
-
- - - - - - - - - - -

- sausage-bacon-tomato-and-sausage-spam-spam-bacon-spam-tomato-and-spam-spam-bacon-tomato-and-spam-bacon-tomato-and-spam-tomato-and-spam -

- -
- - - - - - - - - - - - - - - -

- sausage-bacon-tomato-and-spam-spam-bacon-spam-tomato-and-spam-bacon-tomato-and-bacon-tomato-and-tomato-and -

- -
- -
-
- - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...wie bekommt man dann den konvertierten Wert 'raus. -

-

- Visitor ist entweder void, oder bool -

- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
  • - kein allgemeines Such-Framework bauen! -
  • -
  • - den Begriff des "Containers" knapp halten: was keine const_reference bietet, ist kein Container -
  • -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Man würde also neben das Standard-Format ein toleriertes zweites Format stellen, welches dann ein Bürger zweiter Klasse wäre, aber auf allen wichtien APIs als 2.Alternative mit auftaucht. Zudem würde man gewisse Abkürzungs-Pfade schaffen, auf denen die alternative Spec dann verlustfrei durchgereicht werden kann. -

-
    -
  • - es ist überhaupt nicht klar, welches Format dann der Standardfall sein sollte -
  • -
  • - das läuft vor allem auf eine Performance-Betrachtung hinaus, und einen trade-off, wo man ggfs Fehler durch andere Programmierer akzeptiert -
  • -
- -
-
-
-
- - - - - - - - - -

- wenn man zum µ-Grid eine eindeutige Rundungs-Regel hinzufügt, -

-

- kann es praktisch auch Sound-Samples korrekt addressieren:

1/96000 ≙ 10,41666666666666666667 µTicks -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - -

- im Besonderen bei den pragmatischen Lösungen -

- -
- - - -
- - - -
- - - - - - - - - - - - - - - - - - - -

- und ganz im Besonderen: wir stützen uns für die Zeitbehandlung nicht auf libGavl ab -

- -
- -
-
- - - - - - - - - - - - - - - - - - -

- FSecs durch einen neuen Wrapper RSec ersetzen -

- -
- - - - - - - - - - - - - - - - - -

- nicht implizit konstruierbar aus int64_t -

- -
- - - - - - - - - - - - - - - - - - - - - -

- ...seinerzeit fand ich diese Art »Offenheit« noch gut; auch weil ich mir erhoffte, damit mehr Contributors zu bekommen. Die Erfahrungen sprechen dagegen; klar, die Leute mögen erst einmal gerne „move fast and break things“ — aber wenn dann Aufräumen oder anstrengende Konzeptions-Arbeit notwendig würde, bleibt alles liegen und man verschwindet aus dem Projekt. -

- -
-
- - - - - - - - - - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Begründung: sie entstehen als Delta aus validen Zeitpunkten -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -70143,8 +70252,7 @@              >

- - +
@@ -70162,8 +70270,7 @@ lib::iter_explorer::Expander<lib::iter_explorer::BaseAdapter<lib::SingleValIter<steam::engine::JobTicket*> >, lib::TransformIter<lib::TransformIter<lib::IterStateWrapper<steam::engine::JobTicket::Prerequisite, lib::LinkedElements<steam::engine::JobTicket::Prerequisite>::IterationState>, const steam::engine::JobTicket&>, steam::engine::JobTicket*> >

- - +
@@ -70187,8 +70294,7 @@ Expander<SrC, ExpandedChildren>

- - +
@@ -70376,7 +70482,8 @@ - + + @@ -70389,6 +70496,194 @@ + + + + + + + + + + + + + +

+ auch das zum Glück +

+

+ denn diese ist am aller fragwürdigsten +

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

+ ...was wohl genau daran liegt, daß TypeBinding konzeptionell "daneben" ist +

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

+ hier ist ein Hinweis auf TICKET #1125 : get rid of Val +

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