From d92878876a94babbd3ae90696d9af2cf0bb72a92 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 4 Jul 2015 03:39:53 +0200 Subject: [PATCH] WIP: attempt to define the object builder invocation chain TODO still unresolved issues with the bootstrap. Looks like we shall not initiate from the basic Rec(), but reather require an explicit construction. --- src/lib/diff/gen-node.hpp | 33 +++++++++++++++ src/lib/diff/record.hpp | 84 ++++++++++++++++++++++++++++++++++----- wiki/thinkPad.ichthyo.mm | 72 ++++++++++++++++++++++++++++++++- 3 files changed, 179 insertions(+), 10 deletions(-) diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index 594f0881d..fece1c643 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -263,6 +263,39 @@ namespace diff{ + /* === Specialisation to add fluent GenNode builder API to Record === */ + + template<> + inline GenNode&& + Rec::Mutator::genNode() + { + UNIMPLEMENTED("wrap newly built Record into a new GenNode instance"); + } + + template<> + inline GenNode&& + Rec::Mutator::genNode(string const& symbolicID) + { + UNIMPLEMENTED("wrap newly built Record into a new named GenNode instance"); + } + + template<> + template + inline Rec::Mutator& + Rec::Mutator::attrib (ARGS&& ...args) + { + UNIMPLEMENTED("split sequence of arguments into key-value pairs and use these to populate the attributes collection"); + } + + template<> + template + inline Rec::Mutator& + Rec::Mutator::scope (ARGS&& ...args) + { + UNIMPLEMENTED("split sequence of arguments and build GenNode instances from them, to populate scope collection"); + } + + /* === Specialisation for handling of attributes in Record === */ template<> diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index 5a4ab6a3b..a33d36b83 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -131,7 +131,6 @@ namespace diff{ class Record { using _Vec = std::vector; - using Attrib = std::pair; using Attribs = _Vec; using Children = _Vec; @@ -247,6 +246,44 @@ namespace diff{ + /* ==== extension point for fluent builder API ====== */ + + // to initiate and open builder chain: + Mutator + type (string const& typeID) + { + return Mutator(*this).type(typeID); + } + + template + Mutator + attrib (ARGS&& ...args) + { + return Mutator(*this).attrib(std::forward(args)...); + } + + template + Mutator + scope (ARGS&& ...args) + { + return Mutator(*this).scope(std::forward(args)...); + } + + // to close and finish builder chain (needs specialisation) + VAL&& + genNode() + { + return Mutator(*this).genNode(); + } + + VAL&& + genNode(string const& symbolicID) + { + return Mutator(*this).genNode(symbolicID); + } + + + /* ==== Exposing scope and contents for iteration ====== */ using iterator = IterAdapter; @@ -354,6 +391,12 @@ namespace diff{ std::swap (existingInstance, record_); } + bool + empty() const + { + return record_.empty(); + } + /* === functions to alter contents === */ @@ -364,29 +407,52 @@ namespace diff{ record_.type_ = newTypeID; } - void + Mutator& + type (string const& typeID) + { + setType (typeID); + return *this; + } + + Mutator& set (string const& key, VAL const& newValue) { ///////////TODO; + return *this; } - void + Mutator& appendChild (VAL const& newChild) { record_.children_.push_back (newChild); + return *this; } - void + Mutator& prependChild (VAL const& newChild) { record_.children_.insert (record_.children_.begin(), newChild); + return *this; } - bool - empty() const - { - return record_.empty(); - } + + /* === extension point for building specific value types === */ + /* + * the following builder functions are to be specialised + * to create a Record holding specific value types, + * especially for building a tree like structure + * with GenNode holding a Record + */ + + VAL&& genNode(); + VAL&& genNode(string const& symbolicID); + + template + Mutator& attrib (ARGS&& ...); + + template + Mutator& scope (ARGS&& ...); + }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 8e782dbcd..517c951c3 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -196,8 +196,78 @@ + + + + + + +

+ Object builder +

+ + +
+ + + + + + + +

+ Problem ist, wir definieren den Typ Record generisch, +

+

+ verwenden dann aber nur die spezialisierung Record<GenNode> +

+

+ Und die Builder-Funktionen brauchen eigentlich spezielles Wissen über den zu konstruierenden Zieltyp +

+ + +
+
- + + + + + + +

+ Ergebnis move +

+

+ pro / contra +

+ + +
+ + + + + +

+ Move ist gefährlich +

+

+ aber auch deutlich effizienter, +

+

+ denn wir müssen sonst das ganze erzeugte Ergebnis einmal kopieren. +

+

+ Nicht sicher, ob der Optimiser das hinbekommt +

+ + +
+
+
+
+