add any_terator
This commit is contained in:
parent
9730da4805
commit
43c117e400
422
share/any_iterator/any_iterator.hpp
Normal file
422
share/any_iterator/any_iterator.hpp
Normal file
@ -0,0 +1,422 @@
|
||||
// (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
|
||||
|
||||
#ifndef ANY_ITERATOR_01102007TMB_HPP
|
||||
#define ANY_ITERATOR_01102007TMB_HPP
|
||||
|
||||
// Includes
|
||||
// ========
|
||||
|
||||
#include "detail/any_iterator_abstract_base.hpp"
|
||||
#include "detail/any_iterator_wrapper.hpp"
|
||||
#include "detail/any_iterator_metafunctions.hpp"
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace IteratorTypeErasure
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The any_iterator is modeled after the "type erasure pattern" as set
|
||||
// forth in boost::any. The class names correspond as follows:
|
||||
//
|
||||
// boost::any ==> any_iterator
|
||||
// boost::any::placeholder ==> any_iterator_abstract_base
|
||||
// boost::any::holder ==> any_iterator_wrapper
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class CategoryOrTraversal,
|
||||
class Reference = Value&,
|
||||
class Difference = std::ptrdiff_t
|
||||
>
|
||||
class any_iterator :
|
||||
public boost::iterator_facade<
|
||||
any_iterator<
|
||||
Value,
|
||||
CategoryOrTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
>,
|
||||
Value,
|
||||
CategoryOrTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
>
|
||||
{
|
||||
|
||||
// We make every other any_iterator our friend. This is needed only for
|
||||
// the conversion from non-const to const, but there should be no harm
|
||||
// in being overly friendly here.
|
||||
template<
|
||||
class OtherValue,
|
||||
class OtherCategoryOrTraversal,
|
||||
class OtherReference,
|
||||
class OtherDifference
|
||||
>
|
||||
friend class any_iterator;
|
||||
|
||||
public:
|
||||
typedef typename boost::iterator_category_to_traversal<CategoryOrTraversal>::type Traversal;
|
||||
|
||||
private:
|
||||
|
||||
struct enabler{}; // a private type avoids misuse
|
||||
struct disabler{}; // a private type avoids misuse
|
||||
|
||||
// The type-erasing abstract base class, that is, the type that the
|
||||
// impl-pointer points to.
|
||||
typedef
|
||||
detail::any_iterator_abstract_base<
|
||||
Value,
|
||||
Traversal,
|
||||
Reference,
|
||||
Difference
|
||||
> abstract_base_type;
|
||||
|
||||
typedef
|
||||
boost::iterator_facade<
|
||||
any_iterator<
|
||||
Value,
|
||||
CategoryOrTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
>,
|
||||
Value,
|
||||
CategoryOrTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
> super_type;
|
||||
|
||||
// The two types that this any_iterator type recognizes as const versions of
|
||||
// itself.
|
||||
typedef any_iterator<
|
||||
typename boost::add_const<Value>::type,
|
||||
CategoryOrTraversal,
|
||||
typename detail::make_iterator_reference_const<Reference>::type,
|
||||
Difference
|
||||
> const_type_with_const_value_type;
|
||||
//
|
||||
typedef any_iterator<
|
||||
typename boost::remove_const<Value>::type,
|
||||
CategoryOrTraversal,
|
||||
typename detail::make_iterator_reference_const<Reference>::type,
|
||||
Difference
|
||||
> const_type_with_non_const_value_type;
|
||||
|
||||
public:
|
||||
|
||||
any_iterator() : m_pointer_to_impl(NULL)
|
||||
{}
|
||||
|
||||
any_iterator(any_iterator const & rhs) : super_type(rhs)
|
||||
{
|
||||
if( rhs.m_pointer_to_impl )
|
||||
{
|
||||
m_pointer_to_impl = rhs.m_pointer_to_impl->clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pointer_to_impl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
any_iterator& operator=(any_iterator const & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
any_iterator tmp(rhs);
|
||||
swap(tmp);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Constructor from wrapped iterator. The static assert defines the
|
||||
// granularity of the type erasure.
|
||||
//
|
||||
// NOTE 1: If you want to make the constructor non-explicit, then you
|
||||
// really must replace the static assert with an enable_if, or else
|
||||
// metafunctions such as is_convertible will say the wrong thing.
|
||||
// However, if you use enable_if here, you'll descend into the ugly
|
||||
// mess described in the last section of my article at
|
||||
// http://www.artima.com/cppsource/type_erasure.html.
|
||||
//
|
||||
// NOTE 2: If you remove the restriction that the wrapped iterator
|
||||
// cannot be an any_iterator, you must ensure that the conversions from
|
||||
// non-const to const any_iterators still work correctly. If you don't
|
||||
// do anything, you will end up with wrapping instead of conversion.
|
||||
//
|
||||
template<class WrappedIterator>
|
||||
explicit any_iterator(
|
||||
WrappedIterator const & wrapped_iterator,
|
||||
typename boost::disable_if<
|
||||
detail::is_any_iterator<WrappedIterator>,
|
||||
disabler
|
||||
>::type = disabler()
|
||||
)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If this static assert fires, you are trying to construct the any_iterator
|
||||
// from a concrete iterator that is not suitable for the type erasure that
|
||||
// the any_iterator provides.
|
||||
//
|
||||
BOOST_STATIC_ASSERT((detail::is_iterator_type_erasure_compatible<WrappedIterator, any_iterator>::type::value));
|
||||
|
||||
typedef
|
||||
detail::any_iterator_wrapper<
|
||||
WrappedIterator,
|
||||
Value,
|
||||
Traversal,
|
||||
Reference,
|
||||
Difference
|
||||
> wrapper_type;
|
||||
|
||||
m_pointer_to_impl = wrapper_type::create(wrapped_iterator);
|
||||
}
|
||||
|
||||
// Assignment from wrapped iterator. The enable_if condition defines
|
||||
// the granularity of the type erasure.
|
||||
//
|
||||
// NOTE: If you remove the restriction that the wrapped iterator
|
||||
// cannot be an any_iterator, you must ensure that the conversions from
|
||||
// non-const to const any_iterators still work correctly. If you don't
|
||||
// do anything, you will end up with wrapping instead of conversion.
|
||||
template<class WrappedIterator>
|
||||
typename boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
detail::is_iterator_type_erasure_compatible<WrappedIterator, any_iterator>,
|
||||
boost::mpl::not_<detail::is_any_iterator<WrappedIterator> >
|
||||
>,
|
||||
any_iterator
|
||||
>::type &
|
||||
operator=(WrappedIterator const & wrapped_iterator)
|
||||
{
|
||||
any_iterator tmp(wrapped_iterator);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Conversion from non-const to const any_iterator. There are two versions.
|
||||
// This first one applies if the target has const value type.
|
||||
operator const_type_with_const_value_type () const
|
||||
{
|
||||
const_type_with_const_value_type conversion_result;
|
||||
if( m_pointer_to_impl )
|
||||
{
|
||||
conversion_result.m_pointer_to_impl = m_pointer_to_impl->make_const_clone_with_const_value_type();
|
||||
}
|
||||
return conversion_result;
|
||||
}
|
||||
|
||||
// Conversion from non-const to const any_iterator. There are two versions.
|
||||
// This second one applies if the target has non-const value type.
|
||||
operator const_type_with_non_const_value_type () const
|
||||
{
|
||||
const_type_with_non_const_value_type conversion_result;
|
||||
if( m_pointer_to_impl )
|
||||
{
|
||||
conversion_result.m_pointer_to_impl = m_pointer_to_impl->make_const_clone_with_non_const_value_type();
|
||||
}
|
||||
return conversion_result;
|
||||
}
|
||||
|
||||
// Conversion to weaker traversal type
|
||||
template<typename TargetTraversal>
|
||||
operator any_iterator<
|
||||
Value,
|
||||
TargetTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
>
|
||||
() const
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If this static assert fires, you are trying to convert between two
|
||||
// any_iterator types that are not suitable for conversion.
|
||||
//
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_base_of<
|
||||
typename boost::iterator_category_to_traversal<TargetTraversal>::type,
|
||||
typename boost::iterator_category_to_traversal<CategoryOrTraversal>::type
|
||||
>::type::value
|
||||
));
|
||||
|
||||
any_iterator<
|
||||
Value,
|
||||
TargetTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
> conversion_result;
|
||||
|
||||
if( m_pointer_to_impl )
|
||||
{
|
||||
typename boost::iterator_category_to_traversal<TargetTraversal>::type* funcSelector = NULL;
|
||||
conversion_result.m_pointer_to_impl = make_traversal_converted_version(funcSelector);
|
||||
}
|
||||
return conversion_result;
|
||||
}
|
||||
|
||||
~any_iterator()
|
||||
{
|
||||
delete m_pointer_to_impl;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
Reference dereference() const
|
||||
{
|
||||
return m_pointer_to_impl->dereference();
|
||||
}
|
||||
|
||||
bool equal(any_iterator const & rhs) const
|
||||
{
|
||||
if( m_pointer_to_impl == rhs.m_pointer_to_impl )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( m_pointer_to_impl == NULL || rhs.m_pointer_to_impl == NULL )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If the next line does not compile, you are trying to compare
|
||||
// two iterators for equality whose categories do not allow that
|
||||
// comparison.
|
||||
return m_pointer_to_impl->equal(*(rhs.m_pointer_to_impl));
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
m_pointer_to_impl->increment();
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If the next line does not compile, you are trying to decrement
|
||||
// an iterator whose category does not allow decrementing.
|
||||
return m_pointer_to_impl->decrement();
|
||||
}
|
||||
|
||||
void advance(Difference n)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If the next line does not compile, you are trying to use an
|
||||
// operation that is defined only for random access iterators
|
||||
// on an iterator that is not random access.
|
||||
m_pointer_to_impl->advance(n);
|
||||
}
|
||||
|
||||
Difference distance_to(any_iterator const & other) const
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// *** Message to Client ***
|
||||
//
|
||||
// If the next line does not compile, you are trying to use an
|
||||
// operation that is defined only for random access iterators
|
||||
// on an iterator that is not random access.
|
||||
return m_pointer_to_impl->distance_to(*(other.m_pointer_to_impl));
|
||||
}
|
||||
|
||||
any_iterator& swap(any_iterator& other)
|
||||
{
|
||||
// NOTE: iterator_facade doesn't have a swap method, so no call
|
||||
// to base class here.
|
||||
std::swap(m_pointer_to_impl, other.m_pointer_to_impl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
detail::any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::incrementable_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_traversal_converted_version(boost::incrementable_traversal_tag* funcSelector) const
|
||||
{
|
||||
return m_pointer_to_impl->make_incrementable_version();
|
||||
}
|
||||
|
||||
detail::any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::single_pass_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_traversal_converted_version(boost::single_pass_traversal_tag* funcSelector) const
|
||||
{
|
||||
return m_pointer_to_impl->make_single_pass_version();
|
||||
}
|
||||
|
||||
detail::any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::forward_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_traversal_converted_version(boost::forward_traversal_tag* funcSelector) const
|
||||
{
|
||||
return m_pointer_to_impl->make_forward_version();
|
||||
}
|
||||
|
||||
detail::any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::bidirectional_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_traversal_converted_version(boost::bidirectional_traversal_tag* funcSelector) const
|
||||
{
|
||||
return m_pointer_to_impl->make_bidirectional_version();
|
||||
}
|
||||
|
||||
abstract_base_type* m_pointer_to_impl;
|
||||
|
||||
};
|
||||
|
||||
// Metafunction that takes an iterator and returns an any_iterator with the same
|
||||
// traits.
|
||||
template<class iterator>
|
||||
struct make_any_iterator_type
|
||||
{
|
||||
typedef
|
||||
any_iterator<
|
||||
typename boost::iterator_value<iterator>::type,
|
||||
typename boost::iterator_category<iterator>::type,
|
||||
typename boost::iterator_reference<iterator>::type,
|
||||
typename boost::iterator_difference<iterator>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
} // end namespace IteratorTypeErasure
|
||||
|
||||
#endif // ANY_ITERATOR_01102007TMB_HPP
|
||||
255
share/any_iterator/detail/any_iterator_abstract_base.hpp
Normal file
255
share/any_iterator/detail/any_iterator_abstract_base.hpp
Normal file
@ -0,0 +1,255 @@
|
||||
// (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
|
||||
|
||||
#ifndef ANY_ITERATOR_ABSTRACT_BASE_01102007TMB_HPP
|
||||
#define ANY_ITERATOR_ABSTRACT_BASE_01102007TMB_HPP
|
||||
|
||||
// Includes
|
||||
// ========
|
||||
|
||||
#include "any_iterator_metafunctions.hpp"
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
namespace IteratorTypeErasure
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The partial specializations of any_iterator_abstract_base (which is
|
||||
// the equivalent of boost::any::placeholder) 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 Value,
|
||||
class Traversal,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal = Traversal
|
||||
>
|
||||
class any_iterator_abstract_base;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal
|
||||
>
|
||||
class any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::incrementable_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
>
|
||||
{
|
||||
|
||||
protected:
|
||||
typedef any_iterator_abstract_base<
|
||||
Value,
|
||||
UsedAsBaseForTraversal,
|
||||
Reference,
|
||||
Difference
|
||||
> most_derived_type;
|
||||
|
||||
typedef most_derived_type clone_result_type;
|
||||
|
||||
typedef any_iterator_abstract_base<
|
||||
typename boost::add_const<Value>::type,
|
||||
UsedAsBaseForTraversal,
|
||||
typename make_iterator_reference_const<Reference>::type,
|
||||
Difference
|
||||
> const_clone_with_const_value_type_result_type;
|
||||
|
||||
typedef any_iterator_abstract_base<
|
||||
typename boost::remove_const<Value>::type,
|
||||
UsedAsBaseForTraversal,
|
||||
typename make_iterator_reference_const<Reference>::type,
|
||||
Difference
|
||||
> const_clone_with_non_const_value_type_result_type;
|
||||
|
||||
public:
|
||||
|
||||
// Plain clone function for copy construction and assignment.
|
||||
virtual clone_result_type * clone() const=0;
|
||||
|
||||
// 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=0;
|
||||
virtual const_clone_with_non_const_value_type_result_type * make_const_clone_with_non_const_value_type() const=0;
|
||||
|
||||
// gcc 3.4.2 does not like pure virtual declaration with inline definition,
|
||||
// so I make the destructor non-pure just to spite them.
|
||||
virtual ~any_iterator_abstract_base()
|
||||
{}
|
||||
|
||||
virtual Reference dereference() const=0;
|
||||
virtual void increment() = 0;
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal
|
||||
>
|
||||
class any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::single_pass_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
> : public any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::incrementable_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// gcc 3.4.2 insists on qualification of most_derived_type.
|
||||
virtual bool equal(typename any_iterator_abstract_base::most_derived_type const &) const = 0;
|
||||
|
||||
virtual any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::incrementable_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_incrementable_version() const=0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal
|
||||
>
|
||||
class any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::forward_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
> : public any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::single_pass_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
>
|
||||
{
|
||||
public:
|
||||
virtual any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::single_pass_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_single_pass_version() const=0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal
|
||||
>
|
||||
class any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::bidirectional_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
> : public any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::forward_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void decrement() = 0;
|
||||
|
||||
virtual any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::forward_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_forward_version() const=0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Reference,
|
||||
class Difference,
|
||||
class UsedAsBaseForTraversal
|
||||
>
|
||||
class any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::random_access_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
> : public any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::bidirectional_traversal_tag,
|
||||
Reference,
|
||||
Difference,
|
||||
UsedAsBaseForTraversal
|
||||
>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void advance(Difference) = 0;
|
||||
|
||||
// gcc 3.4.2 insists on qualification of most_derived_type.
|
||||
virtual Difference distance_to(typename any_iterator_abstract_base::most_derived_type const &) const= 0;
|
||||
|
||||
virtual any_iterator_abstract_base<
|
||||
Value,
|
||||
boost::bidirectional_traversal_tag,
|
||||
Reference,
|
||||
Difference
|
||||
>* make_bidirectional_version() const=0;
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
} // end namespace IteratorTypeErasure
|
||||
|
||||
#endif // ANY_ITERATOR_ABSTRACT_BASE_01102007TMB_HPP
|
||||
363
share/any_iterator/detail/any_iterator_metafunctions.hpp
Normal file
363
share/any_iterator/detail/any_iterator_metafunctions.hpp
Normal file
@ -0,0 +1,363 @@
|
||||
// (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.
|
||||
|
||||
// File Name
|
||||
// =========
|
||||
//
|
||||
// metafunctions.h
|
||||
|
||||
// Description
|
||||
// ===========
|
||||
//
|
||||
// Metafunctions for any_iterator
|
||||
|
||||
#ifndef ANY_ITERATOR_METAFUNCTIONS_01102007TMB_HPP
|
||||
#define ANY_ITERATOR_METAFUNCTIONS_01102007TMB_HPP
|
||||
|
||||
// Revision History
|
||||
// ================
|
||||
//
|
||||
// 27 Dec 2006 (Thomas Becker) Created
|
||||
|
||||
// Includes
|
||||
// ========
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
namespace IteratorTypeErasure
|
||||
{
|
||||
|
||||
template<
|
||||
class Value,
|
||||
class Traversal,
|
||||
class Reference,
|
||||
class Difference
|
||||
>
|
||||
class any_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename T>
|
||||
struct remove_reference_and_const
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::remove_const<
|
||||
T
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename IteratorReference>
|
||||
struct make_iterator_reference_const
|
||||
{
|
||||
typedef typename boost::mpl::if_<
|
||||
typename boost::is_reference<IteratorReference>::type,
|
||||
typename boost::remove_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::remove_const<
|
||||
IteratorReference
|
||||
>::type
|
||||
>::type
|
||||
>::type const &,
|
||||
typename boost::remove_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::remove_const<
|
||||
IteratorReference
|
||||
>::type
|
||||
>::type
|
||||
>::type const
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct value_types_erasure_compatible
|
||||
{
|
||||
// Really, we just want WrappedIterator's value_type to convert to
|
||||
// AnyIterator's value_type. But many real world output iterators
|
||||
// define their value_type as void. Therefore, we simply ignore
|
||||
// the value type for output iterators. That's fine because for
|
||||
// output iterators, the relevant type erasure information is all
|
||||
// in the reference type.
|
||||
|
||||
typedef typename boost::mpl::or_<
|
||||
boost::is_same<
|
||||
typename boost::iterator_category<WrappedIterator>::type,
|
||||
std::output_iterator_tag
|
||||
>,
|
||||
|
||||
// Really, we just want WrappedIterator's value_type to convert to
|
||||
// AnyIterator's value_type. But we need to work around a flaw in
|
||||
// boost::is_convertible. boost::is_convertible<X, Y>::value is
|
||||
// false whenever X and Y are abstract base classes (even when X
|
||||
// and Y are the same). This will be fixed in C++ concepts.
|
||||
boost::mpl::or_<
|
||||
boost::is_same<
|
||||
typename boost::iterator_value<WrappedIterator>::type,
|
||||
typename boost::iterator_value<AnyIterator>::type
|
||||
>,
|
||||
boost::is_base_of<
|
||||
typename boost::iterator_value<AnyIterator>::type,
|
||||
typename boost::iterator_value<WrappedIterator>::type
|
||||
>,
|
||||
boost::is_convertible<
|
||||
typename boost::iterator_value<WrappedIterator>::type,
|
||||
typename boost::iterator_value<AnyIterator>::type
|
||||
>
|
||||
>
|
||||
> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct reference_types_erasure_compatible_1
|
||||
{
|
||||
typedef typename boost::is_convertible<
|
||||
typename boost::iterator_reference<WrappedIterator>::type,
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct reference_types_erasure_compatible_2
|
||||
{
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_reference<
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>,
|
||||
boost::is_reference<
|
||||
typename boost::iterator_reference<WrappedIterator>::type
|
||||
>,
|
||||
boost::mpl::bool_<true>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct reference_types_erasure_compatible_3
|
||||
{
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::mpl::and_<
|
||||
boost::is_reference<
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>,
|
||||
boost::is_reference<
|
||||
typename boost::iterator_reference<WrappedIterator>::type
|
||||
>
|
||||
>,
|
||||
boost::mpl::or_<
|
||||
boost::is_same<
|
||||
typename remove_reference_and_const<
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>::type,
|
||||
typename remove_reference_and_const<
|
||||
typename boost::iterator_reference<WrappedIterator>::type
|
||||
>::type
|
||||
>,
|
||||
boost::is_base_of<
|
||||
typename remove_reference_and_const<
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>::type,
|
||||
typename remove_reference_and_const<
|
||||
typename boost::iterator_reference<WrappedIterator>::type
|
||||
>::type
|
||||
>
|
||||
>,
|
||||
boost::mpl::bool_<true>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct reference_types_erasure_compatible
|
||||
{
|
||||
// Output iterators are weird. Many real world output iterators
|
||||
// define their reference type as void. In the world of boost
|
||||
// iterators, that's terribly wrong, because in that world, an
|
||||
// iterator's reference type is always the result type of
|
||||
// operator* (and that makes very good sense, too). Therefore,
|
||||
// when WrappedIterator is an output iterator, we use
|
||||
// WrappedIterator& for WrappedIterator's reference type,
|
||||
// because that's the real, true reference type. Moreover,
|
||||
// we just require that WrappedIterator& convert to AnyIterator's
|
||||
// reference type. The other subtleties are not relevant.
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_same<
|
||||
typename boost::iterator_category<WrappedIterator>::type,
|
||||
std::output_iterator_tag
|
||||
>,
|
||||
boost::is_convertible<
|
||||
WrappedIterator&,
|
||||
typename boost::iterator_reference<AnyIterator>::type
|
||||
>,
|
||||
boost::mpl::and_<
|
||||
|
||||
// WrappedIterator's reference type must convert to AnyIterator's reference type.
|
||||
typename reference_types_erasure_compatible_1<WrappedIterator, AnyIterator>::type,
|
||||
|
||||
// If AnyIterator's reference type is a reference, then the
|
||||
// same must be true for WrappedIterator's reference type.
|
||||
typename reference_types_erasure_compatible_2<WrappedIterator, AnyIterator>::type,
|
||||
|
||||
// If AnyIterator's reference type and WrappedIterator's
|
||||
// reference type are both references, then one of the
|
||||
// following must hold:
|
||||
//
|
||||
// 1) AnyIterator's reference type and WrappedIterator's
|
||||
// reference type are the same.
|
||||
//
|
||||
// 2) AnyIterator's reference type is a base class of WrappedIterator's
|
||||
// reference type.
|
||||
//
|
||||
typename reference_types_erasure_compatible_3<WrappedIterator, AnyIterator>::type
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct difference_types_erasure_compatible
|
||||
{
|
||||
|
||||
// Difference type matters only for random access iterators.
|
||||
|
||||
typedef typename boost::mpl::or_<
|
||||
boost::mpl::not_<
|
||||
boost::is_same<
|
||||
// Do not use boost::iterator_traversal<AnyIterator>::type here,
|
||||
// as it does not equal the traversal tag.
|
||||
typename AnyIterator::Traversal,
|
||||
boost::random_access_traversal_tag
|
||||
>
|
||||
>,
|
||||
boost::mpl::and_<
|
||||
boost::is_convertible<
|
||||
typename boost::iterator_difference<WrappedIterator>::type,
|
||||
typename boost::iterator_difference<AnyIterator>::type
|
||||
>,
|
||||
boost::is_convertible<
|
||||
typename boost::iterator_difference<AnyIterator>::type,
|
||||
typename boost::iterator_difference<WrappedIterator>::type
|
||||
>
|
||||
>
|
||||
> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct traversal_types_erasure_compatible
|
||||
{
|
||||
typedef typename boost::mpl::or_<
|
||||
boost::is_same<
|
||||
// Do not use boost::iterator_traversal<AnyIterator>::type here,
|
||||
// as it does not equal the traversal tag.
|
||||
typename AnyIterator::Traversal,
|
||||
typename boost::iterator_traversal<WrappedIterator>::type
|
||||
>,
|
||||
boost::is_base_of<
|
||||
// Do not use boost::iterator_traversal<AnyIterator>::type here,
|
||||
// as it does not equal the traversal tag.
|
||||
typename AnyIterator::Traversal,
|
||||
typename boost::iterator_traversal<WrappedIterator>::type
|
||||
>
|
||||
> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<
|
||||
class WrappedIterator,
|
||||
class AnyIterator
|
||||
>
|
||||
struct is_iterator_type_erasure_compatible :
|
||||
public boost::mpl::bool_<
|
||||
boost::mpl::and_<
|
||||
value_types_erasure_compatible<WrappedIterator, AnyIterator>,
|
||||
reference_types_erasure_compatible<WrappedIterator, AnyIterator>,
|
||||
difference_types_erasure_compatible<WrappedIterator, AnyIterator>,
|
||||
traversal_types_erasure_compatible<WrappedIterator, AnyIterator>
|
||||
>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<class SomeIterator>
|
||||
struct is_any_iterator : public boost::mpl::bool_<false>
|
||||
{
|
||||
};
|
||||
//
|
||||
template<
|
||||
class Value,
|
||||
class Traversal,
|
||||
class Reference,
|
||||
class Difference
|
||||
>
|
||||
struct is_any_iterator<
|
||||
any_iterator<
|
||||
Value,
|
||||
Traversal,
|
||||
Reference,
|
||||
Difference
|
||||
>
|
||||
> : public boost::mpl::bool_<true>
|
||||
{
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
} // end namespace IteratorTypeErasure
|
||||
|
||||
#endif // ANY_ITERATOR_METAFUNCTIONS_01102007TMB_HPP
|
||||
443
share/any_iterator/detail/any_iterator_wrapper.hpp
Normal file
443
share/any_iterator/detail/any_iterator_wrapper.hpp
Normal file
@ -0,0 +1,443 @@
|
||||
// (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
|
||||
Loading…
Reference in New Issue
Block a user