[SVN r20853]
This commit is contained in:
Dave Abrahams
2003-11-19 04:25:17 +00:00
parent cd37eb3bfb
commit 62b70f57a9
11 changed files with 369 additions and 232 deletions

View File

@ -15,7 +15,7 @@
namespace boost {
template <class Incrementable, class Category, class Difference> class counting_iterator;
template <class Incrementable, class Traversal, class Difference> class counting_iterator;
namespace detail
{
@ -67,35 +67,37 @@ namespace detail
};
BOOST_STATIC_ASSERT(is_numeric<int>::value);
template <class Incrementable, class Category, class Difference>
template <class Incrementable, class Traversal, class Difference>
struct counting_iterator_base
{
typedef typename mpl::apply_if<
is_same<Category, use_default>
typedef typename detail::ia_dflt_help<
Traversal
, mpl::apply_if<
is_numeric<Incrementable>
, mpl::identity<std::random_access_iterator_tag>
, BOOST_ITERATOR_CATEGORY<Incrementable>
, mpl::identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
>
, mpl::identity<Category>
>::type category;
>::type traversal;
typedef typename mpl::apply_if<
is_same<Difference, use_default>
typedef typename detail::ia_dflt_help<
Difference
, 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
counting_iterator<Incrementable, Traversal, Difference> // self
, Incrementable // Base
, Incrementable // Value
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
# endif
, traversal
, Incrementable const& // reference
, difference
> type;
};
@ -128,11 +130,11 @@ namespace detail
};
}
template <class Incrementable, class Category = use_default, class Difference = use_default>
template <class Incrementable, class Traversal = use_default, class Difference = use_default>
class counting_iterator
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
: public detail::counting_iterator_base<Incrementable, Traversal, Difference>::type
{
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
typedef typename detail::counting_iterator_base<Incrementable, Traversal, Difference>::type super_t;
friend class iterator_core_access;
public:

View File

@ -24,6 +24,11 @@
# define BOOST_ITERATOR_CONFIG_DEF
#endif
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))

View File

@ -0,0 +1,220 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# include <boost/iterator/iterator_categories.hpp>
# include <boost/static_assert.hpp>
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
# include <boost/mpl/and.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_const.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/python/detail/indirect_traits.hpp>
# endif
//
// iterator_category deduction for iterator_facade
//
// forward declaration
namespace boost { struct use_default; }
namespace boost { namespace detail {
struct input_output_iterator_tag
: std::input_iterator_tag, std::output_iterator_tag {};
//
// True iff the user has explicitly disabled writability of this
// iterator. Pass the iterator_facade's Value parameter and its
// nested ::reference type.
//
template <class ValueParam, class Reference>
struct iterator_writability_disabled
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
: mpl::or_<
is_const<Reference>
, python::detail::is_reference_to_const<Reference>
, is_const<ValueParam>
>
# else
: is_const<ValueParam>
# endif
{};
//
// Convert an iterator_facade's traversal category, Value parameter,
// and ::reference type to an appropriate old-style category.
//
// If writability has been disabled per the above metafunction, the
// result will not be convertible to output_iterator_tag.
//
// Otherwise, if Traversal == single_pass_traversal_tag, the following
// conditions will result in a tag that is convertible both to
// input_iterator_tag and output_iterator_tag:
//
// 1. Reference is a reference to non-const
// 2. Reference is not a reference and is convertible to Value
//
template <class Traversal, class ValueParam, class Reference>
struct iterator_facade_default_category
: mpl::apply_if<
mpl::and_<
is_reference<Reference>
, is_convertible<Traversal,forward_traversal_tag>
>
, mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<std::random_access_iterator_tag>
, mpl::if_<
is_convertible<Traversal,bidirectional_traversal_tag>
, std::bidirectional_iterator_tag
, std::forward_iterator_tag
>
>
, typename mpl::apply_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
, mpl::or_< // check for readability
is_same<ValueParam,use_default>
, is_convertible<Reference, ValueParam>
>
>
, mpl::if_<
iterator_writability_disabled<ValueParam,Reference>
, std::input_iterator_tag
, input_output_iterator_tag
>
, mpl::identity<std::output_iterator_tag>
>
>
{
};
// True iff T is convertible to an old-style iterator category.
template <class T>
struct is_iterator_category
: mpl::or_<
is_convertible<T,std::input_iterator_tag>
, is_convertible<T,std::output_iterator_tag>
>
{
};
template <>
struct is_iterator_category<int>
: mpl::false_
{};
template <class T>
struct is_iterator_traversal
: is_convertible<T,incrementable_traversal_tag>
{};
//
// A composite iterator_category tag convertible to Category (a pure
// old-style category) and Traversal (a pure traversal tag).
// Traversal must be a strict increase of the traversal power given by
// Category.
//
template <class Category, class Traversal>
struct iterator_category_with_traversal
: Category, Traversal
{
# if 0
// Because of limitations on multiple user-defined conversions,
// this should be a good test of whether convertibility is enough
// in the spec, or whether we need to specify inheritance.
operator Category() const { return Category(); }
operator Traversal() const { return Traversal(); }
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// Make sure this isn't used to build any categories where
// convertibility to Traversal is redundant. Should just use the
// Category element in that case.
BOOST_STATIC_ASSERT(
!(is_convertible<
typename iterator_category_to_traversal<Category>::type
, Traversal
>::value));
BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
# endif
};
template <>
struct iterator_category_with_traversal<int,int>
{};
// Computes an iterator_category tag whose traversal is Traversal and
// which is appropriate for an iterator
template <class Traversal, class ValueParam, class Reference>
struct facade_iterator_category_impl
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
# endif
typedef typename iterator_facade_default_category<
Traversal,ValueParam,Reference
>::type category;
typedef typename mpl::if_<
is_same<
Traversal
, typename iterator_category_to_traversal<category>::type
>
, category
, iterator_category_with_traversal<category,Traversal>
>::type type;
};
template <>
struct facade_iterator_category_impl<int,int,int> {};
//
// Compute an iterator_category for iterator_facade
//
template <class CategoryOrTraversal, class ValueParam, class Reference>
struct facade_iterator_category
: mpl::apply_if<
is_iterator_category<CategoryOrTraversal>
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
>
{
};
template <>
struct facade_iterator_category<int,int,int>
{
typedef int type;
};
}} // namespace boost::detail
# include <boost/iterator/detail/config_undef.hpp>
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP

View File

@ -14,6 +14,8 @@
// should be the last #include
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
namespace boost {
namespace detail
@ -122,7 +124,7 @@ namespace detail
{};
template <class It>
struct is_mutable_lvalue_iterator_impl
struct is_non_const_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
>::template rebind<It>
@ -135,10 +137,12 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_mutable_lvalue_iterator,T,::boost::detail::is_mutable_lvalue_iterator_impl<T>::value)
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP

View File

@ -13,6 +13,8 @@
// should be the last #include
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
namespace boost {
namespace detail
@ -99,6 +101,8 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1(
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP

View File

@ -26,7 +26,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/type_traits/remove_reference.hpp>
#else
# include <boost/type_traits/add_reference.hpp>
@ -38,6 +38,20 @@
namespace boost
{
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
struct use_default;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not
// needed for vc6/vc7.
template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
# endif
namespace detail
{
@ -157,7 +171,7 @@ namespace boost
typedef iterator_facade<
Derived
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename detail::ia_dflt_help<
Value
, mpl::apply_if<
@ -177,7 +191,7 @@ namespace boost
, iterator_traversal<Base>
>::type
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename detail::ia_dflt_help<
Reference
, iterator_reference<Base>
@ -199,6 +213,7 @@ namespace boost
>
type;
};
template <class T> int static_assert_convertible_to(T);
}
//
@ -287,17 +302,18 @@ namespace boost
// );
return m_iterator == x.base();
}
typedef typename iterator_category_to_traversal<
typename super_t::iterator_category
>::type my_traversal;
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
typedef int assertion[sizeof(detail::static_assert_convertible_to<cat>(my_traversal()))];
// BOOST_STATIC_ASSERT((is_convertible<my_traversal,cat>::value));
void advance(typename super_t::difference_type n)
{
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
BOOST_STATIC_ASSERT(
(is_convertible<
BOOST_DEDUCED_TYPENAME super_t::iterator_category
, random_access_traversal_tag
>::value)
);
# endif
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
m_iterator += n;
}
@ -305,14 +321,7 @@ namespace boost
void decrement()
{
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
BOOST_STATIC_ASSERT(
(is_convertible<
BOOST_DEDUCED_TYPENAME super_t::iterator_category
, bidirectional_traversal_tag
>::value)
);
# endif
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
--m_iterator;
}
@ -322,12 +331,7 @@ namespace boost
typename super_t::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
{
BOOST_STATIC_ASSERT(
(is_convertible<
BOOST_DEDUCED_TYPENAME super_t::iterator_category
, random_access_traversal_tag
>::value)
);
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
@ -335,6 +339,8 @@ namespace boost
return y.base() - m_iterator;
}
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
private: // data members
Base m_iterator;
};

