From 269ef076555cdbcec073971cc1726a8267340204 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 17 Sep 2015 19:00:55 +0200 Subject: [PATCH] introduce special treatment for RecRef payload The intention is to allow a Ref to "stand-in" for a GenNode holding a full Record inline --- src/lib/diff/gen-node.hpp | 63 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index f57a11dba..c94185060 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -188,6 +188,11 @@ namespace diff{ Locator expand() const; operator string() const; + + template + X& get(); + template + X const& get() const; }; @@ -345,7 +350,7 @@ namespace diff{ - /* === iteration / recursive expansion / references === */ + /* === iteration / recursive expansion === */ /** @@ -495,6 +500,58 @@ namespace diff{ + + /* === References : special treatment on element access === */ + + template + inline X& + DataCap::get() + { + return Variant::get(); + } + + template + inline X const& + DataCap::get() const + { + return Variant::get(); + } + + /** especially when accessing for a Record, + * a payload of type \c RecordRef> (aka RecRef) + * will be automatically dereferenced. Effectively this allows + * a GenNode with a RecRef payload to "stand in" for a node holding + * a full Record inline. And it allows the construction of a special + * \link #Ref Ref-GenNode \endlink, which even shares the \em identity + * (the ID) of the referenced record-GenNode. + * @note effectively this opens an indirect loophole to const correctness, + * since it is possible explicitly to retrieve the RecRef from a + * const GenNode and then to access the referred-to Record + * without const. In case this turns out to be problematic, + * we'd have to alter the semantics of RecRef + */ + template<> + inline Rec& + DataCap::get() + { + Rec* rec = maybeGet(); + if (rec) return *rec; + + return Variant::get(); + } + + template<> + inline Rec const& + DataCap::get() const + { + Rec* rec = unConst(this)->maybeGet(); + if (rec) return *rec; + + return Variant::get(); + } + + + /** * Constructor for a specially crafted 'ref GenNode'. * The identity record of the generated object will be prepared @@ -509,8 +566,8 @@ namespace diff{ */ explicit Ref(string const& symbolicID) - : GenNode(fabricateRefID (symbolicID) - , DataCap(RecRef())) // note: places NIL into the reference part + : GenNode(fabricateRefID (symbolicID)//note: seeds the type hash with Rec, not RecRef + , DataCap(RecRef())) // note: places NIL into the reference part { } /** build reference to a Record, using the original ID