forked from boostorg/iterator
Removed access category tags from iterator library, made corresponding
changes elsewhere. boost/iterator and libs/iterator/test were updated from branch "simplify" [SVN r20905]
This commit is contained in:
@ -15,7 +15,12 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Incrementable, class Category, class Difference> class counting_iterator;
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal
|
||||
, class Difference
|
||||
>
|
||||
class counting_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@ -67,34 +72,37 @@ namespace detail
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||
template <class Incrementable, class Category, class Difference>
|
||||
|
||||
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
typedef typename mpl::apply_if<
|
||||
is_same<Category, use_default>
|
||||
typedef typename detail::ia_dflt_help<
|
||||
CategoryOrTraversal
|
||||
, 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
|
||||
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // value_type
|
||||
, category
|
||||
, 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 +136,20 @@ namespace detail
|
||||
};
|
||||
}
|
||||
|
||||
template <class Incrementable, class Category = use_default, class Difference = use_default>
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class counting_iterator
|
||||
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
|
||||
: public detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
|
||||
typedef typename detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
|
@ -1,360 +1 @@
|
||||
// (C) Copyright Thomas Witt 2002. 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 BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
# define BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
# 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 <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
# include <iterator>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
struct incrementable_traversal_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct single_pass_traversal_tag
|
||||
: incrementable_traversal_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct forward_traversal_tag
|
||||
: single_pass_traversal_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 { };
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Tag detection meta functions
|
||||
//
|
||||
|
||||
// I bet this is defined somewhere else. Let's wait and see.
|
||||
struct error_type;
|
||||
|
||||
# ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
// True iff T is a tag "derived" from Tag
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: mpl::or_<
|
||||
is_convertible<T, Tag>
|
||||
|
||||
// Because we can't actually get forward_iterator_tag to
|
||||
// derive from input_output_iterator_tag, we need this
|
||||
// case.
|
||||
, mpl::and_<
|
||||
is_convertible<T,std::forward_iterator_tag>
|
||||
, is_convertible<detail::input_output_iterator_tag,Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
# 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_traversal, forward_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(incrementable_traversal, single_pass_traversal)
|
||||
|
||||
# endif // BOOST_NO_IS_CONVERTIBLE workarounds
|
||||
|
||||
# endif // ndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class Tag, class Known, class Else>
|
||||
struct known_tag
|
||||
: mpl::apply_if<is_tag<Known,Tag>, mpl::identity<Known>, Else>
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct max_known_traversal_tag
|
||||
: known_tag<
|
||||
Tag, random_access_traversal_tag
|
||||
, known_tag<
|
||||
Tag, bidirectional_traversal_tag
|
||||
, known_tag<
|
||||
Tag, forward_traversal_tag
|
||||
, known_tag<
|
||||
Tag, single_pass_traversal_tag
|
||||
, known_tag<
|
||||
Tag, incrementable_traversal_tag
|
||||
, error_iterator_tag
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
// Doesn't cope with these odd combinations: readable+swappable,
|
||||
// writable+swappable. That doesn't matter for the sake of
|
||||
// new-style tag base computation, which is all it's used for
|
||||
// anyway.
|
||||
template <class Tag>
|
||||
struct max_known_access_tag
|
||||
: known_tag<
|
||||
Tag, writable_lvalue_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_lvalue_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_writable_iterator_tag
|
||||
, known_tag<
|
||||
Tag, writable_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_iterator_tag
|
||||
, mpl::apply_if<
|
||||
is_tag<Tag, swappable_iterator_tag>
|
||||
, mpl::identity<null_category_tag>
|
||||
, error_iterator_tag
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// For compilers not supporting is_convertible this only
|
||||
// works with the new boost return and traversal category
|
||||
// types. The exact boost _types_ are required. No derived types
|
||||
// will work.
|
||||
//
|
||||
//
|
||||
template <class T1, class T2>
|
||||
struct minimum_category
|
||||
: mpl::apply_if<
|
||||
is_tag<T1,T2>
|
||||
, mpl::identity<T1>
|
||||
, mpl::if_<
|
||||
is_tag<T2, T1>
|
||||
, T2
|
||||
, error_type
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct minimum_category<int, int> { typedef minimum_category type; };
|
||||
# endif
|
||||
|
||||
//
|
||||
// Tag classification for use in iterator_adaptor
|
||||
//
|
||||
template <class Tag>
|
||||
struct is_access_tag
|
||||
: mpl::or_<
|
||||
is_tag<readable_iterator_tag, Tag>
|
||||
, mpl::or_<
|
||||
is_tag<writable_iterator_tag, Tag>
|
||||
, is_tag<swappable_iterator_tag, Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct is_traversal_tag
|
||||
: is_tag<incrementable_traversal_tag, Tag>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
#error obsolete
|
||||
|
@ -18,7 +18,66 @@
|
||||
#include <boost/config.hpp> // for prior
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#define BOOST_ITERATOR_CONFIG_DEF // if you get an error here, you have nested config_def #inclusion.
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# error you have nested config_def #inclusion.
|
||||
#else
|
||||
# define BOOST_ITERATOR_CONFIG_DEF
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
|
||||
|
||||
// Recall that in general, compilers without partial specialization
|
||||
// can't strip constness. Consider counting_iterator, which normally
|
||||
// passes a const Value to iterator_facade. As a result, any code
|
||||
// which makes a std::vector of the iterator's value_type will fail
|
||||
// when its allocator declares functions overloaded on reference and
|
||||
// const_reference (the same type).
|
||||
//
|
||||
// Furthermore, Borland 5.5.1 drops constness in enough ways that we
|
||||
// end up using a proxy for operator[] when we otherwise shouldn't.
|
||||
// Using reference constness gives it an extra hint that it can
|
||||
// return the value_type from operator[] directly, but is not
|
||||
// strictly neccessary. Not sure how best to resolve this one.
|
||||
|
||||
# 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))
|
||||
# define BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
# if 0 // test code
|
||||
struct v {};
|
||||
|
||||
typedef char (&no)[3];
|
||||
|
||||
template <class T>
|
||||
no foo(T const&, ...);
|
||||
|
||||
template <class T>
|
||||
char foo(T&, int);
|
||||
|
||||
|
||||
struct value_iterator
|
||||
{
|
||||
v operator*() const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lvalue_deref_helper
|
||||
{
|
||||
static T& x;
|
||||
enum { value = (sizeof(foo(*x,0)) == 1) };
|
||||
};
|
||||
|
||||
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
|
||||
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \
|
||||
|
@ -18,6 +18,7 @@
|
||||
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
|
||||
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
#undef BOOST_ARG_DEPENDENT_TYPENAME
|
||||
#undef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# undef BOOST_ITERATOR_CONFIG_DEF
|
||||
|
214
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
214
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
@ -0,0 +1,214 @@
|
||||
// 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
|
||||
{
|
||||
// Using inheritance for only input_iterator_tag helps to avoid
|
||||
// ambiguities when a stdlib implementation dispatches on a
|
||||
// function which is overloaded on both input_iterator_tag and
|
||||
// output_iterator_tag, as STLPort does, in its __valid_range
|
||||
// function. I claim it's better to avoid the ambiguity in these
|
||||
// cases.
|
||||
operator std::output_iterator_tag() const
|
||||
{
|
||||
return 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 <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
|
||||
};
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
//
|
||||
// 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>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
98
include/boost/iterator/detail/minimum_category.hpp
Executable file
98
include/boost/iterator/detail/minimum_category.hpp
Executable file
@ -0,0 +1,98 @@
|
||||
// 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 MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// For compilers not supporting is_convertible this only
|
||||
// works with the new boost return and traversal category
|
||||
// types. The exact boost _types_ are required. No derived types
|
||||
// will work.
|
||||
//
|
||||
//
|
||||
template <bool GreaterEqual, bool LessEqual>
|
||||
struct minimum_category_impl;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct error_not_related_by_convertibility;
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
: error_not_related_by_convertibility<T1,T2>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||
struct minimum_category
|
||||
{
|
||||
typedef minimum_category_impl<
|
||||
::boost::is_convertible<T1,T2>::value
|
||||
, ::boost::is_convertible<T2,T1>::value
|
||||
> outer;
|
||||
|
||||
typedef typename outer::template apply<T1,T2> inner;
|
||||
typedef typename inner::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category<mpl::_1,mpl::_2>
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply : minimum_category<T1,T2>
|
||||
{};
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct minimum_category<int,int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
@ -13,28 +13,42 @@
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
struct filter_iterator_base
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>
|
||||
, Iterator
|
||||
, use_default
|
||||
, typename mpl::if_<
|
||||
is_convertible<
|
||||
typename iterator_traversal<Iterator>::type
|
||||
, bidirectional_traversal_tag
|
||||
>
|
||||
, forward_traversal_tag
|
||||
, use_default
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
>
|
||||
: public detail::filter_iterator_base<Predicate, Iterator>::type
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> super_t;
|
||||
typedef typename detail::filter_iterator_base<
|
||||
Predicate, Iterator
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
|
@ -4,16 +4,19 @@
|
||||
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
// should be the last #include
|
||||
// should be the last #includes
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
@ -122,7 +125,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 +138,13 @@ 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>
|
||||
#include <boost/type_traits/detail/bool_trait_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,12 +26,32 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
#else
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@ -142,63 +162,51 @@ namespace boost
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value
|
||||
, class Category
|
||||
, class Traversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_adaptor_base
|
||||
{
|
||||
private: // intermediate results
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::or_<
|
||||
is_same<Category, use_default>
|
||||
, mpl::or_<
|
||||
is_access_tag<Category>
|
||||
, is_traversal_tag<Category>
|
||||
>
|
||||
>
|
||||
, BOOST_ITERATOR_CATEGORY<Base>
|
||||
, mpl::identity<Category>
|
||||
>::type category;
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value, use_default>
|
||||
, iterator_reference<Base>
|
||||
, mpl::identity<Value&>
|
||||
>
|
||||
>::type reference;
|
||||
|
||||
public: // return type
|
||||
typedef iterator_facade<
|
||||
Derived
|
||||
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
, typename detail::ia_dflt_help<
|
||||
Value
|
||||
, mpl::apply_if<
|
||||
is_same<Reference,use_default>
|
||||
, iterator_value<Base>
|
||||
, remove_reference<Reference>
|
||||
>
|
||||
>::type
|
||||
# else
|
||||
, typename detail::ia_dflt_help<
|
||||
Value, iterator_value<Base>
|
||||
>::type
|
||||
# endif
|
||||
|
||||
, typename mpl::apply_if<
|
||||
is_access_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, access_category_tag<category, reference>
|
||||
, typename detail::ia_dflt_help<
|
||||
Traversal
|
||||
, iterator_traversal<Base>
|
||||
>::type
|
||||
|
||||
, typename mpl::apply_if<
|
||||
is_traversal_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, traversal_category_tag<category>
|
||||
, typename detail::ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value,use_default>
|
||||
, iterator_reference<Base>
|
||||
, add_reference<Value>
|
||||
>
|
||||
>::type
|
||||
|
||||
, reference
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Difference, iterator_difference<Base>
|
||||
>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
template <class T> int static_assert_convertible_to(T);
|
||||
}
|
||||
|
||||
//
|
||||
@ -215,8 +223,8 @@ namespace boost
|
||||
// const. If const, a conforming compiler strips constness for the
|
||||
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||
//
|
||||
// Category - the iterator_category of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::iterator_category is used.
|
||||
// Category - the traversal category of the resulting iterator. If not
|
||||
// supplied, iterator_traversal<Base>::type is used.
|
||||
//
|
||||
// Reference - the reference type of the resulting iterator, and in
|
||||
// particular, the result type of operator*(). If not supplied but
|
||||
@ -230,19 +238,19 @@ namespace boost
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Traversal = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Difference
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
typedef typename detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Difference
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type super_t;
|
||||
|
||||
public:
|
||||
@ -288,16 +296,17 @@ 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(
|
||||
(detail::is_tag<
|
||||
random_access_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::value)
|
||||
);
|
||||
# endif
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
|
||||
m_iterator += n;
|
||||
}
|
||||
|
||||
@ -305,14 +314,7 @@ namespace boost
|
||||
|
||||
void decrement()
|
||||
{
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::is_tag<
|
||||
bidirectional_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::value)
|
||||
);
|
||||
# endif
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
|
||||
--m_iterator;
|
||||
}
|
||||
|
||||
@ -322,12 +324,7 @@ namespace boost
|
||||
typename super_t::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::is_tag<
|
||||
random_access_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::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 +332,8 @@ namespace boost
|
||||
return y.base() - m_iterator;
|
||||
}
|
||||
|
||||
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
|
||||
|
||||
private: // data members
|
||||
Base m_iterator;
|
||||
};
|
||||
|
@ -8,29 +8,75 @@
|
||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||
#include <boost/mpl/bitand.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
namespace boost {
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
|
||||
namespace iterator_archetypes
|
||||
{
|
||||
enum {
|
||||
readable_iterator_bit = 1
|
||||
, writable_iterator_bit = 2
|
||||
, swappable_iterator_bit = 4
|
||||
, lvalue_iterator_bit = 8
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
// Not quite tags, since dispatching wouldn't work.
|
||||
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
|
||||
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|writable_iterator_bit)
|
||||
>::type readable_writable_iterator_t;
|
||||
|
||||
namespace detail {
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|lvalue_iterator_bit)
|
||||
>::type readable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(lvalue_iterator_bit|writable_iterator_bit)
|
||||
>::type writable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
|
||||
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
|
||||
|
||||
template <class Derived, class Base>
|
||||
struct has_access
|
||||
: mpl::equal_to<
|
||||
mpl::bitand_<Derived,Base>
|
||||
, Base
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
@ -38,12 +84,18 @@ namespace boost
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy :
|
||||
assign_proxy<T>
|
||||
struct read_proxy
|
||||
{
|
||||
operator T();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy
|
||||
: assign_proxy<T>
|
||||
, read_proxy<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
@ -55,7 +107,7 @@ namespace boost
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
ValueType operator[](std::ptrdiff_t n) const;
|
||||
read_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
@ -65,16 +117,29 @@ namespace boost
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets :
|
||||
mpl::if_< is_tag<random_access_traversal_tag, TraversalCategory>,
|
||||
mpl::if_< is_tag<writable_iterator_tag, AccessCategory>,
|
||||
writable_operator_brackets< Value >,
|
||||
mpl::if_< is_tag<readable_iterator_tag, AccessCategory>,
|
||||
readable_operator_brackets<Value>,
|
||||
no_operator_brackets > >,
|
||||
no_operator_brackets >::type
|
||||
{
|
||||
};
|
||||
struct operator_brackets
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename mpl::apply_if<
|
||||
is_convertible<TraversalCategory, random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, mpl::identity<writable_operator_brackets<Value> >
|
||||
, mpl::if_<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
, readable_operator_brackets<Value>
|
||||
, no_operator_brackets
|
||||
>
|
||||
>
|
||||
, mpl::identity<no_operator_brackets>
|
||||
>::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
@ -188,28 +253,32 @@ namespace boost
|
||||
bogus_type >
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class> struct undefined;
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct access_archetype_impl
|
||||
{
|
||||
template <class AccessCategory>
|
||||
struct iterator_access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype
|
||||
template <class Value, class AccessCategory>
|
||||
struct iterator_access_archetype
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename access_archetype_impl<AccessCategory>::template archetype<Value>
|
||||
typename iterator_access_archetype_impl<
|
||||
AccessCategory
|
||||
>::template archetype<Value>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_iterator_tag>
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
@ -221,11 +290,13 @@ namespace boost
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<writable_iterator_tag>
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
@ -238,54 +309,62 @@ namespace boost
|
||||
|
||||
detail::assign_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_writable_iterator_tag>
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef detail::read_write_proxy<Value> reference;
|
||||
|
||||
detail::read_write_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_lvalue_iterator_tag>
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef Value& reference;
|
||||
|
||||
Value& operator*() const;
|
||||
Value* operator->() const;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<writable_lvalue_iterator_tag>
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_lvalue_iterator_tag>
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_lvalue_iterator_t
|
||||
>
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||
# endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
: detail::operator_brackets<
|
||||
typename remove_cv<Value>::type
|
||||
, AccessCategory
|
||||
@ -296,45 +375,74 @@ namespace boost
|
||||
, Value
|
||||
, TraversalCategory
|
||||
>
|
||||
{
|
||||
};
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
, public access_archetype<Value, AccessCategory>
|
||||
struct iterator_archetype_base
|
||||
: iterator_access_archetype<Value, AccessCategory>
|
||||
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
{
|
||||
typedef iterator_access_archetype<Value, AccessCategory> access;
|
||||
|
||||
typedef typename detail::facade_iterator_category<
|
||||
TraversalCategory
|
||||
, typename mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, remove_const<Value>
|
||||
, add_const<Value>
|
||||
>::type
|
||||
, typename access::reference
|
||||
>::type iterator_category;
|
||||
|
||||
// Needed for some broken libraries (see below)
|
||||
typedef boost::iterator<
|
||||
iterator_category
|
||||
, Value
|
||||
, typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type
|
||||
, typename access::pointer
|
||||
, typename access::reference
|
||||
> workaround_iterator_base;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
, public std::iterator<
|
||||
iterator_tag<AccessCategory,TraversalCategory>
|
||||
, typename access_archetype<Value, AccessCategory>::value_type
|
||||
, typename traversal_archetype_base<
|
||||
, public detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type
|
||||
>
|
||||
>::workaround_iterator_base
|
||||
# endif
|
||||
{
|
||||
// Derivation from std::iterator above caused ambiguity, so now
|
||||
// we have to declare all the types here.
|
||||
{
|
||||
// Derivation from std::iterator above caused references to nested
|
||||
// types to be ambiguous, so now we have to redeclare them all
|
||||
// here.
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
||||
|
||||
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
|
||||
typedef detail::iterator_archetype_base<
|
||||
Value,AccessCategory,TraversalCategory
|
||||
> base;
|
||||
|
||||
typedef typename access_archetype<Value, AccessCategory>::reference reference;
|
||||
|
||||
typedef typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type difference_type;
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator_category iterator_category;
|
||||
# endif
|
||||
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
|
||||
iterator_archetype();
|
||||
iterator_archetype(iterator_archetype const&);
|
||||
|
||||
@ -342,7 +450,7 @@ namespace boost
|
||||
|
||||
// Optional conversion from mutable
|
||||
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -4,426 +4,160 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// TODO:
|
||||
// Add separate category tag for operator[].
|
||||
|
||||
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
|
||||
#define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
# define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/detail/categories.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/detail/workaround.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/apply.hpp>
|
||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||
#ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
#endif
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
#include <iterator>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
|
||||
#endif
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// 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>
|
||||
{
|
||||
};
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
struct incrementable_traversal_tag {};
|
||||
|
||||
// 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
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
struct single_pass_traversal_tag
|
||||
: incrementable_traversal_tag {};
|
||||
|
||||
// std_to_new_tags --
|
||||
struct forward_traversal_tag
|
||||
: single_pass_traversal_tag {};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag {};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag {};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// A metafunction which converts any standard tag into its
|
||||
// corresponding new-style traversal tag.
|
||||
// Convert a "strictly old-style" iterator category to a traversal
|
||||
// tag. This is broken out into a separate metafunction to reduce
|
||||
// the cost of instantiating iterator_category_to_traversal, below,
|
||||
// for new-style types.
|
||||
//
|
||||
// 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_traversal_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::identity<readable_iterator_tag> {};
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::output_iterator_tag>
|
||||
{
|
||||
typedef incrementable_traversal_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
|
||||
// something less sophisticated.
|
||||
//
|
||||
// The solution depends on the fact that only
|
||||
// std iterator categories work with is_xxx_iterator
|
||||
// meta functions, as BOOST_NO_IS_CONVERTIBLE is
|
||||
// defined for cwpro7.
|
||||
//
|
||||
template <class 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) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: is_boost_iterator_tag<Tag>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal)
|
||||
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: mpl::if_<
|
||||
is_class<Tag>
|
||||
, has_traversal<Tag>
|
||||
, mpl::false_
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class NewCategoryTag>
|
||||
struct get_traversal_category {
|
||||
typedef typename NewCategoryTag::traversal type;
|
||||
};
|
||||
|
||||
// Remove all writability from the given access tag. This
|
||||
// functionality is part of new_category_to_access in order to
|
||||
// support deduction of the proper default access category for
|
||||
// iterator_adaptor; when the reference type is a reference to
|
||||
// constant we must strip writability.
|
||||
template <class AccessTag>
|
||||
struct remove_access_writability
|
||||
template <class Cat>
|
||||
struct old_category_to_traversal
|
||||
: mpl::apply_if<
|
||||
is_tag<writable_lvalue_iterator_tag, AccessTag>
|
||||
, mpl::identity<readable_lvalue_iterator_tag>
|
||||
|
||||
is_convertible<Cat,std::random_access_iterator_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_tag<readable_writable_iterator_tag, AccessTag>
|
||||
, mpl::identity<readable_iterator_tag>
|
||||
|
||||
, mpl::if_<
|
||||
is_tag<writable_iterator_tag, AccessTag>
|
||||
// Is this OK? I think it may correct be for all
|
||||
// legitimate cases, because at this point the
|
||||
// iterator is not readable, so it could not have
|
||||
// been any more than writable + swappable.
|
||||
, swappable_iterator_tag
|
||||
, AccessTag
|
||||
is_convertible<Cat,std::bidirectional_iterator_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::forward_iterator_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::input_iterator_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::output_iterator_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class NewCategoryTag, class Reference>
|
||||
struct new_category_to_access
|
||||
: mpl::apply_if<
|
||||
python::detail::is_reference_to_const<Reference>
|
||||
, remove_access_writability<typename NewCategoryTag::access>
|
||||
, mpl::identity<typename NewCategoryTag::access>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class CategoryTag, class Reference>
|
||||
struct access_category_tag
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, new_category_to_access<CategoryTag, Reference>
|
||||
, iter_category_to_access<CategoryTag, Reference>
|
||||
>
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct old_category_to_traversal<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template <class CategoryTag>
|
||||
struct traversal_category_tag
|
||||
: 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> { typedef void type; };
|
||||
template <> struct traversal_category_tag<int> { typedef void type; };
|
||||
# endif
|
||||
|
||||
// iterator_tag_base - a metafunction to compute the appropriate
|
||||
// old-style tag (if any) to use as a base for a new-style tag.
|
||||
template <class KnownAccessTag, class KnownTraversalTag>
|
||||
struct iterator_tag_base
|
||||
: minimum_category<
|
||||
typename KnownAccessTag::max_category
|
||||
, typename KnownTraversalTag::max_category
|
||||
template <class Traversal>
|
||||
struct pure_traversal_tag
|
||||
: mpl::apply_if<
|
||||
is_convertible<Traversal,random_access_traversal_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,forward_traversal_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,single_pass_traversal_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,incrementable_traversal_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
{};
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC,<=1200)
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct iterator_tag_base<int,int>
|
||||
: mpl::false_ {}; // just using false_ so that the result will be
|
||||
// a legal base class
|
||||
struct pure_traversal_tag<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
// specialization for this special case. Otherwise we get
|
||||
// input_output_iterator_tag, because the standard hierarchy has a
|
||||
// sudden anomalous distinction between readability and
|
||||
// writability at the level of input iterator/output iterator.
|
||||
template <>
|
||||
struct iterator_tag_base<
|
||||
readable_lvalue_iterator_tag,single_pass_traversal_tag>
|
||||
{
|
||||
typedef std::input_iterator_tag type;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Iterator>
|
||||
struct access_category
|
||||
: detail::access_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
, typename detail::iterator_traits<Iterator>::reference>
|
||||
{};
|
||||
|
||||
template <class Iterator>
|
||||
struct traversal_category
|
||||
: detail::traversal_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
//
|
||||
// Convert an iterator category into a traversal tag
|
||||
//
|
||||
template <class Cat>
|
||||
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_category_to_traversal<Cat>
|
||||
>
|
||||
{
|
||||
};
|
||||
{};
|
||||
|
||||
// Trait to get an iterator's traversal category
|
||||
template <class Iterator = mpl::_1>
|
||||
struct iterator_traversal
|
||||
: iterator_category_to_traversal<
|
||||
typename boost::detail::iterator_traits<Iterator>::iterator_category
|
||||
>
|
||||
{};
|
||||
|
||||
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template <>
|
||||
struct access_category<mpl::_1>
|
||||
{
|
||||
struct iterator_traversal<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : access_category<T>
|
||||
struct apply : iterator_traversal<T>
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_category<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : traversal_category<T>
|
||||
{};
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct iterator_traversal<mpl::_>
|
||||
: iterator_traversal<mpl::_1>
|
||||
{};
|
||||
# endif
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct access_category<T*>
|
||||
: mpl::if_<
|
||||
is_const<T>
|
||||
, readable_lvalue_iterator_tag
|
||||
, writable_lvalue_iterator_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag
|
||||
: detail::iterator_tag_base<
|
||||
typename detail::max_known_access_tag<AccessTag>::type
|
||||
, typename detail::max_known_traversal_tag<TraversalTag>::type
|
||||
>::type
|
||||
{
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag
|
||||
: mpl::false_ {};
|
||||
|
||||
template <class R, class T>
|
||||
struct is_boost_iterator_tag<iterator_tag<R,T> >
|
||||
: mpl::true_ {};
|
||||
# else
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag
|
||||
{
|
||||
typedef char (&yes)[1];
|
||||
typedef char (&no)[2];
|
||||
|
||||
template <class R, class U>
|
||||
static yes test(mpl::identity<iterator_tag<R,U> >*);
|
||||
static no test(...);
|
||||
|
||||
static mpl::identity<T>* inst;
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
@ -15,16 +15,20 @@
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// Use boost/limits to work around missing limits headers on some compilers
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
@ -56,7 +60,6 @@ namespace boost_concepts {
|
||||
public:
|
||||
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> >();
|
||||
@ -64,8 +67,6 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_iterator_tag, access_category>::value));
|
||||
|
||||
reference r = *i; // or perhaps read(x)
|
||||
value_type v(r);
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
@ -73,10 +74,12 @@ namespace boost_concepts {
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename ValueType>
|
||||
template <
|
||||
typename Iterator
|
||||
, typename ValueType = typename boost::detail::iterator_traits<Iterator>::value_type
|
||||
>
|
||||
class WritableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
@ -84,8 +87,6 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_iterator_tag, access_category>::value));
|
||||
|
||||
*i = v; // a good alternative could be something like write(x, v)
|
||||
}
|
||||
ValueType v;
|
||||
@ -95,11 +96,8 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class SwappableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::swappable_iterator_tag, access_category>::value));
|
||||
|
||||
std::iter_swap(i1, i2);
|
||||
}
|
||||
Iterator i1;
|
||||
@ -107,20 +105,20 @@ namespace boost_concepts {
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ReadableLvalueIteratorConcept {
|
||||
class ReadableLvalueIteratorConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
void constraints()
|
||||
{
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_lvalue_iterator_tag, access_category>::value));
|
||||
|
||||
typedef boost::mpl::or_<
|
||||
boost::is_same<reference, value_type&>,
|
||||
boost::is_same<reference, value_type const&> > correct_reference;
|
||||
boost::is_same<reference, value_type&>
|
||||
, boost::is_same<reference, value_type const&>
|
||||
> correct_reference;
|
||||
|
||||
BOOST_STATIC_ASSERT(correct_reference::value);
|
||||
|
||||
@ -135,7 +133,6 @@ 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::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires<
|
||||
@ -145,7 +142,6 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
SwappableIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_lvalue_iterator_tag, access_category>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||
}
|
||||
@ -157,14 +153,19 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class IncrementableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::incrementable_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::incrementable_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
++i;
|
||||
(void)i++;
|
||||
@ -175,21 +176,26 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class SinglePassIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::single_pass_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::single_pass_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ForwardTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
@ -201,19 +207,29 @@ namespace boost_concepts {
|
||||
> difference_type_is_signed_integral;
|
||||
|
||||
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::forward_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::forward_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class BidirectionalTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ForwardTraversalConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::bidirectional_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
--i;
|
||||
(void)i--;
|
||||
@ -224,14 +240,19 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class RandomAccessTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::random_access_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::random_access_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
i += n;
|
||||
i = i + n;
|
||||
@ -326,11 +347,11 @@ namespace detail
|
||||
class InteroperableConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
typedef typename boost::traversal_category<ConstIterator>::type
|
||||
typedef typename boost::iterator_traversal<ConstIterator>::type
|
||||
const_traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
||||
const_difference_type;
|
||||
|
@ -12,15 +12,17 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/interoperable.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.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>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
@ -30,21 +32,7 @@ namespace boost
|
||||
{
|
||||
// This forward declaration is required for the friend declaration
|
||||
// in iterator_core_access
|
||||
template <class I, class V, class AC, class TC, 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
|
||||
template <class I, class V, class TC, class R, class D> class iterator_facade;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@ -75,58 +63,29 @@ namespace boost
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Add const qualification for iterators which are not writable
|
||||
//
|
||||
template<class Value, class AccessCategory>
|
||||
struct const_qualified_ref :
|
||||
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||
Value&,
|
||||
Value const& >
|
||||
{};
|
||||
|
||||
// The apparent duplication here works around a Borland problem
|
||||
template<class Value, class AccessCategory>
|
||||
struct const_qualified_ptr :
|
||||
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||
Value*,
|
||||
Value const* >
|
||||
{};
|
||||
|
||||
//
|
||||
// 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 AccessCategory
|
||||
, class TraversalCategory
|
||||
class ValueParam
|
||||
, class CategoryOrTraversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_facade_types
|
||||
{
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
typedef typename facade_iterator_category<
|
||||
CategoryOrTraversal, ValueParam, Reference
|
||||
>::type iterator_category;
|
||||
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef typename remove_const<ValueParam>::type value_type;
|
||||
|
||||
typedef Difference difference_type;
|
||||
|
||||
typedef typename const_qualified_ptr<Value, AccessCategory>::type pointer;
|
||||
|
||||
// The use_default support is needed for iterator_adaptor.
|
||||
// For practical reasons iterator_adaptor needs to specify
|
||||
// a fixed number of template arguments of iterator_facade.
|
||||
// So use_default is its way to say: "What I really mean
|
||||
// is your default parameter".
|
||||
typedef typename mpl::if_<
|
||||
is_same<Reference, use_default>
|
||||
, typename const_qualified_ref<Value, AccessCategory>::type
|
||||
, Reference
|
||||
>::type reference;
|
||||
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)) \
|
||||
@ -141,7 +100,7 @@ namespace boost
|
||||
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
|
||||
|
||||
typedef
|
||||
iterator<iterator_category, value_type, difference_type, pointer, reference>
|
||||
iterator<iterator_category, value_type, Difference, pointer, Reference>
|
||||
base;
|
||||
# endif
|
||||
};
|
||||
@ -208,7 +167,7 @@ namespace boost
|
||||
: m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference()
|
||||
operator reference() const
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
@ -223,28 +182,24 @@ namespace boost
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
template <class Iterator, class ValueType, class Category, class Reference>
|
||||
template <class Iterator, class Value, class Reference>
|
||||
struct operator_brackets_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
|
||||
iterator_writability_disabled<Value,Reference>
|
||||
, Value
|
||||
, operator_brackets_proxy<Iterator>
|
||||
, ValueType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||
{
|
||||
return operator_brackets_proxy<Iterator>(iter);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
@ -255,18 +210,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 AC1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class AC2, class TC2, class R2, class D2 \
|
||||
class Derived1, class V1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class TC2, class R2, class D2 \
|
||||
> \
|
||||
prefix typename detail::enable_if_interoperable< \
|
||||
Derived1, Derived2, result_type \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, AC1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, AC2, TC2, R2, D2> const& rhs)
|
||||
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template <class Derived, class V, class AC, class TC, class R, class D> \
|
||||
template <class Derived, class V, class TC, class R, class D> \
|
||||
prefix Derived operator+ args
|
||||
|
||||
//
|
||||
@ -287,7 +242,7 @@ namespace boost
|
||||
public:
|
||||
# else
|
||||
|
||||
template <class I, class V, class AC, class TC, class R, class D> friend class iterator_facade;
|
||||
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
|
||||
@ -307,7 +262,7 @@ namespace boost
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (iterator_facade<Derived, V, AC, TC, R, D> const&
|
||||
, (iterator_facade<Derived, V, TC, R, D> const&
|
||||
, typename Derived::difference_type)
|
||||
)
|
||||
;
|
||||
@ -315,7 +270,7 @@ namespace boost
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (typename Derived::difference_type
|
||||
, iterator_facade<Derived, V, AC, TC, R, D> const&)
|
||||
, iterator_facade<Derived, V, TC, R, D> const&)
|
||||
)
|
||||
;
|
||||
|
||||
@ -370,26 +325,21 @@ namespace boost
|
||||
template <
|
||||
class Derived // The derived iterator type being constructed
|
||||
, class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference = BOOST_DEDUCED_TYPENAME detail::const_qualified_ref<Value, AccessCategory>::type
|
||||
, 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, AccessCategory, TraversalCategory, Reference, Difference
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
>::base
|
||||
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||
# endif
|
||||
{
|
||||
private:
|
||||
typedef typename
|
||||
detail::iterator_facade_types<Value, AccessCategory, TraversalCategory, Reference, Difference>
|
||||
types;
|
||||
|
||||
//
|
||||
// Curiously Recursive Template interface.
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
typedef Derived derived_t;
|
||||
|
||||
@ -403,13 +353,17 @@ namespace boost
|
||||
return static_cast<Derived const&>(*this);
|
||||
}
|
||||
|
||||
typedef detail::iterator_facade_types<
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
> associated_types;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename types::value_type value_type;
|
||||
typedef typename types::reference reference;
|
||||
typedef typename types::difference_type difference_type;
|
||||
typedef typename types::pointer pointer;
|
||||
typedef typename types::iterator_category iterator_category;
|
||||
typedef typename associated_types::value_type value_type;
|
||||
typedef Reference reference;
|
||||
typedef Difference difference_type;
|
||||
typedef typename associated_types::pointer pointer;
|
||||
typedef typename associated_types::iterator_category iterator_category;
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
@ -430,14 +384,16 @@ namespace boost
|
||||
>::make(*this->derived());
|
||||
}
|
||||
|
||||
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
|
||||
typename detail::operator_brackets_result<Derived,Value,Reference>::type
|
||||
operator[](difference_type n) const
|
||||
{
|
||||
typedef typename
|
||||
detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::use_proxy
|
||||
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++()
|
||||
@ -615,13 +571,13 @@ namespace boost
|
||||
}
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||
iterator_facade<Derived, V, TC, R, D> const& i
|
||||
, typename Derived::difference_type n
|
||||
))
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
typename Derived::difference_type n
|
||||
, iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||
, iterator_facade<Derived, V, TC, R, D> const& i
|
||||
))
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||
|
@ -24,15 +24,13 @@
|
||||
# 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>
|
||||
|
||||
# include <boost/iterator/detail/config_def.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 +43,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 +56,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 +66,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 +77,14 @@ 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());
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||
@ -91,11 +92,17 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
|
||||
T& v3 = *i2;
|
||||
assert(v1 == v3);
|
||||
|
||||
// A non-const lvalue iterator is not neccessarily writable, but we
|
||||
// are assuming the value_type is assignable here
|
||||
*i = v2;
|
||||
|
||||
T& v4 = *i2;
|
||||
assert(v2 == v4);
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_mutable_lvalue(result_category());
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
@ -159,7 +166,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||
readable_iterator_test(i2, v2);
|
||||
}
|
||||
|
||||
|
||||
// random access
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
@ -169,10 +175,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == j[c]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[c];
|
||||
assert(*i == x);
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
@ -183,10 +191,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == j[N - 1 - c]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
|
||||
assert(*i == x);
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
@ -197,8 +207,8 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
}
|
||||
}
|
||||
|
||||
// #if 0'd code snipped; see CVS v 1.4 if you need it back
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||
@ -46,52 +48,37 @@ namespace boost
|
||||
};
|
||||
#endif
|
||||
|
||||
// Given the transform iterator's transformation and iterator, this
|
||||
// is the type used as its traits.
|
||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||
struct transform_iterator_base
|
||||
{
|
||||
private:
|
||||
|
||||
// transform_iterator does not support writable/swappable iterators
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
||||
#endif
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
is_same< Reference, use_default >
|
||||
// By default, dereferencing the iterator yields the same as
|
||||
// the function. Do we need to adjust the way
|
||||
// function_object_result is computed for the standard
|
||||
// proposal (e.g. using Doug's result_of)?
|
||||
typedef typename ia_dflt_help<
|
||||
Reference
|
||||
, function_object_result<UnaryFunction>
|
||||
, mpl::identity<Reference>
|
||||
>::type result_type;
|
||||
>::type reference;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_same< Value, use_default >
|
||||
, typename remove_reference< result_type >::type
|
||||
, Value
|
||||
// To get the default for Value: remove any reference on the
|
||||
// result type, but retain any constness to signal
|
||||
// non-writability. Note that if we adopt Thomas' suggestion
|
||||
// to key non-writability *only* on the Reference argument,
|
||||
// we'd need to strip constness here as well.
|
||||
typedef typename ia_dflt_help<
|
||||
Value
|
||||
, remove_reference<reference>
|
||||
>::type cv_value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_reference< result_type >
|
||||
, typename mpl::if_<
|
||||
is_const< cv_value_type >
|
||||
, readable_lvalue_iterator_tag
|
||||
, writable_lvalue_iterator_tag
|
||||
>::type
|
||||
, readable_iterator_tag
|
||||
>::type maximum_access_tag;
|
||||
|
||||
typedef typename minimum_category<
|
||||
maximum_access_tag
|
||||
, typename access_category<Iterator>::type
|
||||
>::type access_category;
|
||||
|
||||
public:
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, access_category
|
||||
, result_type
|
||||
, use_default // Leave the traversal category alone
|
||||
, reference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
@ -150,12 +137,16 @@ namespace boost
|
||||
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
||||
}
|
||||
|
||||
// Version which allows explicit specification of the UnaryFunction
|
||||
// type.
|
||||
//
|
||||
// This generator is not provided if UnaryFunction is a function
|
||||
// pointer type, because it's too dangerous: the default-constructed
|
||||
// function pointer in the iterator be 0, leading to a runtime
|
||||
// crash.
|
||||
template <class UnaryFunction, class Iterator>
|
||||
// don't provide this generator if UnaryFunction is a
|
||||
// function pointer type. Too dangerous. We should probably
|
||||
// find a cheaper test than is_class<>
|
||||
typename iterators::enable_if<
|
||||
is_class<UnaryFunction>
|
||||
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
|
||||
, transform_iterator<UnaryFunction, Iterator>
|
||||
>::type
|
||||
make_transform_iterator(Iterator it)
|
||||
@ -174,4 +165,6 @@ namespace boost
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/minimum_category.hpp>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
@ -259,16 +261,17 @@ namespace boost {
|
||||
)
|
||||
{
|
||||
typedef typename tuple_meta_transform<
|
||||
typename Tuple::tail_type
|
||||
BOOST_DEDUCED_TYPENAME Tuple::tail_type
|
||||
, Fun
|
||||
>::type transformed_tail_type;
|
||||
|
||||
return tuples::cons<
|
||||
typename mpl::apply1<Fun, typename Tuple::head_type>::type
|
||||
BOOST_DEDUCED_TYPENAME mpl::apply1<
|
||||
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
|
||||
>::type
|
||||
, transformed_tail_type
|
||||
>(
|
||||
f(boost::tuples::get<0>(t)),
|
||||
tuple_transform(t.get_tail(), f)
|
||||
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
|
||||
);
|
||||
}
|
||||
|
||||
@ -380,12 +383,12 @@ namespace boost {
|
||||
{
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple
|
||||
, traversal_category<mpl::_1>
|
||||
, iterator_traversal<>
|
||||
>::type tuple_of_traversal_tags;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
tuple_of_traversal_tags
|
||||
, minimum_category<mpl::_1,mpl::_2>
|
||||
, minimum_category<>
|
||||
, random_access_traversal_tag
|
||||
>::type type;
|
||||
};
|
||||
@ -398,31 +401,6 @@ namespace boost {
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename Iterator>
|
||||
struct iterator_is_readable
|
||||
: is_tag<
|
||||
readable_iterator_tag
|
||||
, typename access_category<Iterator>::type
|
||||
>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1, iterator_is_readable, (Iterator))
|
||||
};
|
||||
|
||||
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template <>
|
||||
struct iterator_is_readable<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : iterator_is_readable<T>
|
||||
{};
|
||||
};
|
||||
# endif
|
||||
|
||||
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
||||
// accumulating functor. To this end, we need to wrap it into
|
||||
// a struct that has exactly two arguments (that is, template
|
||||
@ -446,28 +424,6 @@ namespace boost {
|
||||
};
|
||||
# endif
|
||||
|
||||
// Metafunction to assert that all iterators in a tuple are
|
||||
// readable.
|
||||
//
|
||||
// Probably not worth it, IMO. Why not a writable zip_iterator
|
||||
// anyway? -- dwa.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct all_iterators_in_tuple_readable
|
||||
{
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple,
|
||||
iterator_is_readable<mpl::_1>
|
||||
>::type tuple_of_readability_bools;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
tuple_of_readability_bools,
|
||||
and_with_two_args<mpl::_1,mpl::_2>
|
||||
, mpl::bool_<true>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class zip_iterator_base
|
||||
@ -479,14 +435,6 @@ namespace boost {
|
||||
struct zip_iterator_base
|
||||
{
|
||||
private:
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// seems to give vc7's parser fits, and vc6 needs help here too
|
||||
BOOST_STATIC_ASSERT(
|
||||
detail::all_iterators_in_tuple_readable<
|
||||
IteratorTuple
|
||||
>::type::value
|
||||
);
|
||||
#endif
|
||||
// Reference type is the type of the tuple obtained from the
|
||||
// iterators' reference types.
|
||||
typedef typename
|
||||
@ -506,11 +454,6 @@ namespace boost {
|
||||
detail::minimum_traversal_category_in_iterator_tuple<
|
||||
IteratorTuple
|
||||
>::type traversal_category;
|
||||
|
||||
// Access category is readable_iterator_tag. It has been
|
||||
// asserted that all iterators in the tuple are readable.
|
||||
typedef readable_iterator_tag access_category;
|
||||
|
||||
public:
|
||||
|
||||
// The iterator facade type from which the zip iterator will
|
||||
@ -518,7 +461,6 @@ namespace boost {
|
||||
typedef iterator_facade<
|
||||
zip_iterator<IteratorTuple>,
|
||||
value_type,
|
||||
access_category,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
@ -616,7 +558,7 @@ namespace boost {
|
||||
{
|
||||
detail::tuple_impl_specific::tuple_for_each(
|
||||
m_iterator_tuple,
|
||||
detail::advance_iterator<typename super_t::difference_type>(n)
|
||||
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
|
||||
);
|
||||
}
|
||||
// Incrementing a zip iterator means to increment all iterators in
|
||||
|
@ -18,6 +18,8 @@ test-suite iterator
|
||||
# compilation problems.
|
||||
[ run is_convertible_fail.cpp ]
|
||||
|
||||
[ run zip_iterator_test.cpp ]
|
||||
|
||||
# These tests should work for just about everything.
|
||||
[ compile is_lvalue_iterator.cpp ]
|
||||
[ compile is_readable_iterator.cpp ]
|
||||
@ -34,8 +36,6 @@ test-suite iterator
|
||||
[ run counting_iterator_test.cpp ]
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
]
|
||||
[ compile iterator_categories.cpp ]
|
||||
[ run zip_iterator_test.cpp ]
|
||||
|
||||
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
||||
[ run ../../utility/counting_iterator_example.cpp ]
|
||||
|
@ -5,15 +5,16 @@
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/iterator/iterator_concepts.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp> // remove
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include "static_assert_same.hpp" // remove
|
||||
|
||||
struct new_random_access
|
||||
: std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
{};
|
||||
|
||||
struct new_iterator
|
||||
: public boost::iterator< boost::iterator_tag<
|
||||
boost::writable_lvalue_iterator_tag
|
||||
, boost::random_access_traversal_tag>, int>
|
||||
: public boost::iterator< new_random_access, int >
|
||||
{
|
||||
int& operator*() const { return *m_x; }
|
||||
new_iterator& operator++() { return *this; }
|
||||
@ -52,102 +53,12 @@ struct old_iterator
|
||||
};
|
||||
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
||||
|
||||
struct my_writable_lvalue_iterator_tag
|
||||
{
|
||||
operator boost::writable_lvalue_iterator_tag() const;
|
||||
};
|
||||
|
||||
struct my_single_pass_traversal_tag
|
||||
{
|
||||
operator boost::single_pass_traversal_tag() const;
|
||||
};
|
||||
|
||||
void test_tag_convertibility()
|
||||
{
|
||||
// This set of tests is by no means complete.
|
||||
|
||||
// Test that this is an input/output iterator
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
boost::writable_lvalue_iterator_tag
|
||||
, boost::single_pass_traversal_tag
|
||||
> tag;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
|
||||
// Test that it's possible to build new sub-tags without
|
||||
// derivation. Convertibility should be enough
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
my_writable_lvalue_iterator_tag
|
||||
, my_single_pass_traversal_tag
|
||||
> tag;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
|
||||
// Test that a single-pass readable lvalue iterator is only an
|
||||
// input iterator. Requires special case handling in
|
||||
// categories.hpp
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
boost::readable_lvalue_iterator_tag
|
||||
, boost::single_pass_traversal_tag
|
||||
> tag;
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test_tag_convertibility();
|
||||
|
||||
typedef boost::iterator_tag< boost::writable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag;
|
||||
|
||||
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<tag>::value));
|
||||
int test = static_assert_same<tag::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<tag::traversal, boost::random_access_traversal_tag>::value;
|
||||
|
||||
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<new_iterator::iterator_category>::value));
|
||||
test = static_assert_same<new_iterator::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<new_iterator::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||
|
||||
typedef boost::traversal_category<new_iterator>::type traversal_category;
|
||||
|
||||
// BOOST_STATIC_ASSERT(boost::detail::has_traversal<new_iterator::iterator_category>::value);
|
||||
BOOST_STATIC_ASSERT(boost::detail::is_new_iterator_tag<new_iterator::iterator_category>::value);
|
||||
|
||||
|
||||
test = static_assert_same<traversal_category, boost::random_access_traversal_tag>::value;
|
||||
(void)test;
|
||||
boost::iterator_traversal<new_iterator>::type tc;
|
||||
boost::random_access_traversal_tag derived = tc;
|
||||
(void)derived;
|
||||
|
||||
boost::function_requires<
|
||||
boost_concepts::WritableLvalueIteratorConcept<int*> >();
|
||||
|
@ -7,13 +7,12 @@
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/iterator/new_iterator_tests.hpp>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
|
||||
using boost::dummyT;
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
struct one_or_four
|
||||
{
|
||||
@ -38,10 +37,10 @@ int main()
|
||||
filter_iter(one_or_four(), array, array+N)
|
||||
, dummyT(1), dummyT(4));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::detail::is_tag<
|
||||
boost::random_access_traversal_tag
|
||||
, boost::traversal_category<filter_iter>::type
|
||||
BOOST_STATIC_ASSERT(
|
||||
(!boost::is_convertible<
|
||||
boost::iterator_traversal<filter_iter>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
|
@ -46,8 +46,7 @@
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
|
||||
using boost::dummyT;
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<boost::dummyT>)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<dummyT>)
|
||||
|
||||
typedef std::vector<int> storage;
|
||||
typedef std::vector<int*> pointer_ra_container;
|
||||
|
@ -32,12 +32,15 @@ struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::n
|
||||
boost::noncopyable const& operator*() const;
|
||||
};
|
||||
|
||||
struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
|
||||
template <class T>
|
||||
struct proxy_iterator
|
||||
: boost::iterator<std::output_iterator_tag,T>
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
typedef boost::iterator<std::input_iterator_tag,v> base;
|
||||
typedef boost::iterator<std::input_iterator_tag,value_type> base;
|
||||
typedef base::iterator_category iterator_category;
|
||||
typedef base::value_type value_type;
|
||||
typedef base::difference_type difference_type;
|
||||
typedef base::pointer pointer;
|
||||
typedef base::reference reference;
|
||||
@ -45,14 +48,43 @@ struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
|
||||
|
||||
struct proxy
|
||||
{
|
||||
operator v&() const;
|
||||
proxy& operator=(v) const;
|
||||
operator value_type&() const;
|
||||
proxy& operator=(value_type) const;
|
||||
};
|
||||
|
||||
proxy operator*() const;
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy)
|
||||
template <class T>
|
||||
struct lvalue_iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T difference_type;
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T* pointer;
|
||||
|
||||
T& operator*() const;
|
||||
lvalue_iterator& operator++();
|
||||
lvalue_iterator operator++(int);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct constant_lvalue_iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T difference_type;
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T const* pointer;
|
||||
|
||||
T const& operator*() const;
|
||||
constant_lvalue_iterator& operator++();
|
||||
constant_lvalue_iterator operator++(int);
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<v>::proxy)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<int>::proxy)
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -62,7 +94,8 @@ int main()
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
|
||||
#endif
|
||||
@ -70,18 +103,43 @@ int main()
|
||||
// reference binding
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator<v*>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<v const*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator<std::deque<v>::iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<proxy_iterator>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
|
||||
|
||||
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<value_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<noncopyable_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include <numeric>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
# include <boost/iterator/is_readable_iterator.hpp>
|
||||
# include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
#endif
|
||||
#include <boost/pending/iterator_tests.hpp>
|
||||
|
||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
@ -26,7 +30,7 @@
|
||||
|
||||
#include "static_assert_same.hpp"
|
||||
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
@ -83,7 +87,7 @@ struct ptr_iterator
|
||||
ptr_iterator<V>
|
||||
, V*
|
||||
, V
|
||||
, std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
, V&
|
||||
#endif
|
||||
@ -94,7 +98,7 @@ private:
|
||||
ptr_iterator<V>
|
||||
, V*
|
||||
, V
|
||||
, std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
, V&
|
||||
#endif
|
||||
@ -114,13 +118,13 @@ public:
|
||||
};
|
||||
|
||||
// Non-functional iterator for category modification checking
|
||||
template <class Iter, class Category>
|
||||
struct modify_category
|
||||
template <class Iter, class Traversal>
|
||||
struct modify_traversal
|
||||
: boost::iterator_adaptor<
|
||||
modify_category<Iter, Category>
|
||||
modify_traversal<Iter, Traversal>
|
||||
, Iter
|
||||
, boost::use_default
|
||||
, Category
|
||||
, Traversal
|
||||
>
|
||||
{};
|
||||
|
||||
@ -179,6 +183,33 @@ struct constant_iterator
|
||||
: base_t(it) {}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
template <class Iter, class Trav>
|
||||
int static_assert_traversal(Iter* = 0, Trav* = 0)
|
||||
{
|
||||
typedef typename boost::iterator_category_to_traversal<
|
||||
BOOST_DEDUCED_TYPENAME Iter::iterator_category
|
||||
>::type t2;
|
||||
|
||||
return static_assert_same<Trav,t2>::value;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -219,7 +250,17 @@ main()
|
||||
typedef ptr_iterator<int const> Iter1;
|
||||
test = static_assert_same<Iter1::value_type, int>::value;
|
||||
test = static_assert_same<Iter1::reference, const int&>::value;
|
||||
test = static_assert_same<Iter1::iterator_category::access, boost::readable_lvalue_iterator_tag>::value; test = static_assert_same<Iter1::pointer, const int*>::value;
|
||||
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
|
||||
test = static_assert_same<Iter1::pointer, int const*>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -229,19 +270,19 @@ main()
|
||||
|
||||
test = static_assert_same<Iter::value_type, int>::value;
|
||||
test = static_assert_same<Iter::reference, int const&>::value;
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
|
||||
test = static_assert_same<Iter::pointer, int const*>::value;
|
||||
#endif
|
||||
|
||||
test = static_assert_same<BaseIter::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<Iter::iterator_category::access, boost::readable_lvalue_iterator_tag>::value;
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
|
||||
#endif
|
||||
|
||||
// Test category modification
|
||||
typedef modify_category<BaseIter, boost::readable_iterator_tag> ReadableIter;
|
||||
test = static_assert_same<ReadableIter::iterator_category::access, boost::readable_iterator_tag>::value;
|
||||
|
||||
typedef modify_category<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
|
||||
test = static_assert_same<BaseIter::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||
test = static_assert_same<IncrementableIter::iterator_category::traversal, boost::incrementable_traversal_tag>::value;
|
||||
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
|
||||
|
||||
static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
|
||||
static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
|
||||
}
|
||||
|
||||
// Test the iterator_adaptor
|
||||
|
@ -12,14 +12,15 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef boost::iterator_archetype<int,
|
||||
boost::writable_lvalue_iterator_tag,
|
||||
boost::random_access_traversal_tag> iter;
|
||||
typedef boost::iterator_archetype<
|
||||
int
|
||||
, boost::iterator_archetypes::writable_lvalue_iterator_t
|
||||
, boost::random_access_traversal_tag
|
||||
> iter;
|
||||
|
||||
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
||||
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
||||
}
|
||||
|
||||
return 0; // keep msvc happy
|
||||
}
|
||||
|
||||
|
@ -1,91 +0,0 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
// Utility function which converts an iterator_category into a
|
||||
// traversal tag
|
||||
template <class C>
|
||||
typename iterator_category_to_traversal<C>::type c2t(C)
|
||||
{
|
||||
typedef typename iterator_category_to_traversal<C>::type result;
|
||||
return result();
|
||||
}
|
||||
|
||||
struct v
|
||||
{
|
||||
v();
|
||||
~v();
|
||||
};
|
||||
|
||||
//
|
||||
// Test conversions from iterator_tag<...> to old-style iterator categories
|
||||
//
|
||||
|
||||
// These "solid" tag types ensure exact matching of iterator
|
||||
// classification, because unlike the std:: iterator tags, they're not
|
||||
// inter-convertible
|
||||
struct output_iter {};
|
||||
struct input_iter {};
|
||||
struct input_output_iter {};
|
||||
struct forward_iter {};
|
||||
struct bidirectional_iter {};
|
||||
struct random_access_iter{} ;
|
||||
|
||||
// Convert various old-style categories into "solid" tags.
|
||||
input_iter cat(std::input_iterator_tag);
|
||||
output_iter cat(std::output_iterator_tag);
|
||||
input_output_iter cat(boost::detail::input_output_iterator_tag);
|
||||
forward_iter cat(std::forward_iterator_tag);
|
||||
bidirectional_iter cat(std::bidirectional_iterator_tag);
|
||||
random_access_iter cat(std::random_access_iterator_tag);
|
||||
|
||||
random_access_iter x1 = cat(iterator_tag<v,v&,random_access_traversal_tag>());
|
||||
random_access_iter x2 = cat(iterator_tag<v,v const&,random_access_traversal_tag>());
|
||||
bidirectional_iter x3 = cat(iterator_tag<v,v const&,bidirectional_traversal_tag>());
|
||||
forward_iter x4 = cat(iterator_tag<v,v const&,forward_traversal_tag>());
|
||||
input_output_iter x5 = cat(iterator_tag<v,v,bidirectional_traversal_tag>());
|
||||
input_iter x6 = cat(iterator_tag<v const,v,bidirectional_traversal_tag>());
|
||||
output_iter x7 = cat(iterator_tag<v,v const&,incrementable_traversal_tag>());
|
||||
|
||||
|
||||
//
|
||||
// Test conversion from old-style iterator categories to traversal categories
|
||||
//
|
||||
|
||||
// These "solid" tag types ensure exact matching of iterator
|
||||
// classification, because unlike the traversal tags, they're not
|
||||
// inter-convertible
|
||||
struct incrementable_traversal {};
|
||||
struct single_pass_traversal {};
|
||||
struct forward_traversal {};
|
||||
struct bidirectional_traversal {};
|
||||
struct random_access_traversal {} ;
|
||||
|
||||
// Convert various traversal categories into "solid" tags
|
||||
incrementable_traversal trav(incrementable_traversal_tag);
|
||||
single_pass_traversal trav(single_pass_traversal_tag);
|
||||
forward_traversal trav(forward_traversal_tag);
|
||||
bidirectional_traversal trav(bidirectional_traversal_tag);
|
||||
random_access_traversal trav(random_access_traversal_tag);
|
||||
|
||||
// Show that full types of tags that are already traversal categories
|
||||
// are preserved
|
||||
iterator_tag<v,v&,random_access_traversal_tag> yz1
|
||||
= c2t(iterator_tag<v,v&,random_access_traversal_tag>());
|
||||
|
||||
// Test traversal extraction from both old-style and new-style tags
|
||||
random_access_traversal yy1 = trav(c2t(iterator_tag<v,v&,random_access_traversal_tag>()));
|
||||
bidirectional_traversal yy2 = trav(c2t(iterator_tag<v,v&,bidirectional_traversal_tag>()));
|
||||
forward_traversal yy3 = trav(c2t(iterator_tag<v,v const&,forward_traversal_tag>()));
|
||||
single_pass_traversal yy4 = trav(c2t(iterator_tag<v const,v,single_pass_traversal_tag>()));
|
||||
incrementable_traversal yy5 = trav(c2t(iterator_tag<v,v const&,incrementable_traversal_tag>()));
|
||||
|
||||
random_access_traversal z1 = trav(c2t(std::random_access_iterator_tag()));
|
||||
bidirectional_traversal z2 = trav(c2t(std::bidirectional_iterator_tag()));
|
||||
forward_traversal z3 = trav(c2t(std::forward_iterator_tag()));
|
||||
single_pass_traversal z4 = trav(c2t(std::input_iterator_tag()));
|
||||
incrementable_traversal z5 = trav(c2t(std::output_iterator_tag()));
|
@ -11,8 +11,6 @@
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
// Test reverse iterator
|
||||
int main()
|
||||
{
|
||||
|
@ -10,13 +10,17 @@
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U>
|
||||
struct static_assert_same;
|
||||
struct static_assert_same_base;
|
||||
|
||||
template <class T>
|
||||
struct static_assert_same<T,T>
|
||||
struct static_assert_same_base<T,T>
|
||||
{
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct static_assert_same : static_assert_same_base<T,U> {};
|
||||
|
||||
#else
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
@ -184,17 +184,14 @@ main()
|
||||
for (int k2 = 0; k2 < N; ++k2)
|
||||
x[k2] = x[k2] * 2;
|
||||
|
||||
boost::input_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||
, x[0]
|
||||
, x[1]);
|
||||
boost::input_iterator_test(
|
||||
boost::make_transform_iterator(y, mult_2), x[0], x[1]);
|
||||
|
||||
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_2)
|
||||
, x[0]
|
||||
, x[1]);
|
||||
boost::input_iterator_test(
|
||||
boost::make_transform_iterator(&y[0], mult_2), x[0], x[1]);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||
, N
|
||||
, x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator(y, mult_2), N, x);
|
||||
|
||||
}
|
||||
|
||||
@ -213,25 +210,34 @@ main()
|
||||
|
||||
}
|
||||
|
||||
std::copy(x,
|
||||
x + N,
|
||||
boost::make_transform_iterator((pair_t*)values, select_first()));
|
||||
std::copy(
|
||||
x
|
||||
, x + N
|
||||
, boost::make_transform_iterator((pair_t*)values, select_first())
|
||||
);
|
||||
|
||||
std::copy(y,
|
||||
y + N,
|
||||
boost::make_transform_iterator((pair_t*)values, select_second()));
|
||||
std::copy(
|
||||
y
|
||||
, y + N
|
||||
, boost::make_transform_iterator((pair_t*)values, select_second())
|
||||
);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, value_select_first()),
|
||||
N,
|
||||
x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, value_select_first())
|
||||
, N
|
||||
, x
|
||||
);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()),
|
||||
N,
|
||||
x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, const_select_first())
|
||||
, N, x
|
||||
);
|
||||
|
||||
boost::constant_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
|
||||
boost::constant_lvalue_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
|
||||
|
||||
boost::mutable_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
|
||||
boost::non_const_lvalue_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,12 @@
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "static_assert_same.hpp"
|
||||
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
#include <boost/iterator/detail/minimum_category.hpp>
|
||||
|
||||
struct X { int a; };
|
||||
|
||||
@ -40,29 +43,32 @@ void category_test()
|
||||
using namespace boost::detail;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!is_tag<
|
||||
input_output_iterator_tag
|
||||
, std::input_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!is_tag<
|
||||
input_output_iterator_tag
|
||||
, std::output_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
!boost::is_convertible<
|
||||
std::input_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
!boost::is_convertible<
|
||||
std::output_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
boost::is_convertible<
|
||||
input_output_iterator_tag
|
||||
, std::forward_iterator_tag>::value));
|
||||
, std::input_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<
|
||||
input_output_iterator_tag
|
||||
, std::output_iterator_tag>::value));
|
||||
|
||||
#if 0 // This seems wrong; we're not advertising
|
||||
// input_output_iterator_tag are we?
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<
|
||||
std::forward_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
#endif
|
||||
|
||||
int test = static_assert_min_cat<
|
||||
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
|
||||
@ -72,9 +78,11 @@ void category_test()
|
||||
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
|
||||
>::value;
|
||||
|
||||
#if 0
|
||||
test = static_assert_min_cat<
|
||||
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
|
||||
>::value;
|
||||
#endif
|
||||
|
||||
test = static_assert_min_cat<
|
||||
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
|
||||
@ -84,28 +92,12 @@ void category_test()
|
||||
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
|
||||
>::value;
|
||||
|
||||
#if 0 // This would be wrong: a random access iterator is not
|
||||
// neccessarily writable, as is an output iterator.
|
||||
test = static_assert_min_cat<
|
||||
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
||||
>::value;
|
||||
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< incrementable_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< single_pass_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< forward_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< bidirectional_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< random_access_traversal_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< readable_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< swappable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_lvalue_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_lvalue_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< incrementable_traversal_tag >::value));
|
||||
#endif
|
||||
|
||||
(void)test;
|
||||
}
|
||||
|
@ -48,31 +48,17 @@
|
||||
#include <set>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/is_readable_iterator.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <stddef.h>
|
||||
|
||||
// Uncomment to see static assert.
|
||||
// #define PROVOKE_STATIC_ASSERT
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fake iterator for testing zip iterator categories
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class fake_writable_iterator
|
||||
{
|
||||
public:
|
||||
typedef int& reference;
|
||||
typedef int value_type;
|
||||
typedef int* pointer;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef boost::iterator_tag<
|
||||
boost::writable_iterator_tag,
|
||||
boost::forward_traversal_tag
|
||||
> iterator_category;
|
||||
};
|
||||
template <class It>
|
||||
struct pure_traversal
|
||||
: boost::detail::pure_traversal_tag<
|
||||
typename boost::iterator_traversal<It>::type
|
||||
>
|
||||
{};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -871,24 +857,14 @@ int main( void )
|
||||
|
||||
// The big iterator of the previous test has vector, list, and set iterators.
|
||||
// Therefore, it must be bidirectional, but not random access.
|
||||
bool bBigItIsBidirectionalIterator = boost::is_same<
|
||||
boost::bidirectional_traversal_tag,
|
||||
boost::traversal_category<zip_it_12_type>::type
|
||||
bool bBigItIsBidirectionalIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value;
|
||||
//
|
||||
bool bBigItIsRandomAccessIterator = boost::is_same<
|
||||
boost::random_access_traversal_tag,
|
||||
boost::traversal_category<zip_it_12_type>::type
|
||||
>::value;
|
||||
//
|
||||
bool bBigItIsReadableIterator = boost::is_same<
|
||||
boost::readable_iterator_tag,
|
||||
boost::access_category<zip_it_12_type>::type
|
||||
>::value;
|
||||
//
|
||||
bool bBigItIsReadableLValueIterator = boost::is_same<
|
||||
boost::readable_lvalue_iterator_tag,
|
||||
boost::access_category<zip_it_12_type>::type
|
||||
|
||||
bool bBigItIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
|
||||
// A combining iterator with all vector iterators must have random access
|
||||
@ -901,63 +877,15 @@ int main( void )
|
||||
>
|
||||
> all_vects_type;
|
||||
|
||||
bool bAllVectsIsRandomAccessIterator = boost::is_same<
|
||||
boost::random_access_traversal_tag,
|
||||
boost::traversal_category<all_vects_type>::type
|
||||
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<all_vects_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
//
|
||||
bool bAllVectsIsReadableIterator = boost::is_same<
|
||||
boost::readable_iterator_tag,
|
||||
boost::access_category<all_vects_type>::type
|
||||
>::value;
|
||||
//
|
||||
bool bAllVectsIsReadableLValueIterator = boost::is_same<
|
||||
boost::readable_lvalue_iterator_tag,
|
||||
boost::access_category<all_vects_type>::type
|
||||
>::value;
|
||||
|
||||
// Test if the meta function all_iterators_readable, which is used
|
||||
// for compile-time asserting, works.
|
||||
//
|
||||
bool bAllIteratorsReadable1 =
|
||||
boost::detail::all_iterators_in_tuple_readable<
|
||||
boost::tuples::tuple<
|
||||
std::vector<int>::const_iterator,
|
||||
std::set<double>::iterator
|
||||
>
|
||||
>::type::value;
|
||||
|
||||
bool bAllIteratorsReadable2 =
|
||||
boost::detail::all_iterators_in_tuple_readable<
|
||||
boost::tuples::tuple<
|
||||
std::vector<int>::const_iterator,
|
||||
fake_writable_iterator,
|
||||
std::set<double>::iterator
|
||||
>
|
||||
>::type::value;
|
||||
|
||||
// Compile-time assert because of non-readable iterator.
|
||||
//
|
||||
#ifdef PROVOKE_STATIC_ASSERT
|
||||
typedef boost::zip_iterator<
|
||||
boost::tuples::tuple<
|
||||
fake_writable_iterator
|
||||
>
|
||||
>no_compile_type;
|
||||
|
||||
no_compile_type no_compile;
|
||||
#endif
|
||||
|
||||
// The big test.
|
||||
if( bBigItIsBidirectionalIterator &&
|
||||
! bBigItIsRandomAccessIterator &&
|
||||
bBigItIsReadableIterator &&
|
||||
! bBigItIsReadableLValueIterator &&
|
||||
bAllVectsIsRandomAccessIterator &&
|
||||
! bAllVectsIsReadableLValueIterator &&
|
||||
bAllVectsIsReadableIterator &&
|
||||
bAllIteratorsReadable1 &&
|
||||
! bAllIteratorsReadable2
|
||||
bAllVectsIsRandomAccessIterator
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
@ -977,6 +905,6 @@ int main( void )
|
||||
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
|
||||
<< std::endl;
|
||||
|
||||
return 0;
|
||||
return num_failed_tests;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user