View File

@ -13,16 +13,12 @@
# include <boost/detail/workaround.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/placeholders.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_const.hpp>
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@ -54,70 +50,7 @@ struct random_access_traversal_tag
namespace detail
{
struct input_output_iterator_tag
: std::input_iterator_tag, std::output_iterator_tag {};
//
// Helper for iterator_tag and iterator_facade. True iff the user
// has explicitly disabled writability of this iterator.
//
template <class Value, class Reference>
struct iterator_writability_disabled
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
: mpl::or_<is_const<Reference>,python::detail::is_reference_to_const<Reference> >
# else
: is_const<typename remove_reference<Reference>::type>
# endif
# else
: is_const<Value>
# endif
{};
template <class Value, class Reference, class Traversal>
struct old_iterator_category
{
typedef typename mpl::
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
if_
# else
apply_if
# endif
<
mpl::and_<
is_reference<Reference>
, is_convertible<Traversal,forward_traversal_tag>
>
, mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<std::random_access_iterator_tag>
, mpl::if_<
is_convertible<Traversal,bidirectional_traversal_tag>
, std::bidirectional_iterator_tag
, std::forward_iterator_tag
>
>
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
::type
# endif
, typename mpl::apply_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
, is_convertible<Reference, Value>
>
, mpl::if_<
iterator_writability_disabled<Value,Reference>
, std::input_iterator_tag
, input_output_iterator_tag
>
, mpl::identity<std::output_iterator_tag>
>
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
::type
# endif
>::type type;
};
//
// Convert a "strictly old-style" iterator category to a traversal
// tag. This is broken out into a separate metafunction to reduce
@ -125,7 +58,7 @@ namespace detail
// for new-style types.
//
template <class Cat>
struct old_style_category_to_traversal
struct category_to_traversal
: mpl::apply_if<
is_convertible<Cat,std::random_access_iterator_tag>
, mpl::identity<random_access_traversal_tag>
@ -151,7 +84,7 @@ namespace detail
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct old_style_category_to_traversal<int>
struct category_to_traversal<int>
{
typedef int type;
};
@ -167,38 +100,10 @@ struct iterator_category_to_traversal
: mpl::apply_if< // if already convertible to a traversal tag, we're done.
is_convertible<Cat,incrementable_traversal_tag>
, mpl::identity<Cat>
, detail::old_style_category_to_traversal<Cat>
, detail::category_to_traversal<Cat>
>
{};
//
// To be used for a new-style iterator's iterator_category; provides
// implicit conversion to the appropriate old-style iterator category.
//
// If Value is const the result will not be convertible to
// output_iterator_tag.
//
// Otherwise, if Traversal == single_pass_traversal_tag, the following
// conditions will result in a tag that is convertible both to
// input_iterator_tag and output_iterator_tag:
//
// 1. Reference is a reference to non-const
// 2. Reference is not a reference and is convertible to Value
//
template <class Value, class Reference, class Traversal>
struct iterator_tag
: detail::old_iterator_category<Value, Reference, Traversal>::type
{
operator Traversal() { return Traversal(); }
# if 0
typedef typename detail::old_iterator_category<
Value, Reference, Traversal
>::type old_category;
operator old_category() const { return old_category(); }
# endif
};
// Trait to get an iterator's traversal category
template <class Iterator = mpl::_1>
struct iterator_traversal
@ -226,7 +131,6 @@ struct iterator_traversal<mpl::_>
{};
# endif
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@ -12,21 +12,17 @@
#include <boost/static_assert.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/iterator/interoperable.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# include <boost/type_traits/add_pointer.hpp>
# include <boost/type_traits/add_const.hpp>
#endif
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/or.hpp>
@ -36,22 +32,8 @@ namespace boost
{
// This forward declaration is required for the friend declaration
// in iterator_core_access
template <class I, class V, class TC, class R, class D> class iterator_facade;
template <class I, class V, class C, class R, class D> class iterator_facade;
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
struct use_default;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not
// needed for vc6/vc7.
template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
# endif
namespace detail
{
//
@ -82,37 +64,41 @@ namespace boost
};
//
// Generates the associated types for an iterator_facade with the
// given parameters. Additionally generates a 'base' type for
// compiler/library combinations which require user-defined
// iterators to inherit from std::iterator.
// Generates associated types for an iterator_facade with the
// given parameters.
//
template <
class Value
, class TraversalCategory
class ValueParam
, class CategoryOrTraversal
, class Reference
, class Difference
>
struct iterator_facade_types
{
typedef iterator_tag<Value, Reference, TraversalCategory> iterator_category;
typedef typename remove_const<Value>::type value_type;
{
typedef typename facade_iterator_category<
CategoryOrTraversal, ValueParam, Reference
>::type iterator_category;
typedef typename remove_const<ValueParam>::type value_type;
typedef typename mpl::apply_if<
detail::iterator_writability_disabled<ValueParam,Reference>
, add_pointer<typename add_const<value_type>::type>
, add_pointer<value_type>
>::type pointer;
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|| BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
// To interoperate with some broken library/compiler
// combinations, user-defined iterators must be derived from
// std::iterator. It is possible to implement a standard
// library for broken compilers without this limitation.
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
typedef
iterator<iterator_category, value_type, Difference, Value*, Reference>
iterator<iterator_category, value_type, Difference, pointer, Reference>
base;
# endif
};
@ -176,10 +162,10 @@ namespace boost
public:
operator_brackets_proxy(Iterator const& iter)
: m_iter(iter)
: m_iter(iter)
{}
operator reference()
operator reference() const
{
return *m_iter;
}
@ -222,18 +208,18 @@ namespace boost
// Macros which describe the declarations of binary operators
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class R1, class D1 \
, class Derived2, class V2, class TC2, class R2, class D2 \
class Derived1, class V1, class C1, class R1, class D1 \
, class Derived2, class V2, class C2, class R2, class D2 \
> \
prefix typename detail::enable_if_interoperable< \
Derived1, Derived2, result_type \
>::type \
operator op( \
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
iterator_facade<Derived1, V1, C1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, C2, R2, D2> const& rhs)
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \
template <class Derived, class V, class C, class R, class D> \
prefix Derived operator+ args
//
@ -254,7 +240,7 @@ namespace boost
public:
# else
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
template <class I, class V, class C, class R, class D> friend class iterator_facade;
# define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
@ -274,7 +260,7 @@ namespace boost
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend
, (iterator_facade<Derived, V, TC, R, D> const&
, (iterator_facade<Derived, V, C, R, D> const&
, typename Derived::difference_type)
)
;
@ -282,7 +268,7 @@ namespace boost
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend
, (typename Derived::difference_type
, iterator_facade<Derived, V, TC, R, D> const&)
, iterator_facade<Derived, V, C, R, D> const&)
)
;
@ -337,14 +323,14 @@ namespace boost
template <
class Derived // The derived iterator type being constructed
, class Value
, class TraversalCategory
, class CategoryOrTraversal
, class Reference = Value&
, class Difference = std::ptrdiff_t
>
class iterator_facade
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public detail::iterator_facade_types<
Value, TraversalCategory, Reference, Difference
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
@ -365,21 +351,17 @@ namespace boost
return static_cast<Derived const&>(*this);
}
typedef detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
public:
typedef typename remove_const<Value>::type value_type;
typedef typename associated_types::value_type value_type;
typedef Reference reference;
typedef Difference difference_type;
# if BOOST_ITERATOR_REFERENCE_PRIMACY
typedef typename mpl::apply_if<
detail::iterator_writability_disabled<Value,Reference>
, add_pointer<typename add_const<value_type>::type>
, add_pointer<value_type>
>::type pointer;
# else
typedef Value* pointer;
# endif
typedef iterator_tag<Value,Reference,TraversalCategory> iterator_category;
typedef typename associated_types::pointer pointer;
typedef typename associated_types::iterator_category iterator_category;
reference operator*() const
{
@ -403,9 +385,9 @@ namespace boost
typename detail::operator_brackets_result<Derived,Value,Reference>::type
operator[](difference_type n) const
{
typedef detail::iterator_writability_disabled<Value,Reference> use_proxy;
typedef detail::iterator_writability_disabled<Value,Reference> not_writable;
return detail::make_operator_brackets_result<Derived>(this->derived() + n, use_proxy());
return detail::make_operator_brackets_result<Derived>(this->derived() + n, not_writable());
}
Derived& operator++()
@ -583,13 +565,13 @@ namespace boost
}
BOOST_ITERATOR_FACADE_PLUS((
iterator_facade<Derived, V, TC, R, D> const& i
iterator_facade<Derived, V, C, R, D> const& i
, typename Derived::difference_type n
))
BOOST_ITERATOR_FACADE_PLUS((
typename Derived::difference_type n
, iterator_facade<Derived, V, TC, R, D> const& i
, iterator_facade<Derived, V, C, R, D> const& i
))
# undef BOOST_ITERATOR_FACADE_PLUS
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD

