444 lines
12 KiB
C++
444 lines
12 KiB
C++
// (C) Copyright Thomas Becker 2005. Permission to copy, use, modify, sell and
|
|
// distribute this software is granted provided this copyright notice appears
|
|
// in all copies. This software is provided "as is" without express or implied
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
// Revision History
|
|
// ================
|
|
//
|
|
// 27 Dec 2006 (Thomas Becker) Created
|
|
// 12 Jul 2010 (Thomas Becker acting on bug report by Edgar Binder)
|
|
// Bug fix: Constructors and create function of <code>any_iterator_wrapper</code>
|
|
// from wrapped iterator must take their argument by const reference (performance!).
|
|
|
|
#ifndef ANY_ITERATOR_WRAPPER_01102007TMB_HPP
|
|
#define ANY_ITERATOR_WRAPPER_01102007TMB_HPP
|
|
|
|
// Includes
|
|
// ========
|
|
|
|
#include "any_iterator_abstract_base.hpp"
|
|
#include "any_iterator_metafunctions.hpp"
|
|
#include <boost/type_traits/add_const.hpp>
|
|
#include <boost/type_traits/remove_const.hpp>
|
|
#include <boost/cast.hpp>
|
|
|
|
namespace IteratorTypeErasure
|
|
{
|
|
|
|
namespace detail
|
|
{
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
// The partial specializations of any_iterator_wrapper (which is the
|
|
// the equivalent of boost::any::holder) mirror the hierarchy of
|
|
// boost's iterator traversal tags.
|
|
//
|
|
// The first four template arguments are as in boost::iterator_facade.
|
|
// The last template argument is the traversal tag of the most
|
|
// derived class of the current instantiation of the hierarchy. This
|
|
// is a slight variant of the CRTP where the derived class passes
|
|
// itself as a template argument to the base class(es). Here, it seemed
|
|
// more convenient to pass up just the traversal tag of the most
|
|
// derived class.
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Traversal,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal = Traversal
|
|
>
|
|
class any_iterator_wrapper;
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal
|
|
>
|
|
class any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::incrementable_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> : public any_iterator_abstract_base<
|
|
Value,
|
|
UsedAsBaseForTraversal,
|
|
Reference,
|
|
Difference
|
|
>
|
|
{
|
|
|
|
protected:
|
|
typedef any_iterator_abstract_base<Value, UsedAsBaseForTraversal, Reference, Difference> abstract_base_type;
|
|
|
|
private:
|
|
typedef typename abstract_base_type::clone_result_type clone_result_type;
|
|
typedef typename abstract_base_type::const_clone_with_const_value_type_result_type const_clone_with_const_value_type_result_type;
|
|
typedef typename abstract_base_type::const_clone_with_non_const_value_type_result_type const_clone_with_non_const_value_type_result_type;
|
|
|
|
typedef any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
UsedAsBaseForTraversal,
|
|
Reference,
|
|
Difference
|
|
> clone_type;
|
|
|
|
typedef any_iterator_wrapper<
|
|
WrappedIterator,
|
|
typename boost::add_const<Value>::type,
|
|
UsedAsBaseForTraversal,
|
|
typename make_iterator_reference_const<Reference>::type,
|
|
Difference
|
|
> const_clone_type_with_const_value_type;
|
|
|
|
typedef any_iterator_wrapper<
|
|
WrappedIterator,
|
|
typename boost::remove_const<Value>::type,
|
|
UsedAsBaseForTraversal,
|
|
typename make_iterator_reference_const<Reference>::type,
|
|
Difference
|
|
> const_clone_type_with_non_const_value_type;
|
|
|
|
public:
|
|
|
|
any_iterator_wrapper()
|
|
{}
|
|
|
|
any_iterator_wrapper(WrappedIterator const& wrapped_iterator) :
|
|
m_wrapped_iterator(wrapped_iterator)
|
|
{}
|
|
|
|
static abstract_base_type* create(WrappedIterator const& wrapped_iterator)
|
|
{
|
|
return new clone_type(wrapped_iterator);
|
|
}
|
|
|
|
// Plain clone function for copy construction and assignment.
|
|
virtual clone_result_type * clone() const
|
|
{
|
|
return new clone_type(m_wrapped_iterator);
|
|
}
|
|
|
|
// Clone functions for conversion to a const iterator
|
|
virtual const_clone_with_const_value_type_result_type* make_const_clone_with_const_value_type() const
|
|
{
|
|
return new const_clone_type_with_const_value_type(m_wrapped_iterator);
|
|
}
|
|
//
|
|
virtual const_clone_with_non_const_value_type_result_type* make_const_clone_with_non_const_value_type() const
|
|
{
|
|
return new const_clone_type_with_non_const_value_type(m_wrapped_iterator);
|
|
}
|
|
|
|
virtual Reference dereference() const
|
|
{
|
|
// This const cast is needed for output iterators. Is this perhaps an oversight
|
|
// in iterator_facade?
|
|
return *const_cast<any_iterator_wrapper*>(this)->m_wrapped_iterator;
|
|
}
|
|
|
|
virtual void increment()
|
|
{
|
|
++m_wrapped_iterator;
|
|
}
|
|
|
|
protected:
|
|
|
|
WrappedIterator& get_wrapped_iterator()
|
|
{
|
|
return m_wrapped_iterator;
|
|
}
|
|
|
|
WrappedIterator const & get_wrapped_iterator() const
|
|
{
|
|
return m_wrapped_iterator;
|
|
}
|
|
|
|
private:
|
|
|
|
WrappedIterator m_wrapped_iterator;
|
|
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal
|
|
>
|
|
class any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::single_pass_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> : public any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::incrementable_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
>
|
|
{
|
|
|
|
public:
|
|
|
|
typedef
|
|
any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::incrementable_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> super_type;
|
|
|
|
any_iterator_wrapper()
|
|
{}
|
|
|
|
any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator)
|
|
{}
|
|
|
|
// gcc 3.4.2 insists on qualification of abstract_base_type.
|
|
virtual bool equal(typename any_iterator_wrapper::abstract_base_type const & rhs) const
|
|
{
|
|
return this->get_wrapped_iterator() == boost::polymorphic_downcast<any_iterator_wrapper const *>(&rhs)->get_wrapped_iterator();
|
|
}
|
|
|
|
any_iterator_abstract_base<
|
|
Value,
|
|
boost::incrementable_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>* make_incrementable_version() const
|
|
{
|
|
return new any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::incrementable_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>(this->get_wrapped_iterator());
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal
|
|
>
|
|
class any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::forward_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> : public any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::single_pass_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
>
|
|
{
|
|
|
|
public:
|
|
|
|
typedef
|
|
any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::single_pass_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> super_type;
|
|
|
|
any_iterator_wrapper()
|
|
{}
|
|
|
|
any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator)
|
|
{}
|
|
|
|
any_iterator_abstract_base<
|
|
Value,
|
|
boost::single_pass_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>* make_single_pass_version() const
|
|
{
|
|
return new any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::single_pass_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>(this->get_wrapped_iterator());
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal
|
|
>
|
|
class any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::bidirectional_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> : public any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::forward_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
>
|
|
{
|
|
|
|
public:
|
|
|
|
typedef
|
|
any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::forward_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> super_type;
|
|
|
|
any_iterator_wrapper()
|
|
{}
|
|
|
|
any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator)
|
|
{}
|
|
|
|
virtual void decrement()
|
|
{
|
|
--(this->get_wrapped_iterator());
|
|
}
|
|
|
|
any_iterator_abstract_base<
|
|
Value,
|
|
boost::forward_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>* make_forward_version() const
|
|
{
|
|
return new any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::forward_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>(this->get_wrapped_iterator());
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
template<
|
|
class WrappedIterator,
|
|
class Value,
|
|
class Reference,
|
|
class Difference,
|
|
class UsedAsBaseForTraversal
|
|
>
|
|
class any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::random_access_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> : public any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::bidirectional_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
>
|
|
{
|
|
|
|
public:
|
|
|
|
typedef
|
|
any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::bidirectional_traversal_tag,
|
|
Reference,
|
|
Difference,
|
|
UsedAsBaseForTraversal
|
|
> super_type;
|
|
|
|
any_iterator_wrapper()
|
|
{}
|
|
|
|
any_iterator_wrapper(WrappedIterator const& wrapped_iterator) : super_type(wrapped_iterator)
|
|
{}
|
|
|
|
virtual void advance(Difference n)
|
|
{
|
|
this->get_wrapped_iterator() += n;
|
|
}
|
|
|
|
// gcc 3.4.2 insists on qualification of abstract_base_type.
|
|
virtual Difference distance_to(typename any_iterator_wrapper::abstract_base_type const & other) const
|
|
{
|
|
return boost::polymorphic_downcast<any_iterator_wrapper const *>(&other)->get_wrapped_iterator() - this->get_wrapped_iterator();
|
|
}
|
|
|
|
any_iterator_abstract_base<
|
|
Value,
|
|
boost::bidirectional_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>* make_bidirectional_version() const
|
|
{
|
|
return new any_iterator_wrapper<
|
|
WrappedIterator,
|
|
Value,
|
|
boost::bidirectional_traversal_tag,
|
|
Reference,
|
|
Difference
|
|
>(this->get_wrapped_iterator());
|
|
}
|
|
};
|
|
|
|
} // end namespace detail
|
|
|
|
} // end namespace IteratorTypeErasure
|
|
|
|
#endif // ANY_ITERATOR_WRAPPER_01102007TMB_HPP
|