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:
parent
88b2260496
commit
dfd3dc1275
3 changed files with 66 additions and 9 deletions
|
|
@ -245,6 +245,18 @@ namespace lib {
|
|||
// for comparison with IterAdapter{}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
using ConRef = typename iter::TypeBinding<CON>::reference;
|
||||
|
||||
/** allow derived classes to
|
||||
* access backing container */
|
||||
ConRef
|
||||
source()
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
_maybe_throw() const
|
||||
|
|
|
|||
|
|
@ -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 <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
|
@ -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<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,
|
||||
* @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 IT>
|
||||
class WrappedLumieraIterator
|
||||
class WrappedLumieraIter
|
||||
: public IterSource<typename IT::value_type>
|
||||
, 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<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;
|
||||
|
||||
return IterSource<ValType>::build (
|
||||
new WrappedLumieraIterator<TransIT> (
|
||||
new WrappedLumieraIter<TransIT> (
|
||||
transformIterator (source, processingFunc)));
|
||||
}
|
||||
|
||||
|
|
@ -434,7 +450,7 @@ namespace lib {
|
|||
typedef RangeIter<typename CON::iterator> Range;
|
||||
|
||||
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;
|
||||
|
||||
Range contents (begin, end);
|
||||
return IterSource<ValType>::build (new WrappedLumieraIterator<Range>(contents));
|
||||
return IterSource<ValType>::build (new WrappedLumieraIter<Range>(contents));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@
|
|||
|
||||
|
||||
|
||||
namespace std {
|
||||
template<typename _Tp>
|
||||
class shared_ptr;
|
||||
}
|
||||
|
||||
namespace lib {
|
||||
namespace iter {
|
||||
|
||||
|
|
@ -78,6 +83,30 @@ namespace iter {
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue