forked from boostorg/iterator
Many changes from Oxford
[SVN r1137]
This commit is contained in:
Executable
+194
@@ -0,0 +1,194 @@
|
||||
// Copyright David Abrahams 2003. 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.
|
||||
#ifndef COUNTING_ITERATOR_DWA200348_HPP
|
||||
# define COUNTING_ITERATOR_DWA200348_HPP
|
||||
|
||||
# include <boost/iterator/iterator_adaptor.hpp>
|
||||
# include <boost/detail/numeric_traits.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Incrementable, class Category, class Difference> class counting_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Try to detect numeric types at compile time in ways compatible
|
||||
// with the limitations of the compiler and library.
|
||||
template <class T>
|
||||
struct is_numeric_impl
|
||||
{
|
||||
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||
|
||||
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
|
||||
# if defined(BOOST_HAS_LONG_LONG)
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
std::numeric_limits<T>::is_specialized
|
||||
| boost::is_same<T,long long>::value
|
||||
| boost::is_same<T,unsigned long long>::value
|
||||
));
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
# if !defined(__BORLANDC__)
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
boost::is_convertible<int,T>::value
|
||||
&& boost::is_convertible<T,int>::value
|
||||
));
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||
# endif
|
||||
|
||||
# endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_numeric
|
||||
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct numeric_difference
|
||||
{
|
||||
typedef typename boost::detail::numeric_traits<T>::difference_type type;
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||
template <class Incrementable, class Category, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
typedef typename mpl::apply_if<
|
||||
is_same<Category, not_specified>
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, mpl::identity<std::random_access_iterator_tag>
|
||||
, BOOST_ITERATOR_CATEGORY<Incrementable>
|
||||
>
|
||||
, mpl::identity<Category>
|
||||
>::type category;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
is_same<Difference, not_specified>
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, numeric_difference<Incrementable>
|
||||
, iterator_difference<Incrementable>
|
||||
>
|
||||
, mpl::identity<Difference>
|
||||
>::type difference;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
counting_iterator<Incrementable, Category, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // value_type
|
||||
, category
|
||||
, Incrementable const& // reference
|
||||
, Incrementable const* // pointer
|
||||
, difference
|
||||
> type;
|
||||
};
|
||||
|
||||
// Template class distance_policy_select -- choose a policy for computing the
|
||||
// distance between counting_iterators at compile-time based on whether or not
|
||||
// the iterator wraps an integer or an iterator, using "poor man's partial
|
||||
// specialization".
|
||||
|
||||
template <bool is_integer> struct distance_policy_select;
|
||||
|
||||
// A policy for wrapped iterators
|
||||
template <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct iterator_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return boost::detail::distance(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
// A policy for wrapped numbers
|
||||
template <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct number_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return numeric_distance(x, y);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class Incrementable, class Category = not_specified, class Difference = not_specified>
|
||||
class counting_iterator
|
||||
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
|
||||
{
|
||||
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
typedef typename super_t::difference_type difference_type;
|
||||
|
||||
counting_iterator() { }
|
||||
|
||||
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
|
||||
|
||||
counting_iterator(Incrementable x)
|
||||
: super_t(x)
|
||||
{
|
||||
}
|
||||
|
||||
# if 0
|
||||
template<class OtherIncrementable>
|
||||
counting_iterator(
|
||||
counting_iterator<OtherIncrementable> const& t
|
||||
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
|
||||
)
|
||||
: super_t(t.base())
|
||||
{}
|
||||
# endif
|
||||
|
||||
private:
|
||||
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
|
||||
template <class OtherIncrementable>
|
||||
difference_type
|
||||
distance_to(counting_iterator<OtherIncrementable> const& y) const
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
detail::is_numeric<Incrementable>
|
||||
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
>::type d;
|
||||
|
||||
return d::distance(this->base(), y.base());
|
||||
}
|
||||
};
|
||||
|
||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||
template <class Incrementable>
|
||||
inline counting_iterator<Incrementable>
|
||||
make_counting_iterator(Incrementable x)
|
||||
{
|
||||
typedef counting_iterator<Incrementable> result_t;
|
||||
return result_t(x);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost::iterator
|
||||
|
||||
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
||||
@@ -13,42 +13,98 @@
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// faked new old-style categories needed to make new->old mapping
|
||||
// work
|
||||
namespace detail
|
||||
{
|
||||
struct null_category_tag {};
|
||||
struct input_output_iterator_tag : std::input_iterator_tag, std::output_iterator_tag {};
|
||||
}
|
||||
|
||||
//
|
||||
// Access Categories
|
||||
//
|
||||
struct readable_iterator_tag
|
||||
{
|
||||
typedef std::input_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_iterator_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct swappable_iterator_tag
|
||||
{
|
||||
typedef detail::null_category_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_writable_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
, virtual writable_iterator_tag
|
||||
, virtual swappable_iterator_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_lvalue_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_lvalue_iterator_tag
|
||||
: virtual public readable_writable_iterator_tag
|
||||
, virtual public readable_lvalue_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
//
|
||||
// Categories
|
||||
//
|
||||
// !! Fix detection functions if categories
|
||||
// are changed.
|
||||
//
|
||||
|
||||
// Return Type Categories
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag :
|
||||
virtual public readable_iterator_tag, // Not sure about this change -JGS
|
||||
virtual public writable_iterator_tag { };
|
||||
struct constant_lvalue_iterator_tag :
|
||||
virtual public readable_iterator_tag { };
|
||||
struct mutable_lvalue_iterator_tag :
|
||||
virtual public swappable_iterator_tag,
|
||||
virtual public constant_lvalue_iterator_tag { };
|
||||
|
||||
// Traversal Categories
|
||||
struct input_traversal_tag { };
|
||||
struct output_traversal_tag { };
|
||||
struct forward_traversal_tag : virtual public input_traversal_tag,
|
||||
virtual public output_traversal_tag { };
|
||||
struct bidirectional_traversal_tag : virtual public forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : virtual public bidirectional_traversal_tag { };
|
||||
//
|
||||
struct incrementable_iterator_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct single_pass_iterator_tag
|
||||
: incrementable_iterator_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct forward_traversal_tag
|
||||
: single_pass_iterator_tag
|
||||
{
|
||||
typedef std::forward_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag
|
||||
{
|
||||
typedef std::bidirectional_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct error_iterator_tag { };
|
||||
|
||||
@@ -57,384 +113,162 @@ namespace boost {
|
||||
//
|
||||
// Tag detection meta functions
|
||||
//
|
||||
// Needed to work with compilers
|
||||
// without working is_convertible
|
||||
//
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Category>
|
||||
struct is_input_iterator :
|
||||
is_convertible<Category*, std::input_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_iterator :
|
||||
is_convertible<Category*, std::output_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_iterator :
|
||||
is_convertible<Category*, std::forward_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_iterator :
|
||||
is_convertible<Category*, std::bidirectional_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_iterator :
|
||||
is_convertible<Category*, std::random_access_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_readable_iterator :
|
||||
is_convertible<Category*, readable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_writable_iterator :
|
||||
is_convertible<Category*, writable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_swappable_iterator :
|
||||
is_convertible<Category*, swappable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_constant_lvalue_iterator :
|
||||
is_convertible<Category*, constant_lvalue_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_mutable_lvalue_iterator :
|
||||
is_convertible<Category*, mutable_lvalue_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_input_traversal_iterator :
|
||||
is_convertible<Category*, input_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_output_traversal_iterator :
|
||||
is_convertible<Category*, output_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_traversal_iterator :
|
||||
is_convertible<Category*, forward_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_traversal_iterator :
|
||||
is_convertible<Category*, bidirectional_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_traversal_iterator :
|
||||
is_convertible<Category*, random_access_traversal_tag*>
|
||||
{ };
|
||||
|
||||
#else
|
||||
//
|
||||
// We cannot detect the iterator category for custom
|
||||
// tag types. For custom tag types false_ is returned
|
||||
//
|
||||
// As a result the std iterator category detection functions
|
||||
// can't detect the iterator category of the new iterator_tag template.
|
||||
//
|
||||
|
||||
//
|
||||
// std iterator categories
|
||||
//
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_iterator :
|
||||
mpl::false_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_random_access_iterator<std::random_access_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_iterator :
|
||||
is_random_access_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_bidirectional_iterator<std::bidirectional_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_iterator :
|
||||
is_bidirectional_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_forward_iterator<std::forward_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_iterator :
|
||||
is_forward_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_output_iterator<std::output_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_input_iterator :
|
||||
is_forward_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_input_iterator<std::input_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
//
|
||||
// Return type
|
||||
//
|
||||
// The nested is_category template class are used for
|
||||
// minimum category detection in iterator_adaptors.
|
||||
// They are basically a poore mans is_derived replacement.
|
||||
//
|
||||
// A implementation may look like this
|
||||
//
|
||||
// template <class Cat1, class Cat2>
|
||||
// struct min_cat
|
||||
// : mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >,
|
||||
// Cat1,
|
||||
// mpl::if_< is_return_category<Cat2>::template is_category<Cat1>,
|
||||
// Cat2,
|
||||
// error_type
|
||||
// >
|
||||
// > {};
|
||||
|
||||
template <class Category>
|
||||
struct is_mutable_lvalue_iterator :
|
||||
mpl::false_
|
||||
{
|
||||
template <class T>
|
||||
struct is_category
|
||||
: boost::mpl::false_ {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_mutable_lvalue_iterator<mutable_lvalue_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_mutable_lvalue_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_constant_lvalue_iterator :
|
||||
is_mutable_lvalue_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_constant_lvalue_iterator<constant_lvalue_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_constant_lvalue_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_swappable_iterator :
|
||||
is_constant_lvalue_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_swappable_iterator<swappable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_swappable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_readable_iterator :
|
||||
mpl::if_< is_swappable_iterator<Category>,
|
||||
is_swappable_iterator<Category>,
|
||||
is_constant_lvalue_iterator<Category> >::type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator<readable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_readable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_writable_iterator :
|
||||
is_swappable_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_writable_iterator<writable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_writable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_return_category
|
||||
: mpl::if_< is_writable_iterator<Category>,
|
||||
is_writable_iterator<Category>,
|
||||
is_readable_iterator<Category> >::type
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// Traversal
|
||||
//
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_traversal_iterator :
|
||||
mpl::false_
|
||||
{
|
||||
template <class T>
|
||||
struct is_category
|
||||
: boost::mpl::false_ {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_random_access_traversal_iterator<random_access_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_random_access_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_traversal_iterator :
|
||||
is_random_access_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_bidirectional_traversal_iterator<bidirectional_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_bidirectional_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_traversal_iterator :
|
||||
is_bidirectional_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_forward_traversal_iterator<forward_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_forward_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_input_traversal_iterator :
|
||||
is_forward_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_input_traversal_iterator<input_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_input_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_traversal_iterator :
|
||||
is_forward_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_output_traversal_iterator<output_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_output_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_traversal_category
|
||||
: mpl::if_< is_input_traversal_iterator<Category>,
|
||||
is_input_traversal_iterator<Category>,
|
||||
is_output_traversal_iterator<Category> >::type
|
||||
{};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
// I bet this is defined somewhere else. Let's wait and see.
|
||||
//
|
||||
struct error_type;
|
||||
|
||||
#ifdef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Cat1, class Cat2>
|
||||
struct minimum_return_category
|
||||
: mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >,
|
||||
Cat1,
|
||||
mpl::if_< is_return_category<Cat2>::template is_category<Cat1>,
|
||||
Cat2,
|
||||
error_type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class Cat1, class Cat2>
|
||||
struct minimum_traversal_category
|
||||
: mpl::if_< is_traversal_category< Cat1 >::template is_category< Cat2 >,
|
||||
Cat1,
|
||||
mpl::if_< is_traversal_category<Cat2>::template is_category<Cat1>,
|
||||
Cat2,
|
||||
error_type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct minimum_category_select
|
||||
: mpl::if_< is_same< typename T1::type, error_type >,
|
||||
T2,
|
||||
T1 >
|
||||
{};
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Base, class Derived>
|
||||
struct is_base_or_same :
|
||||
mpl::or_< is_same< Base, Derived >,
|
||||
is_base_and_derived< Base, Derived > >
|
||||
struct is_same_or_derived
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
: mpl::or_<
|
||||
is_same<Base, Derived>
|
||||
, is_base_and_derived<Base, Derived>
|
||||
>
|
||||
{};
|
||||
# else
|
||||
: is_base_and_derived<Base, Derived>
|
||||
{};
|
||||
|
||||
template <class T> struct is_same_or_derived<T,T> : mpl::true_ {};
|
||||
# endif
|
||||
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: mpl::or_<
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
is_same_or_derived<Tag, T>
|
||||
# else
|
||||
is_base_and_derived<Tag, T>
|
||||
# endif
|
||||
|
||||
// Because we can't actually get forward_iterator_tag to
|
||||
// derive from input_output_iterator_tag, we need this
|
||||
// case.
|
||||
, mpl::and_<
|
||||
is_same_or_derived<Tag,detail::input_output_iterator_tag>
|
||||
, is_same_or_derived<std::forward_iterator_tag,T>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
#else
|
||||
template <class Tag, class T>
|
||||
struct is_tag;
|
||||
#endif
|
||||
|
||||
// Generate specializations which will allow us to find
|
||||
// null_category_tag as a minimum old-style category for new-style
|
||||
// iterators which don't have an actual old-style category. We
|
||||
// need that so there is a valid base class for all new-style
|
||||
// iterators.
|
||||
#define BOOST_OLD_ITERATOR_CATEGORY(category) \
|
||||
template <> \
|
||||
struct is_tag <detail::null_category_tag, std::category> \
|
||||
: mpl::true_ {};
|
||||
|
||||
BOOST_OLD_ITERATOR_CATEGORY(input_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(output_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(forward_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(bidirectional_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(random_access_iterator_tag)
|
||||
#undef BOOST_OLD_ITERATOR_CATEGORY
|
||||
|
||||
template <>
|
||||
struct is_tag<detail::input_output_iterator_tag,std::forward_iterator_tag>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_tag<T,T> : mpl::true_
|
||||
{};
|
||||
|
||||
# ifdef BOOST_NO_IS_CONVERTIBLE
|
||||
// Workarounds for CWPro7 which can't detect derivation at
|
||||
// compile-time.
|
||||
|
||||
// Fact of life: we can only detect tag refinement relationships
|
||||
// among predefined tags.
|
||||
//
|
||||
// Algorithm:
|
||||
// is_tag(T,U) ->
|
||||
// T == U
|
||||
// || (exists d in derived_from(T) such that is_tag(d, U))
|
||||
//
|
||||
// T == U case is handled above
|
||||
|
||||
// false by default
|
||||
template <class Tag, class T>
|
||||
struct is_tag_impl : mpl::false_
|
||||
{};
|
||||
|
||||
// The generalized template dispatches to is_tag_impl because
|
||||
// is_tag<T,T> and is_tag<some_tag,T> are equally specialized.
|
||||
// This technique simulates making is_tag<T,T> more-specialized.
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: is_tag_impl<Tag, T>
|
||||
{};
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1(base, derived) \
|
||||
BOOST_ITERATOR_DERIVED_TAG1_AUX(base, _, derived)
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1_AUX(base, underscore, derived) \
|
||||
template<class T> \
|
||||
struct is_tag_impl<base##underscore##tag, T> \
|
||||
: is_tag<derived##underscore##tag, T> \
|
||||
{ \
|
||||
};
|
||||
|
||||
// Old-style tag relations
|
||||
template<class T>
|
||||
struct is_tag_impl<detail::null_category_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<std::output_iterator_tag, T>
|
||||
, is_tag<std::input_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::output_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::input_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(detail::input_output_iterator, std::forward_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::forward_iterator, std::bidirectional_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::bidirectional_iterator, std::random_access_iterator)
|
||||
|
||||
// Access tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_lvalue_iterator, writable_lvalue_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(swappable_iterator, readable_writable_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_writable_iterator, writable_lvalue_iterator)
|
||||
|
||||
template<class T>
|
||||
struct is_tag_impl<readable_iterator_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<readable_lvalue_iterator_tag, T>
|
||||
, is_tag<readable_writable_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(writable_iterator, readable_writable_iterator)
|
||||
|
||||
// Traversal tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(bidirectional_traversal, random_access_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(forward_traversal, bidirectional_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(single_pass_iterator, forward_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(incrementable_iterator, single_pass_iterator)
|
||||
|
||||
# endif // BOOST_NO_IS_CONVERTIBLE workarounds
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION case
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
@@ -446,19 +280,18 @@ namespace boost {
|
||||
//
|
||||
//
|
||||
template <class T1, class T2>
|
||||
struct minimum_category :
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
mpl::if_< is_base_or_same< T1, T2 >,
|
||||
T1,
|
||||
mpl::if_< is_base_or_same< T2, T1 >,
|
||||
T2,
|
||||
error_type > >
|
||||
#else
|
||||
minimum_category_select< minimum_return_category<T1, T2>,
|
||||
minimum_traversal_category<T1, T2> >
|
||||
#endif
|
||||
struct minimum_category
|
||||
: mpl::apply_if<
|
||||
is_tag<T1,T2>
|
||||
, mpl::identity<T1>
|
||||
, mpl::if_<
|
||||
is_tag<T2, T1>
|
||||
, T2
|
||||
, error_type
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace boost
|
||||
class Return>
|
||||
struct enable_if
|
||||
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
|
||||
: enabled<Cond::value>::template base<Return>
|
||||
: enabled<(Cond::value)>::template base<Return>
|
||||
# else
|
||||
: mpl::identity<Return>
|
||||
# endif
|
||||
|
||||
@@ -15,20 +15,18 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Iterator>
|
||||
struct filter_iterator_traits
|
||||
: iterator_traits<Iterator>
|
||||
struct filter_iterator_category
|
||||
{
|
||||
typedef iterator_tag<
|
||||
typename return_category<Iterator>::type
|
||||
, typename minimum_category<
|
||||
forward_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> iterator_category;
|
||||
typedef iterator_tag<
|
||||
typename access_category<Iterator>::type
|
||||
, typename minimum_category<
|
||||
forward_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -37,13 +35,15 @@ namespace boost
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, detail::filter_iterator_traits<Iterator>
|
||||
, not_specified
|
||||
, typename detail::filter_iterator_category<Iterator>::type
|
||||
>
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, detail::filter_iterator_traits<Iterator>
|
||||
> super_t;
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, not_specified
|
||||
, typename detail::filter_iterator_category<Iterator>::type
|
||||
> super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
#ifdef BOOST_NO_MPL_AUX_HAS_XXX
|
||||
# include <boost/shared_ptr.hpp>
|
||||
@@ -23,6 +27,8 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Iter, class Value, class Category, class Reference, class Pointer, class Difference>
|
||||
struct indirect_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -73,59 +79,103 @@ namespace boost
|
||||
|
||||
// Metafunction returning the nested element_type typedef
|
||||
template <class T>
|
||||
struct smart_pointer_traits
|
||||
{
|
||||
typedef typename remove_const<
|
||||
typename T::element_type
|
||||
>::type value_type;
|
||||
struct smart_pointer_value : remove_const<typename T::element_type>
|
||||
{};
|
||||
|
||||
typedef typename T::element_type& reference;
|
||||
typedef typename T::element_type* pointer;
|
||||
template <class T>
|
||||
struct iterator_is_mutable
|
||||
: mpl::not_<
|
||||
boost::python::detail::is_reference_to_const<
|
||||
typename iterator_reference<T>::type
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct not_int_impl
|
||||
{
|
||||
template <class U>
|
||||
struct apply {
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct not_int_impl<int> {};
|
||||
|
||||
template <class T, class U>
|
||||
struct not_int
|
||||
: not_int_impl<T>::template apply<U> {};
|
||||
|
||||
// If the Value parameter is unspecified, we use this metafunction
|
||||
// to deduce the default types
|
||||
template <class Iter>
|
||||
struct indirect_defaults
|
||||
: mpl::if_<
|
||||
mpl::and_<
|
||||
is_class<typename iterator_traits<Iter>::value_type>
|
||||
, has_element_type<typename iterator_traits<Iter>::value_type>
|
||||
>
|
||||
, smart_pointer_traits<typename iterator_traits<Iter>::value_type>
|
||||
, iterator_traits<typename iterator_traits<Iter>::value_type>
|
||||
>::type
|
||||
template <class Iter, class Value, class Category, class Reference, class Pointer, class Difference>
|
||||
struct indirect_base
|
||||
{
|
||||
typedef typename iterator_traits<Iter>::iterator_category iterator_category;
|
||||
typedef typename iterator_traits<Iter>::difference_type difference_type;
|
||||
typedef typename iterator_value<Iter>::type dereferenceable;
|
||||
|
||||
typedef mpl::and_<
|
||||
is_class<dereferenceable>
|
||||
, has_element_type<dereferenceable>
|
||||
> is_smart_ptr;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
is_smart_ptr
|
||||
, smart_pointer_value<dereferenceable>
|
||||
, iterator_value<dereferenceable>
|
||||
>::type value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_<
|
||||
is_smart_ptr
|
||||
, iterator_is_mutable<dereferenceable>
|
||||
>
|
||||
, value_type
|
||||
, value_type const
|
||||
>::type cv_value_type;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
indirect_iterator<Iter, Value, Category, Reference, Pointer, Difference>
|
||||
, Iter
|
||||
, cv_value_type
|
||||
, Category
|
||||
, Reference
|
||||
, Pointer
|
||||
, Difference
|
||||
> type;
|
||||
};
|
||||
|
||||
// The traits to use for indirect iterator, by default. Whatever
|
||||
// is supplied gets passed through traits_iterator<...> so that it
|
||||
// is ultimately derived from boost::iterator<...>
|
||||
template <class Base, class Traits>
|
||||
struct indirect_traits
|
||||
: mpl::if_<
|
||||
is_same<Traits,unspecified>
|
||||
, indirect_defaults<Base>
|
||||
, Traits
|
||||
>::type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct indirect_base<int, int, int, int, int, int> {};
|
||||
} // namespace detail
|
||||
|
||||
template <class Iterator, class Traits = detail::unspecified>
|
||||
class indirect_iterator :
|
||||
public iterator_adaptor<
|
||||
indirect_iterator<Iterator, Traits>
|
||||
, Iterator
|
||||
, detail::indirect_traits<Iterator,Traits> >
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = not_specified
|
||||
, class Category = not_specified
|
||||
, class Reference = not_specified
|
||||
, class Pointer = not_specified
|
||||
, class Difference = not_specified
|
||||
>
|
||||
class indirect_iterator
|
||||
: public detail::indirect_base<
|
||||
Iterator
|
||||
, Value
|
||||
, Category
|
||||
, Reference
|
||||
, Pointer
|
||||
, Difference
|
||||
>::type
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
indirect_iterator<Iterator, Traits>
|
||||
, Iterator
|
||||
, detail::indirect_traits<Iterator,Traits>
|
||||
> super_t;
|
||||
typedef typename detail::indirect_base<
|
||||
Iterator
|
||||
, Value
|
||||
, Category
|
||||
, Reference
|
||||
, Pointer
|
||||
, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
@@ -145,7 +195,14 @@ namespace boost
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const { return **this->base(); }
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
return const_cast<super_t::reference>(**this->base());
|
||||
# else
|
||||
return **this->base();
|
||||
# endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -17,16 +17,20 @@
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#include <boost/python/detail/is_xxx.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Traits, class Other>
|
||||
@@ -37,8 +41,8 @@ namespace boost
|
||||
, typename Other::iterator_category
|
||||
>
|
||||
, is_same<
|
||||
typename Traits::iterator_category
|
||||
, typename Other::iterator_category
|
||||
typename Traits::iterator_category // *** THIS IS A BUG!! ***
|
||||
, typename Other::iterator_category // MAKE FAILING TEST BEFORE FIXING!!
|
||||
>
|
||||
>
|
||||
{};
|
||||
@@ -116,6 +120,7 @@ namespace boost
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// iterator_traits_adaptor can be used to create new iterator traits by adapting
|
||||
// the traits of a given iterator type. Together with iterator_adaptor it simplifies
|
||||
@@ -123,68 +128,125 @@ namespace boost
|
||||
// argument ordering is different from the std::iterator template, so that default
|
||||
// arguments can be used effectivly.
|
||||
//
|
||||
template <
|
||||
class Iterator
|
||||
, class ValueType = typename detail::iterator_traits<Iterator>::value_type
|
||||
, class Reference = ValueType&
|
||||
, class Pointer = ValueType*
|
||||
, class IteratorCategory = typename detail::iterator_traits<Iterator>::iterator_category
|
||||
, class DifferenceType = typename detail::iterator_traits<Iterator>::difference_type
|
||||
>
|
||||
struct iterator_traits_adaptor
|
||||
: iterator<
|
||||
IteratorCategory
|
||||
, ValueType
|
||||
, DifferenceType
|
||||
, Pointer
|
||||
, Reference
|
||||
>
|
||||
// The ordering changed slightly with respect to former versions of iterator_adaptor
|
||||
// The idea is that when the user needs to fiddle with the reference type
|
||||
// it is highly likely that the iterator category has to be adjusted as well
|
||||
//
|
||||
// Value - if supplied, the value_type of the resulting iterator, unless
|
||||
// const. If const, a conforming compiler strips constness for the
|
||||
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||
//
|
||||
// Reference - the reference type of the resulting iterator, and in
|
||||
// particular, the result type of operator*(). If not supplied but
|
||||
// Value is supplied, Value& is used. Otherwise
|
||||
// iterator_traits<Base>::reference is used.
|
||||
//
|
||||
// Pointer - the pointer type of the resulting iterator, and in
|
||||
// particular, the result type of operator->(). If not
|
||||
// supplied but Value is supplied, Value* is used. Otherwise
|
||||
// iterator_traits<Base>::pointer is used.
|
||||
//
|
||||
// Category - the iterator_category of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::iterator_category is used.
|
||||
//
|
||||
// Distance - the difference_type of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::difference_type is used.
|
||||
//
|
||||
// TODO
|
||||
// ? Automatic adjustment of category ?
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
};
|
||||
template <class T, class Condition, class DefaultNullaryFn>
|
||||
struct ia_dflt_help
|
||||
: mpl::apply_if<
|
||||
mpl::and_<
|
||||
is_same<T, not_specified>
|
||||
, Condition
|
||||
>
|
||||
, DefaultNullaryFn
|
||||
, mpl::identity<T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value
|
||||
, class Category
|
||||
, class Reference
|
||||
, class Pointer
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_adaptor_base
|
||||
{
|
||||
typedef iterator_facade<
|
||||
Derived
|
||||
, typename detail::ia_dflt_help<Value , mpl::true_ , iterator_value<Base> >::type
|
||||
, typename detail::ia_dflt_help<Category , mpl::true_ , BOOST_ITERATOR_CATEGORY<Base> >::type
|
||||
, typename detail::ia_dflt_help<Reference , is_same<Value, not_specified> , iterator_reference<Base> >::type
|
||||
, typename detail::ia_dflt_help<Pointer , is_same<Value, not_specified> , iterator_pointer<Base> >::type
|
||||
, typename detail::ia_dflt_help<Difference , mpl::true_ , iterator_difference<Base> >::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
template <
|
||||
class Derived
|
||||
, class Iterator
|
||||
, class Traits = detail::iterator_traits<Iterator>
|
||||
, class Base
|
||||
, class Value = not_specified
|
||||
, class Category = not_specified
|
||||
, class Reference = not_specified
|
||||
, class Pointer = not_specified
|
||||
, class Difference = not_specified
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public iterator_facade<Derived,Traits>
|
||||
: public detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Pointer, Difference
|
||||
>::type
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
typedef typename detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Pointer, Difference
|
||||
>::type super_t;
|
||||
|
||||
public:
|
||||
iterator_adaptor() {}
|
||||
|
||||
explicit iterator_adaptor(Iterator iter)
|
||||
explicit iterator_adaptor(Base iter)
|
||||
: m_iterator(iter)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator base() const
|
||||
Base base() const
|
||||
{ return m_iterator; }
|
||||
|
||||
protected:
|
||||
// Core iterator interface for iterator_facade
|
||||
//
|
||||
|
||||
typename Traits::reference dereference() const
|
||||
typename super_t::reference dereference() const
|
||||
{ return *m_iterator; }
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class OtherTraits
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class P, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived,OtherIterator,OtherTraits> const& x) const
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, P, D> const& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::same_category_and_difference<Traits,OtherTraits>::value)
|
||||
(detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
);
|
||||
return m_iterator == x.base();
|
||||
}
|
||||
|
||||
void advance(typename Traits::difference_type n)
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
m_iterator += n;
|
||||
}
|
||||
@@ -192,19 +254,24 @@ namespace boost
|
||||
void increment() { ++m_iterator; }
|
||||
void decrement() { --m_iterator; }
|
||||
|
||||
template <class OtherDerived, class OtherIterator, class OtherTraits>
|
||||
typename Traits::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, OtherTraits> const& y) const
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class P, class D
|
||||
>
|
||||
typename super_t::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, P, D> const& y) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::same_category_and_difference<Traits,OtherTraits>::value)
|
||||
(detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
);
|
||||
return y.base() - m_iterator;
|
||||
}
|
||||
|
||||
private: // data members
|
||||
Iterator m_iterator;
|
||||
// Needed for counting iterator
|
||||
Base const& base_reference() const
|
||||
{ return m_iterator; }
|
||||
|
||||
private: // data members
|
||||
Base m_iterator;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -12,17 +12,23 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/detail/categories.hpp>
|
||||
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
@@ -33,60 +39,142 @@ namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ValueType>
|
||||
struct choose_lvalue_return
|
||||
: mpl::if_<
|
||||
is_const<ValueType>
|
||||
, boost::constant_lvalue_iterator_tag
|
||||
, boost::mutable_lvalue_iterator_tag>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename Category, typename ValueType>
|
||||
struct iter_category_to_return
|
||||
: mpl::if_<
|
||||
is_forward_iterator<Category>
|
||||
, typename choose_lvalue_return<ValueType>::type
|
||||
, typename mpl::if_<
|
||||
is_input_iterator<Category>
|
||||
, boost::readable_iterator_tag
|
||||
, typename mpl::if_<
|
||||
is_output_iterator<Category>
|
||||
, boost::writable_iterator_tag
|
||||
, boost::error_iterator_tag
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
// Helper metafunction for std_category below
|
||||
template <class Cat, class Tag, class Next>
|
||||
struct match_tag
|
||||
: mpl::apply_if<is_tag<Tag, Cat>, mpl::identity<Tag>, Next>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Category>
|
||||
struct iter_category_to_traversal
|
||||
: mpl::if_<
|
||||
is_random_access_iterator<Category>
|
||||
, random_access_traversal_tag
|
||||
, typename mpl::if_<
|
||||
is_bidirectional_iterator<Category>
|
||||
, bidirectional_traversal_tag
|
||||
, typename mpl::if_<
|
||||
is_forward_iterator<Category>
|
||||
, forward_traversal_tag
|
||||
, typename mpl::if_<
|
||||
is_input_iterator<Category>
|
||||
, input_traversal_tag
|
||||
, output_traversal_tag
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
// Converts a possibly user-defined category tag to the
|
||||
// most-derived standard tag which is a base of that tag.
|
||||
template <class Category>
|
||||
struct std_category
|
||||
: match_tag<
|
||||
Category, std::random_access_iterator_tag
|
||||
, match_tag<Category, std::bidirectional_iterator_tag
|
||||
, match_tag<Category, std::forward_iterator_tag
|
||||
, match_tag<Category, std::input_iterator_tag
|
||||
, match_tag<Category, std::output_iterator_tag
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
, mpl::identity<void>
|
||||
# else
|
||||
, void
|
||||
# endif
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// std_to_new_tags --
|
||||
//
|
||||
// A metafunction which converts any standard tag into its
|
||||
// corresponding new-style traversal tag.
|
||||
//
|
||||
// Also, instantiations are metafunction classes which convert a
|
||||
// reference type into a corresponding new-style access tag.
|
||||
template <class Category> struct std_to_new_tags
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) // handle ETI
|
||||
{
|
||||
typedef void type;
|
||||
template <class T> struct apply { typedef void type; };
|
||||
}
|
||||
# endif
|
||||
;
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // handle ETI
|
||||
template <> struct std_to_new_tags<int> {};
|
||||
# endif
|
||||
|
||||
//
|
||||
// Specializations for specific standard tags
|
||||
//
|
||||
template <>
|
||||
struct std_to_new_tags<std::input_iterator_tag>
|
||||
{
|
||||
typedef single_pass_iterator_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::identity<readable_iterator_tag> {};
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::output_iterator_tag>
|
||||
{
|
||||
typedef incrementable_iterator_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::identity<writable_iterator_tag> {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::forward_iterator_tag>
|
||||
{
|
||||
typedef forward_traversal_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::if_<
|
||||
python::detail::is_reference_to_const<Reference>
|
||||
, boost::readable_lvalue_iterator_tag
|
||||
, boost::writable_lvalue_iterator_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::bidirectional_iterator_tag>
|
||||
: std_to_new_tags<std::forward_iterator_tag>
|
||||
{
|
||||
typedef bidirectional_traversal_tag type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::random_access_iterator_tag>
|
||||
: std_to_new_tags<std::bidirectional_iterator_tag>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct old_tag_converter
|
||||
: std_to_new_tags<
|
||||
typename std_category<Category>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Category>
|
||||
struct iter_category_to_traversal
|
||||
: std_to_new_tags<
|
||||
typename std_category<Category>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Category, typename Reference>
|
||||
struct iter_category_to_access
|
||||
: mpl::apply1<
|
||||
iter_category_to_traversal<Category>
|
||||
, Reference
|
||||
>
|
||||
{};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct iter_category_to_access<int, int> {};
|
||||
template <> struct iter_category_to_traversal<int> {};
|
||||
# endif
|
||||
|
||||
// A metafunction returning true iff T is boost::iterator_tag<R,U>
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag;
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
//
|
||||
// has_xxx fails, so we have to use
|
||||
@@ -98,9 +186,13 @@ namespace boost {
|
||||
// defined for cwpro7.
|
||||
//
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag :
|
||||
mpl::and_< mpl::not_< is_input_iterator<Tag> >,
|
||||
mpl::not_< is_output_iterator<Tag> > >
|
||||
struct is_new_iterator_tag
|
||||
: mpl::not_<
|
||||
mpl::or_<
|
||||
is_tag<std::input_iterator_tag, Tag>
|
||||
, is_tag<std::output_iterator_tag, Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
#elif BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \
|
||||
@@ -118,12 +210,11 @@ namespace boost {
|
||||
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: //has_traversal<Tag>
|
||||
mpl::if_<
|
||||
is_class<Tag>
|
||||
, has_traversal<Tag>
|
||||
, mpl::false_
|
||||
>::type
|
||||
: mpl::if_<
|
||||
is_class<Tag>
|
||||
, has_traversal<Tag>
|
||||
, mpl::false_
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
@@ -134,7 +225,7 @@ namespace boost {
|
||||
namespace detail {
|
||||
|
||||
template <class NewCategoryTag>
|
||||
struct get_return_category {
|
||||
struct get_access_category {
|
||||
typedef typename NewCategoryTag::returns type;
|
||||
};
|
||||
template <class NewCategoryTag>
|
||||
@@ -142,51 +233,57 @@ namespace boost {
|
||||
typedef typename NewCategoryTag::traversal type;
|
||||
};
|
||||
|
||||
template <class CategoryTag, class Value>
|
||||
struct return_category_tag
|
||||
template <class CategoryTag, class Reference>
|
||||
struct access_category_tag
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, get_return_category<CategoryTag>
|
||||
, iter_category_to_return<CategoryTag, Value>
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, get_access_category<CategoryTag>
|
||||
, iter_category_to_access<CategoryTag, Reference>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class CategoryTag, class Value>
|
||||
template <class CategoryTag>
|
||||
struct traversal_category_tag
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, get_traversal_category<CategoryTag>
|
||||
, iter_category_to_traversal<CategoryTag>
|
||||
>
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, get_traversal_category<CategoryTag>
|
||||
, iter_category_to_traversal<CategoryTag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct access_category_tag<int, int> {};
|
||||
template <> struct traversal_category_tag<int> {};
|
||||
# endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Iterator>
|
||||
struct return_category
|
||||
: detail::return_category_tag<
|
||||
struct access_category
|
||||
: detail::access_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
, typename detail::iterator_traits<Iterator>::value_type>
|
||||
, typename detail::iterator_traits<Iterator>::reference>
|
||||
{};
|
||||
|
||||
template <class Iterator>
|
||||
struct traversal_category
|
||||
: detail::traversal_category_tag<
|
||||
: detail::traversal_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
, typename detail::iterator_traits<Iterator>::value_type>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct return_category<T*>
|
||||
struct access_category<T*>
|
||||
: mpl::if_<
|
||||
is_const<T>
|
||||
, constant_lvalue_iterator_tag
|
||||
, mutable_lvalue_iterator_tag>
|
||||
, readable_lvalue_iterator_tag
|
||||
, writable_lvalue_iterator_tag>
|
||||
{
|
||||
};
|
||||
|
||||
@@ -198,50 +295,12 @@ namespace boost {
|
||||
|
||||
#endif
|
||||
|
||||
// TODO Fix this for BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
template <class RC, class TC>
|
||||
struct cvt_iterator_category
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
detail::is_mutable_lvalue_iterator<RC>
|
||||
, detail::is_constant_lvalue_iterator<RC>
|
||||
>
|
||||
, typename mpl::if_<
|
||||
detail::is_random_access_traversal_iterator<TC>
|
||||
, std::random_access_iterator_tag
|
||||
, typename mpl::if_<
|
||||
detail::is_bidirectional_traversal_iterator<TC>
|
||||
, std::bidirectional_iterator_tag
|
||||
, typename mpl::if_<
|
||||
detail::is_forward_traversal_iterator<TC>
|
||||
, std::forward_iterator_tag
|
||||
, error_iterator_tag
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
|
||||
, typename mpl::if_<
|
||||
mpl::and_<
|
||||
detail::is_readable_iterator<RC>
|
||||
, detail::is_input_traversal_iterator<TC>
|
||||
>
|
||||
, std::input_iterator_tag
|
||||
, typename mpl::if_<
|
||||
mpl::and_<
|
||||
detail::is_writable_iterator<RC>
|
||||
, detail::is_output_traversal_iterator<TC>
|
||||
>
|
||||
, std::output_iterator_tag
|
||||
, error_iterator_tag
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class ReturnTag, class TraversalTag>
|
||||
struct iterator_tag : cvt_iterator_category<ReturnTag, TraversalTag>::type
|
||||
struct iterator_tag
|
||||
: detail::minimum_category<
|
||||
typename ReturnTag::max_category
|
||||
, typename TraversalTag::max_category
|
||||
>
|
||||
{
|
||||
typedef ReturnTag returns;
|
||||
typedef TraversalTag traversal;
|
||||
@@ -264,11 +323,11 @@ namespace boost {
|
||||
typedef char (&yes)[1];
|
||||
typedef char (&no)[2];
|
||||
|
||||
template <class R, class T>
|
||||
static yes test(iterator_tag<R,T> const&);
|
||||
template <class R, class U>
|
||||
static yes test(mpl::identity<iterator_tag<R,U> >*);
|
||||
static no test(...);
|
||||
|
||||
static T inst;
|
||||
static mpl::identity<T>* inst;
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
@@ -43,9 +43,9 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class ReadableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
@@ -53,7 +53,7 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
static_assert_base_and_derived<boost::readable_iterator_tag, return_category>();
|
||||
static_assert_base_and_derived<boost::readable_iterator_tag, access_category>();
|
||||
|
||||
reference r = *i; // or perhaps read(x)
|
||||
value_type v(r);
|
||||
@@ -65,7 +65,7 @@ namespace boost_concepts {
|
||||
template <typename Iterator, typename ValueType>
|
||||
class WritableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
@@ -73,7 +73,7 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
static_assert_base_and_derived<boost::writable_iterator_tag, return_category>();
|
||||
static_assert_base_and_derived<boost::writable_iterator_tag, access_category>();
|
||||
|
||||
*i = v; // a good alternative could be something like write(x, v)
|
||||
}
|
||||
@@ -86,12 +86,12 @@ namespace boost_concepts {
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
|
||||
static_assert_base_and_derived<boost::constant_lvalue_iterator_tag, return_category>();
|
||||
static_assert_base_and_derived<boost::readable_lvalue_iterator_tag, access_category>();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference, const value_type&>::value));
|
||||
|
||||
@@ -106,14 +106,14 @@ namespace boost_concepts {
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
WritableIteratorConcept<Iterator, value_type> >();
|
||||
|
||||
static_assert_base_and_derived<boost::mutable_lvalue_iterator_tag, return_category>();
|
||||
static_assert_base_and_derived<boost::writable_lvalue_iterator_tag, access_category>();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||
|
||||
@@ -188,54 +188,56 @@ namespace boost_concepts {
|
||||
//===========================================================================
|
||||
// Iterator Interoperability Concept
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename TraversalTag>
|
||||
struct Operations;
|
||||
template <typename TraversalTag>
|
||||
struct Operations;
|
||||
|
||||
template <>
|
||||
struct Operations<boost::input_traversal_tag>
|
||||
{
|
||||
template <>
|
||||
struct Operations<boost::incrementable_iterator_tag>
|
||||
{
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
i1 == i2;
|
||||
i1 != i2;
|
||||
|
||||
i2 == i1;
|
||||
i2 != i1;
|
||||
// no interoperability constraints
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Operations<boost::output_traversal_tag>
|
||||
{
|
||||
template <>
|
||||
struct Operations<boost::single_pass_iterator_tag>
|
||||
{
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
Operations<boost::input_traversal_tag>::constraints(i1, i2);
|
||||
}
|
||||
};
|
||||
Operations<boost::incrementable_iterator_tag>(i1, i2);
|
||||
i1 == i2;
|
||||
i1 != i2;
|
||||
|
||||
template <>
|
||||
struct Operations<boost::forward_traversal_tag>
|
||||
{
|
||||
i2 == i1;
|
||||
i2 != i1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Operations<boost::forward_traversal_tag>
|
||||
{
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
Operations<boost::input_traversal_tag>::constraints(i1, i2);
|
||||
Operations<boost::single_pass_iterator_tag>::constraints(i1, i2);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Operations<boost::bidirectional_traversal_tag>
|
||||
{
|
||||
template <>
|
||||
struct Operations<boost::bidirectional_traversal_tag>
|
||||
{
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
Operations<boost::forward_traversal_tag>::constraints(i1, i2);
|
||||
Operations<boost::forward_traversal_tag>::constraints(i1, i2);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Operations<boost::random_access_traversal_tag>
|
||||
|
||||
@@ -10,18 +10,25 @@
|
||||
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/interoperable.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
struct not_specified;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -53,19 +60,135 @@ namespace boost
|
||||
// Generates the corresponding std::iterator specialization
|
||||
// from the given iterator traits type
|
||||
//
|
||||
template <class Traits>
|
||||
struct std_iterator_from_traits
|
||||
: iterator<
|
||||
typename Traits::iterator_category
|
||||
, typename Traits::value_type
|
||||
, typename Traits::difference_type
|
||||
, typename Traits::pointer
|
||||
, typename Traits::reference
|
||||
>
|
||||
template <class Value, class Category, class Reference, class Pointer, class Difference>
|
||||
struct iterator_facade_base
|
||||
{
|
||||
typedef iterator<
|
||||
Category
|
||||
|
||||
, typename remove_cv<Value>::type
|
||||
|
||||
, Difference
|
||||
|
||||
, typename mpl::if_<
|
||||
is_same<Pointer, not_specified>
|
||||
, Value*
|
||||
, Pointer
|
||||
>::type
|
||||
|
||||
, typename mpl::if_<
|
||||
is_same<Reference, not_specified>
|
||||
, Value&
|
||||
, Reference
|
||||
>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
|
||||
// operator->() needs special support for input iterators to strictly meet the
|
||||
// standard's requirements. If *i is not a reference type, we must still
|
||||
// produce a (constant) lvalue to which a pointer can be formed. We do that by
|
||||
// returning an instantiation of this special proxy class template.
|
||||
|
||||
template <class T>
|
||||
struct operator_arrow_proxy
|
||||
{
|
||||
operator_arrow_proxy(const T& x) : m_value(x) {}
|
||||
const T* operator->() const { return &m_value; }
|
||||
// This function is needed for MWCW and BCC, which won't call operator->
|
||||
// again automatically per 13.3.1.2 para 8
|
||||
operator const T*() const { return &m_value; }
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template <class Reference, class Pointer>
|
||||
struct operator_arrow_pointer
|
||||
{
|
||||
operator_arrow_pointer(Reference x) : m_p(&x) {}
|
||||
operator Pointer() const { return m_p; }
|
||||
Pointer m_p;
|
||||
};
|
||||
|
||||
template <class Value, class Category, class Reference, class Pointer>
|
||||
struct operator_arrow_result
|
||||
: mpl::if_<
|
||||
is_tag<
|
||||
readable_lvalue_iterator_tag
|
||||
, typename access_category_tag<Category,Reference>::type
|
||||
>
|
||||
, operator_arrow_proxy<Value>
|
||||
, Pointer
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template<>
|
||||
struct operator_arrow_result<int, int, int, int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
//
|
||||
// Facade is actually an iterator. We require Facade here
|
||||
// so that we do not have to go through iterator_traits
|
||||
// to access the traits
|
||||
//
|
||||
template <class Iterator>
|
||||
class index_operator_proxy
|
||||
{
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
|
||||
public:
|
||||
index_operator_proxy(Iterator const& iter)
|
||||
: m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference()
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
index_operator_proxy& operator=(value_type const& val)
|
||||
{
|
||||
*m_iter = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
template <class Iterator, class ValueType, class Category, class Reference>
|
||||
struct index_operator_result
|
||||
{
|
||||
typedef typename access_category_tag<Category,Reference>::type access_category;
|
||||
|
||||
typedef is_tag<writable_iterator_tag, access_category> use_proxy;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
use_proxy
|
||||
, index_operator_proxy<Iterator>
|
||||
, ValueType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
index_operator_proxy<Iterator> make_index_operator_result(Iterator const& iter, mpl::true_)
|
||||
{
|
||||
return index_operator_proxy<Iterator>(iter);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
typename Iterator::value_type make_index_operator_result(Iterator const& iter, mpl::false_)
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -131,17 +254,24 @@ namespace boost
|
||||
//
|
||||
template <
|
||||
class Derived
|
||||
, class Traits
|
||||
, class Value = not_specified
|
||||
, class Category = not_specified
|
||||
, class Reference = not_specified
|
||||
, class Pointer = not_specified
|
||||
, class Difference = not_specified
|
||||
>
|
||||
class iterator_facade
|
||||
: public detail::std_iterator_from_traits<Traits>
|
||||
: public detail::iterator_facade_base<Value, Category, Reference, Pointer, Difference>::type
|
||||
{
|
||||
typedef detail::std_iterator_from_traits<Traits> super_t;
|
||||
private:
|
||||
typedef iterator_facade<Derived, Value, Category, Reference, Pointer, Difference> self_t;
|
||||
|
||||
typedef typename
|
||||
detail::iterator_facade_base<Value, Category, Reference, Pointer, Difference>::type
|
||||
super_t;
|
||||
|
||||
public:
|
||||
//
|
||||
// CRT interface. There is no simple way to remove this
|
||||
// from the public interface without template friends
|
||||
// CRT interface.
|
||||
//
|
||||
typedef Derived derived_t;
|
||||
|
||||
@@ -155,10 +285,13 @@ namespace boost
|
||||
return static_cast<Derived const&>(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
typedef typename super_t::value_type value_type;
|
||||
typedef typename super_t::reference reference;
|
||||
typedef typename super_t::difference_type difference_type;
|
||||
typedef typename super_t::pointer pointer;
|
||||
typedef typename super_t::iterator_category iterator_category;
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
@@ -166,14 +299,32 @@ namespace boost
|
||||
}
|
||||
|
||||
// Needs eventual help for input iterators
|
||||
pointer operator->() const
|
||||
typename detail::operator_arrow_result<
|
||||
value_type
|
||||
, iterator_category
|
||||
, reference
|
||||
, pointer
|
||||
>::type
|
||||
operator->() const
|
||||
{
|
||||
return &iterator_core_access::dereference(this->derived());
|
||||
typedef typename detail::operator_arrow_result<
|
||||
value_type
|
||||
, iterator_category
|
||||
, reference
|
||||
, detail::operator_arrow_pointer<reference,pointer>
|
||||
>::type result_t;
|
||||
|
||||
return result_t(*this->derived());
|
||||
}
|
||||
|
||||
reference operator[](difference_type n) const
|
||||
typename detail::index_operator_result<Derived,value_type,iterator_category,reference>::type
|
||||
operator[](difference_type n) const
|
||||
{
|
||||
return *(*this + n);
|
||||
typedef typename
|
||||
detail::index_operator_result<Derived,value_type,iterator_category,reference>::use_proxy
|
||||
use_proxy;
|
||||
|
||||
return detail::make_index_operator_result<Derived>(this->derived() + n, use_proxy());
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
@@ -289,13 +440,16 @@ namespace boost
|
||||
//
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, condition, return_prefix, base_op) \
|
||||
template <class Derived1, class Traits1, class Derived2, class Traits2> \
|
||||
template < \
|
||||
class Derived1, class V1, class C1, class R1, class P1, class D1 \
|
||||
, class Derived2, class V2, class C2, class R2, class P2, class D2 \
|
||||
> \
|
||||
inline typename detail::enable_if_interoperable< \
|
||||
Derived1, Derived2, result_type \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, Traits1> const& lhs \
|
||||
, iterator_facade<Derived2, Traits2> const& rhs) \
|
||||
iterator_facade<Derived1, V1, C1, R1, P1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, C2, R2, P2, D2> const& rhs) \
|
||||
{ \
|
||||
/* For those compilers that do not support enable_if */ \
|
||||
BOOST_STATIC_ASSERT(( \
|
||||
@@ -303,8 +457,8 @@ namespace boost
|
||||
&& condition \
|
||||
)); \
|
||||
return_prefix iterator_core_access::base_op( \
|
||||
rhs.derived(), lhs.derived()); \
|
||||
}
|
||||
static_cast<Derived2 const&>(rhs), static_cast<Derived1 const&>(lhs)); \
|
||||
}
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP( \
|
||||
@@ -327,31 +481,31 @@ namespace boost
|
||||
// operator- requires an additional part in the static assertion
|
||||
BOOST_ITERATOR_FACADE_INTEROP(
|
||||
-
|
||||
, typename Traits1::difference_type
|
||||
, typename Derived1::difference_type
|
||||
, (is_same<
|
||||
BOOST_ARG_DEP_TYPENAME Traits1::difference_type
|
||||
, BOOST_ARG_DEP_TYPENAME Traits2::difference_type
|
||||
BOOST_ARG_DEP_TYPENAME Derived1::difference_type
|
||||
, BOOST_ARG_DEP_TYPENAME Derived2::difference_type
|
||||
>::value)
|
||||
, return
|
||||
, distance_to )
|
||||
# undef BOOST_ITERATOR_FACADE_INTEROP
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||
template <class Derived, class Traits> \
|
||||
inline Derived operator+ args \
|
||||
{ \
|
||||
Derived tmp(i.derived()); \
|
||||
return tmp += n; \
|
||||
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||
template <class Derived, class V, class C, class R, class P, class D> \
|
||||
inline Derived operator+ args \
|
||||
{ \
|
||||
Derived tmp(static_cast<Derived const&>(i)); \
|
||||
return tmp += n; \
|
||||
}
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
iterator_facade<Derived, Traits> const& i
|
||||
, typename Traits::difference_type n
|
||||
iterator_facade<Derived, V, C, R, P, D> const& i
|
||||
, typename Derived::difference_type n
|
||||
))
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
typename Traits::difference_type n
|
||||
, iterator_facade<Derived, Traits> const& i
|
||||
typename Derived::difference_type n
|
||||
, iterator_facade<Derived, V, C, R, P, D> const& i
|
||||
))
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||
|
||||
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
// Copyright David Abrahams 2003. 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.
|
||||
#ifndef ITERATOR_TRAITS_DWA200347_HPP
|
||||
# define ITERATOR_TRAITS_DWA200347_HPP
|
||||
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Unfortunately, g++ 2.95.x chokes when we define a class template
|
||||
// iterator_category which has the same name as its
|
||||
// std::iterator_category() function, probably due in part to the
|
||||
// "std:: is visible globally" hack it uses. Use
|
||||
// BOOST_ITERATOR_CATEGORY to write code that's portable to older
|
||||
// GCCs.
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, <= 2)
|
||||
# define BOOST_ITERATOR_CATEGORY iterator_category_
|
||||
# else
|
||||
# define BOOST_ITERATOR_CATEGORY iterator_category
|
||||
# endif
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_value
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_reference
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::reference type;
|
||||
};
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_pointer
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::pointer type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_difference
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::difference_type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct BOOST_ITERATOR_CATEGORY
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::iterator_category type;
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
template <>
|
||||
struct iterator_value<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_reference<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_pointer<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_difference<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BOOST_ITERATOR_CATEGORY<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
# endif
|
||||
|
||||
} // namespace boost::iterator
|
||||
|
||||
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
||||
@@ -30,8 +30,8 @@ namespace boost {
|
||||
void is_readable(readable_iterator_tag) { }
|
||||
void is_writable(writable_iterator_tag) { }
|
||||
void is_swappable(swappable_iterator_tag) { }
|
||||
void is_constant_lvalue(constant_lvalue_iterator_tag) { }
|
||||
void is_mutable_lvalue(mutable_lvalue_iterator_tag) { }
|
||||
void is_constant_lvalue(readable_lvalue_iterator_tag) { }
|
||||
void is_mutable_lvalue(writable_lvalue_iterator_tag) { }
|
||||
|
||||
// Preconditions: *i == v
|
||||
template <class Iterator, class T>
|
||||
@@ -45,7 +45,7 @@ void readable_iterator_test(const Iterator i1, T v)
|
||||
T v2 = r2;
|
||||
assert(v1 == v);
|
||||
assert(v2 == v);
|
||||
typename return_category<Iterator>::type result_category;
|
||||
typename access_category<Iterator>::type result_category;
|
||||
is_readable(result_category);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void writable_iterator_test(Iterator i, T v)
|
||||
{
|
||||
Iterator i2(i); // Copy Constructible
|
||||
*i2 = v;
|
||||
is_writable(typename return_category<Iterator>::type());
|
||||
is_writable(typename access_category<Iterator>::type());
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
@@ -65,7 +65,7 @@ void swappable_iterator_test(Iterator i, Iterator j)
|
||||
iter_swap(i2, j2);
|
||||
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||
assert(bi == aj && bj == ai);
|
||||
typedef typename return_category<Iterator>::type result_category;
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_swappable(result_category());
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
|
||||
const T& v2 = *i2;
|
||||
assert(v1 == v2);
|
||||
typedef typename return_category<Iterator>::type result_category;
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_constant_lvalue(result_category());
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
*i = v2;
|
||||
T& v4 = *i2;
|
||||
assert(v2 == v4);
|
||||
typedef typename return_category<Iterator>::type result_category;
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_mutable_lvalue(result_category());
|
||||
}
|
||||
|
||||
|
||||
@@ -15,43 +15,36 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class AdaptableUnaryFunction, class Iterator>
|
||||
class transform_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Given the transform iterator's transformation and iterator, this
|
||||
// is the type used as its traits.
|
||||
template <class AdaptableUnaryFunction, class Iterator>
|
||||
struct transform_iterator_traits
|
||||
: iterator_traits_adaptor<
|
||||
Iterator
|
||||
struct transform_iterator_base
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<AdaptableUnaryFunction, Iterator>
|
||||
, Iterator
|
||||
, typename AdaptableUnaryFunction::result_type
|
||||
, typename AdaptableUnaryFunction::result_type
|
||||
, typename AdaptableUnaryFunction::result_type*
|
||||
, iterator_tag<
|
||||
readable_iterator_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>
|
||||
>
|
||||
{
|
||||
, typename AdaptableUnaryFunction::result_type
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
} // transform_iterator_traits
|
||||
|
||||
//
|
||||
template <class AdaptableUnaryFunction, class Iterator>
|
||||
class transform_iterator
|
||||
: public iterator_adaptor<
|
||||
transform_iterator<AdaptableUnaryFunction, Iterator>
|
||||
, Iterator
|
||||
, detail::transform_iterator_traits<AdaptableUnaryFunction,Iterator>
|
||||
>
|
||||
: public detail::transform_iterator_base<AdaptableUnaryFunction, Iterator>::type
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<AdaptableUnaryFunction, Iterator>
|
||||
, Iterator
|
||||
, detail::transform_iterator_traits<AdaptableUnaryFunction,Iterator>
|
||||
> super_t;
|
||||
typedef typename
|
||||
detail::transform_iterator_base<AdaptableUnaryFunction, Iterator>::type
|
||||
super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user