diff --git a/src/lib/diff/diff-message.hpp b/src/lib/diff/diff-message.hpp index 047ad9d52..4538c9c4f 100644 --- a/src/lib/diff/diff-message.hpp +++ b/src/lib/diff/diff-message.hpp @@ -157,11 +157,14 @@ namespace diff{ * this operation needs to impose a _side effect:_ it materialises * the complete diff sequence at once into a heap allocated buffer. */ - DiffMessage& withDiagnostics(); + DiffMessage& updateDiagnostics(); }; - namespace { + + + namespace { // Implementation: take snapshot to enable diagnostics + /** "materialised view" of the diff sequence */ struct DiffSnapshot : std::vector { @@ -176,6 +179,15 @@ namespace diff{ using _RangeIT = RangeIter<_VecIter>; using _Wrapped = WrappedLumieraIter<_RangeIT>; + /** + * Decorator to be layered transparently on top of DiffMessage. + * Actually, what we do is to discharge the diff generator into + * the DiffSnapshot buffer and then replace the link to the original + * generator to this decorator, which, when iterated, yields the + * contents of the DiffSnapshot one by one. But since all DiffSteps + * are now stored into that DiffSnapshot _buffer we control,_ we're + * able to produce a diagnostic listing of the complete sequence. + */ class MaterialisedDiffMessageBuffer : private DiffSnapshot , public _Wrapped @@ -194,8 +206,18 @@ namespace diff{ }; } + /** @par operational semantics + * Since the underlying generator of the DiffStep sequence is an iterator, + * the "materialised view" can only capture what's left at the point when + * updateDiagnostics() is invoked. The captured rest sequence seamlessly + * becomes the new generator and the old generator object is released, + * since the assignment of the new backend typically removes the last + * reference in the smart-ptr managing the generation backend. This + * process can be repeated and then the [diagnostics](operator string()) + * will show the remainder of the sequence _left at that point._ + */ inline DiffMessage& - DiffMessage::withDiagnostics() + DiffMessage::updateDiagnostics() { return *this = DiffMessage{new MaterialisedDiffMessageBuffer(*this)}; } diff --git a/src/lib/format-util.hpp b/src/lib/format-util.hpp index f9d8ac90f..56a68ebcc 100644 --- a/src/lib/format-util.hpp +++ b/src/lib/format-util.hpp @@ -205,6 +205,13 @@ namespace util { return buffer.str().substr(0, len - delim.length()); } + template + inline string + join (std::initializer_list const&& ili, string const& delim =", ") + { + return join (ili, delim); + } + } // namespace util #endif /*LIB_FORMAT_UTIL_H*/ diff --git a/tests/library/diff/diff-message-test.cpp b/tests/library/diff/diff-message-test.cpp index 2dfe3abf4..a63d4f8a0 100644 --- a/tests/library/diff/diff-message-test.cpp +++ b/tests/library/diff/diff-message-test.cpp @@ -33,7 +33,6 @@ #include "lib/iter-adapter-stl.hpp" #include "lib/time/timevalue.hpp" #include "lib/format-util.hpp" -#include "lib/format-cout.hpp" ///////////////TODO remove when done #include "lib/util.hpp" #include @@ -42,6 +41,7 @@ using lumiera::error::LUMIERA_ERROR_ITER_EXHAUST; using lib::iter_stl::IterSnapshot; using lib::iter_stl::snapshot; +using util::contains; using util::isnil; using util::join; using std::string; @@ -294,16 +294,35 @@ namespace test{ ,set(ATTRIB1) ,del(CHILD_T)}; - cout << diffMsg <::DiffStep>"); - diffMsg.withDiagnostics(); - cout << diffMsg <