View File

@ -24,15 +24,11 @@
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/detail/iterator.hpp>
# include <boost/pending/iterator_tests.hpp>
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
namespace boost {
void is_readable(readable_iterator_tag) { }
void is_writable(writable_iterator_tag) { }
void is_swappable(swappable_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>
void readable_iterator_test(const Iterator i1, T v)
@ -45,8 +41,12 @@ void readable_iterator_test(const Iterator i1, T v)
T v2 = r2;
assert(v1 == v);
assert(v2 == v);
typedef typename access_category<Iterator>::type result_category;
is_readable(result_category());
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
// I think we don't really need this as it checks the same things as
// the above code.
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>
@ -54,7 +54,6 @@ void writable_iterator_test(Iterator i, T v)
{
Iterator i2(i); // Copy Constructible
*i2 = v;
is_writable(typename access_category<Iterator>::type());
}
template <class Iterator>
@ -65,8 +64,6 @@ 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 access_category<Iterator>::type result_category;
is_swappable(result_category());
}
template <class Iterator, class T>
@ -78,12 +75,13 @@ 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 access_category<Iterator>::type result_category;
is_constant_lvalue(result_category());
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>
void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
void writable_lvalue_iterator_test(Iterator i, T v1, T v2)
{
Iterator i2(i);
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
@ -94,8 +92,9 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
*i = v2;
T& v4 = *i2;
assert(v2 == v4);
typedef typename access_category<Iterator>::type result_category;
is_mutable_lvalue(result_category());
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>

View File

@ -286,7 +286,7 @@ int main()
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# endif
// Also prove that we can handle raw pointers.
int array[2000];
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));

View File

@ -181,11 +181,22 @@ struct constant_iterator
: base_t(it) {}
};
char (& traversal(boost::incrementable_traversal_tag) )[1];
char (& traversal(boost::single_pass_traversal_tag ) )[2];
char (& traversal(boost::forward_traversal_tag ) )[3];
char (& traversal(boost::bidirectional_traversal_tag) )[4];
char (& traversal(boost::random_access_traversal_tag) )[5];
char (& traversal2(boost::incrementable_traversal_tag) )[1];
char (& traversal2(boost::single_pass_traversal_tag ) )[2];
char (& traversal2(boost::forward_traversal_tag ) )[3];
char (& traversal2(boost::bidirectional_traversal_tag) )[4];
char (& traversal2(boost::random_access_traversal_tag) )[5];
template <class Cat>
struct traversal3
{
static typename boost::iterator_category_to_traversal<Cat>::type x;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
typedef char (&type)[value];
};
template <class Cat>
typename traversal3<Cat>::type traversal(Cat);
int
main()
@ -244,7 +255,7 @@ main()
test = static_assert_same<Iter::pointer, int const*>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif