diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index 3b6f2bb9c..0868fda5c 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -391,6 +391,49 @@ namespace diff{ + /** + * wrapped record reference. + * A helper for lib::GenNode and the diff representation. + * RecordRef is copyable and assignable, but like a reference + * can not be rebound. It can be used to refer to a subtree + * within the diff representation, without the need to copy. + */ + template + class RecordRef + { + using Target = Record; + + Target* record_; + + public: + RecordRef(Target& o) noexcept + : record_(&o) + { } + + RecordRef(Target&&) = delete; + + // standard copy operations acceptable + + + operator Target&() const + { + if (!record_) + throw error::Logic("attempt to dereference an unbound record reference" + ,error::LUMIERA_ERROR_BOTTOM_VALUE); + return *record_; + } + + Target* + get() const noexcept + { + return record_; + } + }; + + + + + /* === Specialisations to define the handling of attributes === */ template<> diff --git a/tests/library/diff/generic-record-representation-test.cpp b/tests/library/diff/generic-record-representation-test.cpp index 13f0da01f..c20488515 100644 --- a/tests/library/diff/generic-record-representation-test.cpp +++ b/tests/library/diff/generic-record-representation-test.cpp @@ -47,6 +47,7 @@ namespace test{ // using lumiera::error::LUMIERA_ERROR_LOGIC; using lumiera::error::LUMIERA_ERROR_INVALID; + using lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE; namespace {//Test fixture.... @@ -105,6 +106,7 @@ namespace test{ verifyMutations(); copy_and_move(); equality(); + wrapRef(); } @@ -294,6 +296,37 @@ namespace test{ CHECK (Seq({"type=u", "a=α", "a=β", "⟂", "a"}) == contents(a)); CHECK (Seq({"type=u", "a=1", "a"}) == contents(aa)); } + + + void + wrapRef() + { + RecS oo({"type = 🌰", "☿ = mercury", "♀ = venus", "♁ = earth", "♂ = mars", "♃ = jupiter", "♄ = saturn"}); + + RecordRef empty; + CHECK (bool(empty) == false); + CHECK (nullptr == empty.get()); + VERIFY_ERROR (BOTTOM_VALUE, RecS& (empty)); + + RecordRef ref(oo); + CHECK (ref); + CHECK (ref.get() == &oo); + + RecS& oor = ref; + CHECK ("🌰" == oor.getType()); + CHECK (oor.get("♄") == "saturn"); + + // are copyable and assignable + RecordRef r2 = ref; + CHECK (r2); + CHECK (r2.get() == ref.get()); + CHECK (!isSameObject (r2, ref)); + + empty = std::move(r2); + CHECK (empty); + CHECK (!r2); + CHECK (nullptr == r2.get()); + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7073b3232..671867b0f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -42,10 +42,10 @@ - - + + - + @@ -59,7 +59,8 @@ - + + @@ -73,8 +74,7 @@ -- im DataCap

- -
+
@@ -111,9 +111,23 @@ - - - + + + + + + + + + + +

+ m.E. die einzig saubere Desgin-Variante! +

+ + +
+
@@ -156,10 +170,10 @@

- - + + - + @@ -170,6 +184,7 @@

+