Victory! bashed the iter-adapters and the ScopedPtrVect into submission, finally.
This commit is contained in:
parent
165cfc7fcd
commit
3f8d82a13f
3 changed files with 146 additions and 63 deletions
|
|
@ -77,11 +77,44 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Helper for creating nested typedefs
|
||||
* within the iterator adaptor, similar to what the STL does.
|
||||
*/
|
||||
template<typename TY>
|
||||
struct IterTraits
|
||||
{
|
||||
typedef typename TY::pointer pointer;
|
||||
typedef typename TY::reference reference;
|
||||
typedef typename TY::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename TY>
|
||||
struct IterTraits<TY *>
|
||||
{
|
||||
typedef TY value_type;
|
||||
typedef TY& reference;
|
||||
typedef TY* pointer;
|
||||
};
|
||||
|
||||
template<typename TY>
|
||||
struct IterTraits<const TY *>
|
||||
{
|
||||
typedef TY value_type;
|
||||
typedef const TY& reference;
|
||||
typedef const TY* pointer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adapter for building an implementation of the lumiera forward iterator concept.
|
||||
|
|
@ -107,9 +140,9 @@ namespace lib {
|
|||
mutable POS pos_;
|
||||
|
||||
public:
|
||||
typedef typename POS::pointer pointer;
|
||||
typedef typename POS::reference reference;
|
||||
typedef typename POS::value_type value_type;
|
||||
typedef typename IterTraits<POS>::pointer pointer;
|
||||
typedef typename IterTraits<POS>::reference reference;
|
||||
typedef typename IterTraits<POS>::value_type value_type;
|
||||
|
||||
IterAdapter (const CON* src, const POS& startpos)
|
||||
: source_(src)
|
||||
|
|
@ -243,9 +276,9 @@ namespace lib {
|
|||
IT e_;
|
||||
|
||||
public:
|
||||
typedef typename IT::pointer pointer;
|
||||
typedef typename IT::reference reference;
|
||||
typedef typename IT::value_type value_type;
|
||||
typedef typename IterTraits<IT>::pointer pointer;
|
||||
typedef typename IterTraits<IT>::reference reference;
|
||||
typedef typename IterTraits<IT>::value_type value_type;
|
||||
|
||||
RangeIter (IT const& start, IT const& end)
|
||||
: p_(start)
|
||||
|
|
@ -287,6 +320,7 @@ namespace lib {
|
|||
RangeIter&
|
||||
operator++()
|
||||
{
|
||||
_maybe_throw();
|
||||
++p_;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -294,6 +328,7 @@ namespace lib {
|
|||
RangeIter
|
||||
operator++(int)
|
||||
{
|
||||
_maybe_throw();
|
||||
return RangeIter (p_++,e_);
|
||||
}
|
||||
|
||||
|
|
@ -361,6 +396,42 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper for type rewritings:
|
||||
* get the element type for an iterator like entity
|
||||
*/
|
||||
template<class TY>
|
||||
struct IterType;
|
||||
|
||||
template<template<class,class> class Iter, class TY, class CON>
|
||||
struct IterType<Iter<TY,CON> >
|
||||
{
|
||||
typedef CON Container;
|
||||
typedef TY ElemType;
|
||||
|
||||
typedef typename RemovePtr<TY>::Type ValueType;
|
||||
|
||||
template<class T2>
|
||||
struct SimilarIter
|
||||
{
|
||||
typedef Iter<T2,CON> Type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class IT>
|
||||
struct IterType<RangeIter<IT> >
|
||||
: IterType<IT>
|
||||
{
|
||||
template<class T2>
|
||||
struct SimilarIter ///< rebind to rewritten Iterator wrapped into RangeIter
|
||||
{
|
||||
typedef typename IterType<IT>::template SimilarIter<T2>::Type WrappedIter;
|
||||
typedef RangeIter<WrappedIter> Type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* wrapper for an existing Iterator type,
|
||||
* automatically dereferencing the output of the former.
|
||||
|
|
@ -372,26 +443,56 @@ namespace lib {
|
|||
class PtrDerefIter
|
||||
: public lib::BoolCheckable<PtrDerefIter<IT> >
|
||||
{
|
||||
IT i_;
|
||||
IT i_; ///< nested source iterator
|
||||
|
||||
|
||||
public:
|
||||
typedef typename IT::value_type pointer;
|
||||
typedef typename IT::value_type pointer;
|
||||
typedef typename RemovePtr<pointer>::Type value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type& reference;
|
||||
|
||||
// the purpose of the following typedefs is to ease building a correct "const iterator"
|
||||
|
||||
typedef typename boost::remove_const<value_type>::type ValueTypeBase; // value_type without const
|
||||
|
||||
typedef typename IterType<IT>::template SimilarIter< ValueTypeBase* * >::Type WrappedIterType;
|
||||
typedef typename IterType<IT>::template SimilarIter<const ValueTypeBase* * >::Type WrappedConstIterType;
|
||||
|
||||
typedef PtrDerefIter<WrappedIterType> IterType;
|
||||
typedef PtrDerefIter<WrappedConstIterType> ConstIterType;
|
||||
|
||||
|
||||
|
||||
/** PtrDerefIter is always created
|
||||
* by wrapping an existing iterator.
|
||||
*/
|
||||
PtrDerefIter (IT srcIter)
|
||||
: i_(srcIter)
|
||||
{ }
|
||||
|
||||
|
||||
/** allow copy initialisation also
|
||||
* when the base iter types are convertible */
|
||||
template<class I2>
|
||||
PtrDerefIter (I2 const& oIter)
|
||||
: i_(reinterpret_cast<IT const&> (oIter.getBase())) /////////////////////////////TODO: properly guard this dangerous conversion by a traits template; the idea is to allow this conversion only for the initialisation of a "const iterator" from its sister type
|
||||
/** allow copy initialisation also when
|
||||
* the wrapped iterator is based on some variation of a pointer.
|
||||
* Especially, this includes initialisation of the "const variant"
|
||||
* from the "normal variant" of PtrDerefIter. Actually, we need to convert
|
||||
* in this case by brute force, because indeed (const TY *)* is not assignable
|
||||
* from (TY *)* -- just we know that our intention is to dereference both levels
|
||||
* of pointers, and then the resulting conversion is correct.
|
||||
* @note in case IT == WrappedIterType, this is just a redefinition of the
|
||||
* default copy ctor. In all other cases, this is an <i>additional
|
||||
* ctor besides the default copy ctor</i> */
|
||||
PtrDerefIter (PtrDerefIter<WrappedIterType> const& oIter)
|
||||
: i_(reinterpret_cast<IT const&> (oIter.getBase()))
|
||||
{ }
|
||||
|
||||
PtrDerefIter&
|
||||
operator= (PtrDerefIter<WrappedIterType> const& ref)
|
||||
{
|
||||
i_ = reinterpret_cast<IT const&> (ref.getBase());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
|
|
@ -450,28 +551,5 @@ namespace lib {
|
|||
bool operator!= (PtrDerefIter<I1> const& il, PtrDerefIter<I2> const& ir) { return !(il == ir); }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper for type rewritings:
|
||||
* get the element type for an iterator like entity
|
||||
*/
|
||||
template<class TY>
|
||||
struct IterType;
|
||||
|
||||
template<template<class,class> class Iter, class TY, class CON>
|
||||
struct IterType<Iter<TY,CON> >
|
||||
{
|
||||
typedef CON Container;
|
||||
typedef TY ElemType;
|
||||
|
||||
typedef typename RemovePtr<TY>::Type Type;
|
||||
|
||||
template<class T2>
|
||||
struct SimilarIter
|
||||
{
|
||||
typedef Iter<T2,CON> Type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "include/logging.h"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
|
@ -56,14 +55,13 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
using util::for_each;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Simple vector based collection of pointers, noncopyable and managing
|
||||
* lifecycle of the pointed-to objects. Implemented by a vector of
|
||||
* bare pointers (private inheritance)
|
||||
* Simple vector based collection of pointers,
|
||||
* managing lifecycle of the pointed-to objects.
|
||||
* Implemented as a non-copyable object, based on a
|
||||
* vector of bare pointers (private inheritance)
|
||||
*/
|
||||
template<class T>
|
||||
class ScopedPtrVect
|
||||
|
|
@ -72,11 +70,12 @@ namespace lib {
|
|||
{
|
||||
typedef std::vector<T*> _Vec;
|
||||
typedef typename _Vec::iterator VIter;
|
||||
// typedef typename _Vec::const_iterator VcIter;
|
||||
typedef typename IterType<VIter>::template SimilarIter<const T**>::Type VcIter;
|
||||
|
||||
typedef RangeIter<VIter> RIter;
|
||||
typedef RangeIter<VcIter> RcIter;
|
||||
typedef PtrDerefIter<RIter> IterType;
|
||||
|
||||
typedef typename IterType::ConstIterType ConstIterType;
|
||||
typedef typename IterType::WrappedConstIterType RcIter;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -84,8 +83,6 @@ namespace lib {
|
|||
typedef T & reference;
|
||||
typedef T const& const_reference;
|
||||
|
||||
typedef typename IterType<VIter>::Type Tupe;
|
||||
|
||||
|
||||
|
||||
ScopedPtrVect ()
|
||||
|
|
@ -154,8 +151,8 @@ namespace lib {
|
|||
return *get(i);
|
||||
}
|
||||
|
||||
typedef PtrDerefIter<RIter> iterator;
|
||||
typedef PtrDerefIter<RcIter> const_iterator;
|
||||
typedef IterType iterator;
|
||||
typedef ConstIterType const_iterator;
|
||||
|
||||
iterator begin() { return iterator (allPtrs()); }
|
||||
const_iterator begin() const { return const_iterator (allPtrs()); }
|
||||
|
|
|
|||
|
|
@ -23,31 +23,27 @@
|
|||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "lib/scoped-ptrvect.hpp"
|
||||
#include "testdummy.hpp"
|
||||
|
||||
//////////////////////////////////////////////TODO test code
|
||||
#include "lib/test/test-helper.hpp"
|
||||
using lib::test::showSizeof;
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
//////////////////////////////////////////////TODO test code
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
using ::Test;
|
||||
using util::isnil;
|
||||
using lumiera::error::LUMIERA_ERROR_ITER_EXHAUST;
|
||||
|
||||
|
||||
typedef ScopedPtrVect<Dummy> VectD;
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* @test ScopedPtrVect manages the lifecycle of a number of objects.
|
||||
* @todo cover the const iterator and implement detaching of objects
|
||||
* @todo implement detaching of objects
|
||||
*/
|
||||
class ScopedPtrVect_test : public Test
|
||||
{
|
||||
|
|
@ -118,12 +114,10 @@ namespace test{
|
|||
++check;
|
||||
++ii;
|
||||
}
|
||||
|
||||
|
||||
// Test the const iterator
|
||||
check = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////TODO test code
|
||||
cout << showSizeof<VectD::Tupe> () << endl;
|
||||
///////////////////////////////////////////////////////////////////TODO test code
|
||||
|
||||
VectD::const_iterator cii = holder.begin();
|
||||
while (cii)
|
||||
{
|
||||
|
|
@ -131,6 +125,20 @@ namespace test{
|
|||
++check;
|
||||
++cii;
|
||||
}
|
||||
|
||||
|
||||
// Verify correct behaviour of iteration end
|
||||
ASSERT (! (holder.end()));
|
||||
ASSERT (isnil (holder.end()));
|
||||
|
||||
VERIFY_ERROR (ITER_EXHAUST, *holder.end() );
|
||||
VERIFY_ERROR (ITER_EXHAUST, ++holder.end() );
|
||||
|
||||
ASSERT (ii == holder.end());
|
||||
ASSERT (cii == holder.end());
|
||||
VERIFY_ERROR (ITER_EXHAUST, ++ii );
|
||||
VERIFY_ERROR (ITER_EXHAUST, ++cii );
|
||||
|
||||
}
|
||||
ASSERT (0==checksum);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue