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....
This commit is contained in:
Fischlurch 2017-08-11 16:56:18 +02:00
parent 88b2260496
commit dfd3dc1275
3 changed files with 66 additions and 9 deletions

View file

@ -245,6 +245,18 @@ namespace lib {
// for comparison with IterAdapter{} // for comparison with IterAdapter{}
protected:
using ConRef = typename iter::TypeBinding<CON>::reference;
/** allow derived classes to
* access backing container */
ConRef
source()
{
return source_;
}
private: private:
void void
_maybe_throw() const _maybe_throw() const

View file

@ -32,7 +32,7 @@
** \par Standard Adapters ** \par Standard Adapters
** As a complement, this header contains a generic implementation ** As a complement, this header contains a generic implementation
** of the IterSource interface by wrapping an existing Lumiera Forward Iterator. ** 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 ** 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 ** is provided, allowing to build opaque "all elements" or "all keys" iterators
** for various STL containers. ** for various STL containers.
@ -53,6 +53,7 @@
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <string>
#include <memory> #include <memory>
@ -60,6 +61,7 @@
namespace lib { namespace lib {
using std::string;
using std::shared_ptr; using std::shared_ptr;
@ -107,7 +109,14 @@ namespace lib {
public: 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 == */ /* == Iteration control API for IterAdapter frontend == */
@ -127,7 +136,14 @@ namespace lib {
/* == public builder API to create instances == */ /* == public builder API to create instances == */
typedef IterAdapter<Pos, DataHandle> iterator; struct iterator
: IterAdapter<Pos, DataHandle>
{
using _I = IterAdapter<Pos, DataHandle>
;
using _I::IterAdapter;
operator string() const {return _I::source()? string(*_I::source()) : ""; }
};
/** build an iterator frontend for the given source, /** build an iterator frontend for the given source,
* @note the source is allocated separately and * @note the source is allocated separately and
@ -203,7 +219,7 @@ namespace lib {
* erasing the specific type information of the template parameter IT * erasing the specific type information of the template parameter IT
*/ */
template<class IT> template<class IT>
class WrappedLumieraIterator class WrappedLumieraIter
: public IterSource<typename IT::value_type> : public IterSource<typename IT::value_type>
, boost::noncopyable , boost::noncopyable
{ {
@ -235,7 +251,7 @@ namespace lib {
public: public:
WrappedLumieraIterator (IT const& orig) WrappedLumieraIter (IT const& orig)
: src_(orig) : src_(orig)
{ } { }
}; };
@ -333,7 +349,7 @@ namespace lib {
{ {
typedef typename _IterT<IT>::Val ValType; typedef typename _IterT<IT>::Val ValType;
return IterSource<ValType>::build (new WrappedLumieraIterator<IT> (source)); return IterSource<ValType>::build (new WrappedLumieraIter<IT> (source));
} }
@ -354,7 +370,7 @@ namespace lib {
typedef typename _TransformIterT<IT,FUN>::TransIter TransIT; typedef typename _TransformIterT<IT,FUN>::TransIter TransIT;
return IterSource<ValType>::build ( return IterSource<ValType>::build (
new WrappedLumieraIterator<TransIT> ( new WrappedLumieraIter<TransIT> (
transformIterator (source, processingFunc))); transformIterator (source, processingFunc)));
} }
@ -434,7 +450,7 @@ namespace lib {
typedef RangeIter<typename CON::iterator> Range; typedef RangeIter<typename CON::iterator> Range;
Range contents (container.begin(), container.end()); Range contents (container.begin(), container.end());
return IterSource<ValType>::build (new WrappedLumieraIterator<Range>(contents)); return IterSource<ValType>::build (new WrappedLumieraIter<Range>(contents));
} }
@ -449,7 +465,7 @@ namespace lib {
typedef RangeIter<IT> Range; typedef RangeIter<IT> Range;
Range contents (begin, end); Range contents (begin, end);
return IterSource<ValType>::build (new WrappedLumieraIterator<Range>(contents)); return IterSource<ValType>::build (new WrappedLumieraIter<Range>(contents));
} }
} }

View file

@ -43,6 +43,11 @@
namespace std {
template<typename _Tp>
class shared_ptr;
}
namespace lib { namespace lib {
namespace iter { namespace iter {
@ -78,6 +83,30 @@ namespace iter {
typedef const TY* pointer; typedef const TY* pointer;
}; };
template<typename TY>
struct TypeBinding<TY &>
{
typedef TY value_type;
typedef TY& reference;
typedef TY* pointer;
};
template<typename TY>
struct TypeBinding<TY const&>
{
typedef TY value_type;
typedef const TY& reference;
typedef const TY* pointer;
};
template<typename TY>
struct TypeBinding<std::shared_ptr<TY>>
{
typedef TY value_type;
typedef const TY& reference;
typedef const TY* pointer;
};
}} // namespace lib }} // namespace lib