mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-29 20:37:17 +02:00
progress
[SVN r20853]
This commit is contained in:
@ -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:
|
||||
|
@ -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))
|
||||
|
220
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
220
include/boost/iterator/detail/facade_iterator_category.hpp
Executable 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user