From dfd3dc1275c5e692d7245690faadb95dc48dd1c6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 11 Aug 2017 16:56:18 +0200 Subject: [PATCH] DiffMessage: reshape IterAdapter to allow for custom diagnostics since we do not want to increase the footprint, we're bound to reuse an existing VTable -- so IterAdapter itself is our only option. Unfortunately we'll need to pass that through one additional decoration layer, which is here the iterator; to be able to add our string conversion there, we need to turn that into a derived class and add a call to access the underlying container, which gets us into element type definition mess.... --- src/lib/iter-adapter.hpp | 12 ++++++++++++ src/lib/iter-source.hpp | 34 +++++++++++++++++++++++++--------- src/lib/iter-type-binding.hpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index 168595ce9..b41dcae2c 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -245,6 +245,18 @@ namespace lib { // for comparison with IterAdapter{} + + protected: + using ConRef = typename iter::TypeBinding::reference; + + /** allow derived classes to + * access backing container */ + ConRef + source() + { + return source_; + } + private: void _maybe_throw() const diff --git a/src/lib/iter-source.hpp b/src/lib/iter-source.hpp index ec97a38a4..59099924d 100644 --- a/src/lib/iter-source.hpp +++ b/src/lib/iter-source.hpp @@ -32,7 +32,7 @@ ** \par Standard Adapters ** As a complement, this header contains a generic implementation ** of the IterSource interface by wrapping an existing Lumiera Forward Iterator. - ** Using this WrappedLumieraIterator, the details of this wrapped source iterator + ** Using this WrappedLumieraIter, the details of this wrapped source iterator ** remain opaque. To ease the use of this adapter, a selection of free functions ** is provided, allowing to build opaque "all elements" or "all keys" iterators ** for various STL containers. @@ -53,6 +53,7 @@ #include #include +#include #include @@ -60,6 +61,7 @@ namespace lib { + using std::string; using std::shared_ptr; @@ -107,7 +109,14 @@ namespace lib { public: - virtual ~IterSource() { }; ///< is ABC + virtual ~IterSource() { }; ///< is ABC + + virtual + operator string() const ///< subclasses may offer diagnostics + { + return "IterSource(opaque)"; + } + /* == Iteration control API for IterAdapter frontend == */ @@ -127,7 +136,14 @@ namespace lib { /* == public builder API to create instances == */ - typedef IterAdapter iterator; + struct iterator + : IterAdapter + { + using _I = IterAdapter + ; + using _I::IterAdapter; + operator string() const {return _I::source()? string(*_I::source()) : "⟂"; } + }; /** build an iterator frontend for the given source, * @note the source is allocated separately and @@ -203,7 +219,7 @@ namespace lib { * erasing the specific type information of the template parameter IT */ template - class WrappedLumieraIterator + class WrappedLumieraIter : public IterSource , boost::noncopyable { @@ -235,7 +251,7 @@ namespace lib { public: - WrappedLumieraIterator (IT const& orig) + WrappedLumieraIter (IT const& orig) : src_(orig) { } }; @@ -333,7 +349,7 @@ namespace lib { { typedef typename _IterT::Val ValType; - return IterSource::build (new WrappedLumieraIterator (source)); + return IterSource::build (new WrappedLumieraIter (source)); } @@ -354,7 +370,7 @@ namespace lib { typedef typename _TransformIterT::TransIter TransIT; return IterSource::build ( - new WrappedLumieraIterator ( + new WrappedLumieraIter ( transformIterator (source, processingFunc))); } @@ -434,7 +450,7 @@ namespace lib { typedef RangeIter Range; Range contents (container.begin(), container.end()); - return IterSource::build (new WrappedLumieraIterator(contents)); + return IterSource::build (new WrappedLumieraIter(contents)); } @@ -449,7 +465,7 @@ namespace lib { typedef RangeIter Range; Range contents (begin, end); - return IterSource::build (new WrappedLumieraIterator(contents)); + return IterSource::build (new WrappedLumieraIter(contents)); } } diff --git a/src/lib/iter-type-binding.hpp b/src/lib/iter-type-binding.hpp index 4580ac18c..fa48a0083 100644 --- a/src/lib/iter-type-binding.hpp +++ b/src/lib/iter-type-binding.hpp @@ -43,6 +43,11 @@ +namespace std { + template + class shared_ptr; +} + namespace lib { namespace iter { @@ -78,6 +83,30 @@ namespace iter { typedef const TY* pointer; }; + template + struct TypeBinding + { + typedef TY value_type; + typedef TY& reference; + typedef TY* pointer; + }; + + template + struct TypeBinding + { + typedef TY value_type; + typedef const TY& reference; + typedef const TY* pointer; + }; + + template + struct TypeBinding> + { + typedef TY value_type; + typedef const TY& reference; + typedef const TY* pointer; + }; + }} // namespace lib