// (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 any_iterator_wrapper
// 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
#include
#include
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 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::type,
UsedAsBaseForTraversal,
typename make_iterator_reference_const::type,
Difference
> const_clone_type_with_const_value_type;
typedef any_iterator_wrapper<
WrappedIterator,
typename boost::remove_const::type,
UsedAsBaseForTraversal,
typename make_iterator_reference_const::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(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(&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(&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