mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-30 04:47:20 +02:00
Got everything working with GCC
[SVN r20864]
This commit is contained in:
@ -13,28 +13,42 @@
|
|||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_class.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
namespace boost
|
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>
|
template <class Predicate, class Iterator>
|
||||||
class filter_iterator
|
class filter_iterator
|
||||||
: public iterator_adaptor<
|
: public detail::filter_iterator_base<Predicate, Iterator>::type
|
||||||
filter_iterator<Predicate, Iterator>, Iterator
|
|
||||||
, use_default
|
|
||||||
, typename detail::minimum_category<
|
|
||||||
bidirectional_traversal_tag
|
|
||||||
, typename traversal_category<Iterator>::type
|
|
||||||
>::type
|
|
||||||
>
|
|
||||||
{
|
{
|
||||||
typedef iterator_adaptor<
|
typedef typename detail::filter_iterator_base<
|
||||||
filter_iterator<Predicate, Iterator>, Iterator
|
Predicate, Iterator
|
||||||
, use_default
|
>::type super_t;
|
||||||
, typename detail::minimum_category<
|
|
||||||
bidirectional_traversal_tag
|
|
||||||
, typename traversal_category<Iterator>::type
|
|
||||||
>::type
|
|
||||||
> super_t;
|
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
@ -8,341 +8,430 @@
|
|||||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||||
|
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/mpl/if.hpp>
|
|
||||||
#include <boost/mpl/and.hpp>
|
|
||||||
#include <boost/operators.hpp>
|
#include <boost/operators.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/is_const.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_const.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
|
||||||
#include <boost/mpl/aux_/msvc_eti_base.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 <boost/iterator/detail/facade_iterator_category.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#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 {
|
||||||
template <class Value, class AccessCategory>
|
readable_iterator_bit = 1
|
||||||
struct access_archetype;
|
, writable_iterator_bit = 2
|
||||||
|
, swappable_iterator_bit = 4
|
||||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
, lvalue_iterator_bit = 8
|
||||||
struct traversal_archetype;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct assign_proxy
|
|
||||||
{
|
|
||||||
assign_proxy& operator=(T);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct read_write_proxy :
|
|
||||||
assign_proxy<T>
|
|
||||||
{
|
|
||||||
operator T();
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct arrow_proxy
|
|
||||||
{
|
|
||||||
T const* operator->() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_operator_brackets {};
|
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
struct readable_operator_brackets
|
|
||||||
{
|
|
||||||
ValueType operator[](std::ptrdiff_t n) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
struct writable_operator_brackets
|
|
||||||
{
|
|
||||||
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class TraversalCategory>
|
|
||||||
struct traversal_archetype_impl
|
|
||||||
{
|
|
||||||
template <class Derived,class Value> struct archetype;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Derived, class Value, class TraversalCategory>
|
|
||||||
struct traversal_archetype_
|
|
||||||
: mpl::aux::msvc_eti_base<
|
|
||||||
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
|
||||||
>::type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
|
||||||
{
|
|
||||||
template<class Derived, class Value>
|
|
||||||
struct archetype
|
|
||||||
{
|
|
||||||
typedef void difference_type;
|
|
||||||
|
|
||||||
Derived& operator++();
|
|
||||||
Derived operator++(int) const;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
|
||||||
{
|
|
||||||
template<class Derived, class Value>
|
|
||||||
struct archetype
|
|
||||||
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
|
||||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
|
||||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
// doesn't seem to pick up != from equality_comparable
|
|
||||||
template <class Derived, class Value>
|
|
||||||
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
|
||||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
|
||||||
#endif
|
|
||||||
template <>
|
|
||||||
struct traversal_archetype_impl<forward_traversal_tag>
|
|
||||||
{
|
|
||||||
template<class Derived, class Value>
|
|
||||||
struct archetype
|
|
||||||
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
|
||||||
{
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
|
||||||
{
|
|
||||||
template<class Derived, class Value>
|
|
||||||
struct archetype
|
|
||||||
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
|
||||||
{
|
|
||||||
Derived& operator--();
|
|
||||||
Derived operator--(int) const;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
|
||||||
{
|
|
||||||
template<class Derived, class Value>
|
|
||||||
struct archetype
|
|
||||||
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
|
||||||
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
|
||||||
{
|
|
||||||
Derived& operator+=(std::ptrdiff_t);
|
|
||||||
Derived& operator-=(std::ptrdiff_t);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
|
||||||
std::ptrdiff_t);
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
Derived& operator+(std::ptrdiff_t,
|
|
||||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
|
||||||
std::ptrdiff_t);
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
|
||||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
|
||||||
|
|
||||||
template <class Derived, class Value>
|
|
||||||
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
|
||||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
|
||||||
|
|
||||||
struct bogus_type;
|
|
||||||
|
|
||||||
template <class Value>
|
|
||||||
struct convertible_type
|
|
||||||
: mpl::if_< is_const<Value>,
|
|
||||||
typename remove_const<Value>::type,
|
|
||||||
bogus_type >
|
|
||||||
{};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
|
|
||||||
template <class> struct undefined;
|
|
||||||
|
|
||||||
template <class AccessCategory>
|
|
||||||
struct access_archetype_impl
|
|
||||||
{
|
|
||||||
template <class Value> struct archetype;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Value, class AccessCategory>
|
// Not quite tags, since dispatching wouldn't work.
|
||||||
struct access_archetype
|
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
|
||||||
: mpl::aux::msvc_eti_base<
|
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
|
||||||
typename access_archetype_impl<AccessCategory>::template archetype<Value>
|
|
||||||
|
typedef mpl::int_<
|
||||||
|
(readable_iterator_bit|writable_iterator_bit)
|
||||||
|
>::type readable_writable_iterator_t;
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
assign_proxy& operator=(T);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class 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
|
||||||
|
{
|
||||||
|
T const* operator->() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_operator_brackets {};
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
|
struct readable_operator_brackets
|
||||||
|
{
|
||||||
|
read_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
|
struct writable_operator_brackets
|
||||||
|
{
|
||||||
|
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct operator_brackets
|
||||||
|
: 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 <>
|
template <class TraversalCategory>
|
||||||
struct access_archetype_impl<readable_iterator_tag>
|
struct traversal_archetype_impl
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Derived,class Value> struct archetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value, class TraversalCategory>
|
||||||
|
struct traversal_archetype_
|
||||||
|
: mpl::aux::msvc_eti_base<
|
||||||
|
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||||
|
>::type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
{
|
{
|
||||||
typedef typename remove_cv<Value>::type value_type;
|
typedef void difference_type;
|
||||||
typedef Value reference;
|
|
||||||
typedef Value* pointer;
|
|
||||||
|
|
||||||
value_type operator*() const;
|
Derived& operator++();
|
||||||
|
Derived operator++(int) const;
|
||||||
detail::arrow_proxy<Value> operator->() const;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct access_archetype_impl<writable_iterator_tag>
|
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template<class Derived, class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
|
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||||
|
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||||
{
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
// doesn't seem to pick up != from equality_comparable
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||||
|
#endif
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<forward_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||||
|
{
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||||
|
{
|
||||||
|
Derived& operator--();
|
||||||
|
Derived operator--(int) const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||||
|
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
Derived& operator+=(std::ptrdiff_t);
|
||||||
|
Derived& operator-=(std::ptrdiff_t);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
std::ptrdiff_t);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator+(std::ptrdiff_t,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
std::ptrdiff_t);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
struct bogus_type;
|
||||||
|
|
||||||
|
template <class Value>
|
||||||
|
struct convertible_type
|
||||||
|
: mpl::if_< is_const<Value>,
|
||||||
|
typename remove_const<Value>::type,
|
||||||
|
bogus_type >
|
||||||
|
{};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
template <class> struct undefined;
|
||||||
|
|
||||||
|
template <class AccessCategory>
|
||||||
|
struct iterator_access_archetype_impl
|
||||||
|
{
|
||||||
|
template <class Value> struct archetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory>
|
||||||
|
struct iterator_access_archetype
|
||||||
|
: mpl::aux::msvc_eti_base<
|
||||||
|
typename iterator_access_archetype_impl<
|
||||||
|
AccessCategory
|
||||||
|
>::template archetype<Value>
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_access_archetype_impl<
|
||||||
|
iterator_archetypes::readable_iterator_t
|
||||||
|
>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
{
|
||||||
|
typedef typename remove_cv<Value>::type value_type;
|
||||||
|
typedef Value reference;
|
||||||
|
typedef Value* pointer;
|
||||||
|
|
||||||
|
value_type operator*() const;
|
||||||
|
|
||||||
|
detail::arrow_proxy<Value> operator->() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_access_archetype_impl<
|
||||||
|
iterator_archetypes::writable_iterator_t
|
||||||
|
>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
{
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||||
# endif
|
# endif
|
||||||
typedef void value_type;
|
typedef void value_type;
|
||||||
typedef void reference;
|
typedef void reference;
|
||||||
typedef void pointer;
|
typedef void pointer;
|
||||||
|
|
||||||
detail::assign_proxy<Value> operator*() const;
|
detail::assign_proxy<Value> operator*() const;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct access_archetype_impl<readable_writable_iterator_tag>
|
struct iterator_access_archetype_impl<
|
||||||
{
|
iterator_archetypes::readable_writable_iterator_t
|
||||||
template <class Value>
|
>
|
||||||
struct archetype
|
{
|
||||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
template <class Value>
|
||||||
{
|
struct archetype
|
||||||
typedef detail::read_write_proxy<Value> reference;
|
: public virtual iterator_access_archetype<
|
||||||
|
Value, iterator_archetypes::readable_iterator_t
|
||||||
detail::read_write_proxy<Value> operator*() const;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct access_archetype_impl<readable_lvalue_iterator_tag>
|
|
||||||
{
|
|
||||||
template <class Value>
|
|
||||||
struct archetype
|
|
||||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
|
||||||
{
|
|
||||||
typedef Value& reference;
|
|
||||||
|
|
||||||
Value& operator*() const;
|
|
||||||
Value* operator->() const;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct access_archetype_impl<writable_lvalue_iterator_tag>
|
|
||||||
{
|
|
||||||
template <class Value>
|
|
||||||
struct archetype
|
|
||||||
: public virtual access_archetype<Value, readable_lvalue_iterator_tag>
|
|
||||||
{
|
|
||||||
# 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 traversal_archetype_base
|
|
||||||
: detail::operator_brackets<
|
|
||||||
typename remove_cv<Value>::type
|
|
||||||
, AccessCategory
|
|
||||||
, TraversalCategory
|
|
||||||
>
|
|
||||||
, detail::traversal_archetype_<
|
|
||||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
|
||||||
, Value
|
|
||||||
, TraversalCategory
|
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
};
|
typedef detail::read_write_proxy<Value> reference;
|
||||||
|
|
||||||
template <class Value, class AccessCategory, class TraversalCategory>
|
detail::read_write_proxy<Value> operator*() const;
|
||||||
struct iterator_archetype
|
};
|
||||||
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
};
|
||||||
, public access_archetype<Value, AccessCategory>
|
|
||||||
|
|
||||||
// These broken libraries require derivation from std::iterator
|
template <>
|
||||||
// (or related magic) in order to handle iter_swap and other
|
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
|
||||||
// iterator operations
|
{
|
||||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
template <class Value>
|
||||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
struct archetype
|
||||||
, public std::iterator<
|
: public virtual iterator_access_archetype<
|
||||||
iterator_tag<AccessCategory,TraversalCategory>
|
Value, iterator_archetypes::readable_iterator_t
|
||||||
, typename access_archetype<Value, AccessCategory>::value_type
|
>
|
||||||
, typename traversal_archetype_base<
|
{
|
||||||
Value, AccessCategory, TraversalCategory
|
typedef Value& reference;
|
||||||
>::difference_type
|
|
||||||
>
|
Value& operator*() const;
|
||||||
|
Value* operator->() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
: 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
|
# endif
|
||||||
{
|
};
|
||||||
// Derivation from std::iterator above caused ambiguity, so now
|
};
|
||||||
// we have to declare all the types here.
|
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct iterator_archetype;
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct traversal_archetype_base
|
||||||
|
: detail::operator_brackets<
|
||||||
|
typename remove_cv<Value>::type
|
||||||
|
, AccessCategory
|
||||||
|
, TraversalCategory
|
||||||
|
>
|
||||||
|
, detail::traversal_archetype_<
|
||||||
|
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||||
|
, Value
|
||||||
|
, TraversalCategory
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct iterator_archetype
|
||||||
|
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||||
|
, public iterator_access_archetype<Value, AccessCategory>
|
||||||
|
|
||||||
|
// 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) \
|
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||||
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
|
||||||
|
, public std::iterator<
|
||||||
|
iterator_tag<AccessCategory,TraversalCategory>
|
||||||
|
, typename iterator_access_archetype<Value, AccessCategory>::value_type
|
||||||
|
, typename traversal_archetype_base<
|
||||||
|
Value, AccessCategory, TraversalCategory
|
||||||
|
>::difference_type
|
||||||
|
>
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
// Derivation from std::iterator above caused ambiguity, so now
|
||||||
|
// we have to declare all the types here.
|
||||||
|
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||||
|
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||||
|
|
||||||
|
typedef typename iterator_access_archetype<Value, AccessCategory>::value_type value_type;
|
||||||
|
|
||||||
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
|
typedef typename iterator_access_archetype<Value, AccessCategory>::pointer pointer;
|
||||||
|
|
||||||
typedef typename access_archetype<Value, AccessCategory>::reference reference;
|
typedef typename traversal_archetype_base<
|
||||||
|
Value, AccessCategory, TraversalCategory
|
||||||
typedef typename traversal_archetype_base<
|
>::difference_type difference_type;
|
||||||
Value, AccessCategory, TraversalCategory
|
|
||||||
>::difference_type difference_type;
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
typedef typename iterator_access_archetype<Value, AccessCategory>::reference reference;
|
||||||
|
|
||||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
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
|
||||||
|
, reference
|
||||||
|
>::type iterator_category;
|
||||||
|
|
||||||
iterator_archetype();
|
iterator_archetype();
|
||||||
iterator_archetype(iterator_archetype const&);
|
iterator_archetype(iterator_archetype const&);
|
||||||
|
|
||||||
iterator_archetype& operator=(iterator_archetype const&);
|
iterator_archetype& operator=(iterator_archetype const&);
|
||||||
|
|
||||||
// Optional conversion from mutable
|
// Optional conversion from mutable
|
||||||
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@ -17,17 +17,12 @@
|
|||||||
# include <boost/mpl/identity.hpp>
|
# include <boost/mpl/identity.hpp>
|
||||||
# include <boost/mpl/placeholders.hpp>
|
# include <boost/mpl/placeholders.hpp>
|
||||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
|
# include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||||
|
|
||||||
# include <boost/type_traits/is_convertible.hpp>
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
# include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
|
# include <boost/static_assert.hpp>
|
||||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
# include <boost/mpl/or.hpp>
|
|
||||||
# include <boost/python/detail/indirect_traits.hpp>
|
|
||||||
# else
|
|
||||||
# include <boost/mpl/remove_reference.hpp>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@ -50,6 +45,81 @@ struct random_access_traversal_tag
|
|||||||
|
|
||||||
namespace detail
|
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, class T2>
|
||||||
|
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 inner::type type;
|
||||||
|
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||||
|
};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||||
|
template <>
|
||||||
|
struct minimum_category<int,int>
|
||||||
|
{
|
||||||
|
typedef int type;
|
||||||
|
};
|
||||||
|
# endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Convert a "strictly old-style" iterator category to a traversal
|
// Convert a "strictly old-style" iterator category to a traversal
|
||||||
@ -88,7 +158,34 @@ namespace detail
|
|||||||
{
|
{
|
||||||
typedef int type;
|
typedef int type;
|
||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
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
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <boost/mpl/bool.hpp>
|
#include <boost/mpl/bool.hpp>
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
#include <boost/mpl/and.hpp>
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
||||||
@ -56,7 +57,6 @@ namespace boost_concepts {
|
|||||||
public:
|
public:
|
||||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
|
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::detail::iterator_traits<Iterator>::reference reference;
|
||||||
typedef BOOST_DEDUCED_TYPENAME ::boost::access_category<Iterator>::type access_category;
|
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
@ -64,8 +64,6 @@ namespace boost_concepts {
|
|||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
boost::DefaultConstructibleConcept<Iterator> >();
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_iterator_tag, access_category>::value));
|
|
||||||
|
|
||||||
reference r = *i; // or perhaps read(x)
|
reference r = *i; // or perhaps read(x)
|
||||||
value_type v(r);
|
value_type v(r);
|
||||||
boost::ignore_unused_variable_warning(v);
|
boost::ignore_unused_variable_warning(v);
|
||||||
@ -76,16 +74,13 @@ namespace boost_concepts {
|
|||||||
template <typename Iterator, typename ValueType>
|
template <typename Iterator, typename ValueType>
|
||||||
class WritableIteratorConcept {
|
class WritableIteratorConcept {
|
||||||
public:
|
public:
|
||||||
typedef typename boost::access_category<Iterator>::type access_category;
|
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
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)
|
*i = v; // a good alternative could be something like write(x, v)
|
||||||
}
|
}
|
||||||
ValueType v;
|
ValueType v;
|
||||||
@ -95,11 +90,8 @@ namespace boost_concepts {
|
|||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
class SwappableIteratorConcept {
|
class SwappableIteratorConcept {
|
||||||
public:
|
public:
|
||||||
typedef typename boost::access_category<Iterator>::type access_category;
|
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::swappable_iterator_tag, access_category>::value));
|
|
||||||
|
|
||||||
std::iter_swap(i1, i2);
|
std::iter_swap(i1, i2);
|
||||||
}
|
}
|
||||||
Iterator i1;
|
Iterator i1;
|
||||||
@ -107,25 +99,25 @@ namespace boost_concepts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
class ReadableLvalueIteratorConcept {
|
class ReadableLvalueIteratorConcept
|
||||||
public:
|
{
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
public:
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
typedef typename boost::access_category<Iterator>::type access_category;
|
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
|
||||||
void constraints() {
|
void constraints()
|
||||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
{
|
||||||
|
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&>
|
||||||
typedef boost::mpl::or_<
|
, boost::is_same<reference, value_type const&>
|
||||||
boost::is_same<reference, value_type&>,
|
> correct_reference;
|
||||||
boost::is_same<reference, value_type const&> > correct_reference;
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(correct_reference::value);
|
BOOST_STATIC_ASSERT(correct_reference::value);
|
||||||
|
|
||||||
reference v = *i;
|
reference v = *i;
|
||||||
boost::ignore_unused_variable_warning(v);
|
boost::ignore_unused_variable_warning(v);
|
||||||
}
|
}
|
||||||
Iterator i;
|
Iterator i;
|
||||||
};
|
};
|
||||||
@ -135,7 +127,6 @@ namespace boost_concepts {
|
|||||||
public:
|
public:
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
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<
|
boost::function_requires<
|
||||||
@ -145,7 +136,6 @@ namespace boost_concepts {
|
|||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
SwappableIteratorConcept<Iterator> >();
|
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));
|
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||||
}
|
}
|
||||||
@ -157,14 +147,19 @@ namespace boost_concepts {
|
|||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
class IncrementableIteratorConcept {
|
class IncrementableIteratorConcept {
|
||||||
public:
|
public:
|
||||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
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;
|
++i;
|
||||||
(void)i++;
|
(void)i++;
|
||||||
@ -175,21 +170,26 @@ namespace boost_concepts {
|
|||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
class SinglePassIteratorConcept {
|
class SinglePassIteratorConcept {
|
||||||
public:
|
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::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
||||||
boost::function_requires< boost::EqualityComparableConcept<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>
|
template <typename Iterator>
|
||||||
class ForwardTraversalConcept {
|
class ForwardTraversalConcept {
|
||||||
public:
|
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::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
@ -201,19 +201,29 @@ namespace boost_concepts {
|
|||||||
> difference_type_is_signed_integral;
|
> difference_type_is_signed_integral;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
|
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>
|
template <typename Iterator>
|
||||||
class BidirectionalTraversalConcept {
|
class BidirectionalTraversalConcept {
|
||||||
public:
|
public:
|
||||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< ForwardTraversalConcept<Iterator> >();
|
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;
|
--i;
|
||||||
(void)i--;
|
(void)i--;
|
||||||
@ -224,14 +234,19 @@ namespace boost_concepts {
|
|||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
class RandomAccessTraversalConcept {
|
class RandomAccessTraversalConcept {
|
||||||
public:
|
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
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||||
difference_type;
|
difference_type;
|
||||||
|
|
||||||
void constraints() {
|
void constraints() {
|
||||||
boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
|
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 += n;
|
||||||
i = i + n;
|
i = i + n;
|
||||||
@ -326,11 +341,11 @@ namespace detail
|
|||||||
class InteroperableConcept
|
class InteroperableConcept
|
||||||
{
|
{
|
||||||
public:
|
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
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||||
difference_type;
|
difference_type;
|
||||||
|
|
||||||
typedef typename boost::traversal_category<ConstIterator>::type
|
typedef typename boost::iterator_traversal<ConstIterator>::type
|
||||||
const_traversal_category;
|
const_traversal_category;
|
||||||
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
||||||
const_difference_type;
|
const_difference_type;
|
||||||
|
@ -160,9 +160,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
|||||||
readable_iterator_test(i2, v2);
|
readable_iterator_test(i2, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void id_type(T const&) { T::no_SuchMember x; }
|
|
||||||
|
|
||||||
// random access
|
// random access
|
||||||
// Preconditions: [i,i+N) is a valid range
|
// Preconditions: [i,i+N) is a valid range
|
||||||
template <class Iterator, class TrueVals>
|
template <class Iterator, class TrueVals>
|
||||||
@ -172,11 +169,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
|||||||
const Iterator j = i;
|
const Iterator j = i;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
id_type(j[c]);
|
for (c = 0; c < N-1; ++c)
|
||||||
for (c = 0; c < N-1; ++c) {
|
{
|
||||||
assert(i == j + c);
|
assert(i == j + c);
|
||||||
assert(*i == vals[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 == *(j + c));
|
||||||
assert(*i == *(c + j));
|
assert(*i == *(c + j));
|
||||||
++i;
|
++i;
|
||||||
@ -187,10 +185,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Iterator k = j + N - 1;
|
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 == k - c);
|
||||||
assert(*i == vals[N - 1 - 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;
|
Iterator q = k - c;
|
||||||
assert(*i == *q);
|
assert(*i == *q);
|
||||||
assert(i > j);
|
assert(i > j);
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include <boost/type_traits/remove_const.hpp>
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||||
@ -46,53 +48,38 @@ namespace boost
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Given the transform iterator's transformation and iterator, this
|
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||||
// is the type used as its traits.
|
|
||||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||||
struct transform_iterator_base
|
struct transform_iterator_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
// 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>
|
||||||
|
>::type reference;
|
||||||
|
|
||||||
// transform_iterator does not support writable/swappable iterators
|
// To get the default for Value: remove any reference on the
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
// result type, but retain any constness to signal
|
||||||
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
// non-writability. Note that if we adopt Thomas' suggestion
|
||||||
#endif
|
// to key non-writability *only* on the Reference argument,
|
||||||
|
// we'd need to strip constness here as well.
|
||||||
typedef typename mpl::apply_if<
|
typedef typename ia_dflt_help<
|
||||||
is_same< Reference, use_default >
|
Value
|
||||||
, function_object_result<UnaryFunction>
|
, remove_reference<reference>
|
||||||
, mpl::identity<Reference>
|
>::type cv_value_type;
|
||||||
>::type result_type;
|
|
||||||
|
|
||||||
typedef typename mpl::if_<
|
public:
|
||||||
is_same< Value, use_default >
|
typedef iterator_adaptor<
|
||||||
, typename remove_reference< result_type >::type
|
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||||
, Value
|
, Iterator
|
||||||
>::type cv_value_type;
|
, cv_value_type
|
||||||
|
, use_default // Leave the traversal category alone
|
||||||
typedef typename mpl::if_<
|
, reference
|
||||||
is_reference< result_type >
|
> 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
|
|
||||||
> type;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,12 +137,16 @@ namespace boost
|
|||||||
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
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>
|
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<
|
typename iterators::enable_if<
|
||||||
is_class<UnaryFunction>
|
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
|
||||||
, transform_iterator<UnaryFunction, Iterator>
|
, transform_iterator<UnaryFunction, Iterator>
|
||||||
>::type
|
>::type
|
||||||
make_transform_iterator(Iterator it)
|
make_transform_iterator(Iterator it)
|
||||||
@ -174,4 +165,6 @@ namespace boost
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/detail/iterator_traits.hpp>
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||||
IteratorTuple
|
IteratorTuple
|
||||||
, traversal_category<mpl::_1>
|
, iterator_traversal<mpl::_1>
|
||||||
>::type tuple_of_traversal_tags;
|
>::type tuple_of_traversal_tags;
|
||||||
|
|
||||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||||
@ -398,31 +398,6 @@ namespace boost {
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
||||||
// accumulating functor. To this end, we need to wrap it into
|
// accumulating functor. To this end, we need to wrap it into
|
||||||
// a struct that has exactly two arguments (that is, template
|
// a struct that has exactly two arguments (that is, template
|
||||||
@ -446,28 +421,6 @@ namespace boost {
|
|||||||
};
|
};
|
||||||
# endif
|
# 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
|
// Class zip_iterator_base
|
||||||
@ -479,14 +432,6 @@ namespace boost {
|
|||||||
struct zip_iterator_base
|
struct zip_iterator_base
|
||||||
{
|
{
|
||||||
private:
|
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
|
// Reference type is the type of the tuple obtained from the
|
||||||
// iterators' reference types.
|
// iterators' reference types.
|
||||||
typedef typename
|
typedef typename
|
||||||
@ -506,11 +451,6 @@ namespace boost {
|
|||||||
detail::minimum_traversal_category_in_iterator_tuple<
|
detail::minimum_traversal_category_in_iterator_tuple<
|
||||||
IteratorTuple
|
IteratorTuple
|
||||||
>::type traversal_category;
|
>::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:
|
public:
|
||||||
|
|
||||||
// The iterator facade type from which the zip iterator will
|
// The iterator facade type from which the zip iterator will
|
||||||
@ -518,7 +458,6 @@ namespace boost {
|
|||||||
typedef iterator_facade<
|
typedef iterator_facade<
|
||||||
zip_iterator<IteratorTuple>,
|
zip_iterator<IteratorTuple>,
|
||||||
value_type,
|
value_type,
|
||||||
access_category,
|
|
||||||
traversal_category,
|
traversal_category,
|
||||||
reference,
|
reference,
|
||||||
difference_type
|
difference_type
|
||||||
|
@ -34,7 +34,6 @@ test-suite iterator
|
|||||||
[ run counting_iterator_test.cpp ]
|
[ run counting_iterator_test.cpp ]
|
||||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||||
]
|
]
|
||||||
[ compile iterator_categories.cpp ]
|
|
||||||
[ run zip_iterator_test.cpp ]
|
[ run zip_iterator_test.cpp ]
|
||||||
|
|
||||||
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
||||||
|
@ -10,10 +10,13 @@
|
|||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include "static_assert_same.hpp" // remove
|
#include "static_assert_same.hpp" // remove
|
||||||
|
|
||||||
|
struct new_random_access
|
||||||
|
: std::random_access_iterator_tag
|
||||||
|
, boost::random_access_traversal_tag
|
||||||
|
{};
|
||||||
|
|
||||||
struct new_iterator
|
struct new_iterator
|
||||||
: public boost::iterator< boost::iterator_tag<
|
: public boost::iterator< new_random_access, int >
|
||||||
boost::writable_lvalue_iterator_tag
|
|
||||||
, boost::random_access_traversal_tag>, int>
|
|
||||||
{
|
{
|
||||||
int& operator*() const { return *m_x; }
|
int& operator*() const { return *m_x; }
|
||||||
new_iterator& operator++() { return *this; }
|
new_iterator& operator++() { return *this; }
|
||||||
@ -52,103 +55,15 @@ struct old_iterator
|
|||||||
};
|
};
|
||||||
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test_tag_convertibility();
|
typedef boost::iterator_traversal<new_iterator>::type traversal_category;
|
||||||
|
|
||||||
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_STATIC_ASSERT(
|
||||||
|
(boost::is_convertible<traversal_category, boost::random_access_traversal_tag>::value
|
||||||
|
));
|
||||||
|
|
||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
boost_concepts::WritableLvalueIteratorConcept<int*> >();
|
boost_concepts::WritableLvalueIteratorConcept<int*> >();
|
||||||
boost::function_requires<
|
boost::function_requires<
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <boost/iterator/reverse_iterator.hpp>
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
#include <boost/iterator/new_iterator_tests.hpp>
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -38,12 +39,12 @@ int main()
|
|||||||
filter_iter(one_or_four(), array, array+N)
|
filter_iter(one_or_four(), array, array+N)
|
||||||
, dummyT(1), dummyT(4));
|
, dummyT(1), dummyT(4));
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT(
|
||||||
!boost::detail::is_tag<
|
(!boost::is_convertible<
|
||||||
boost::random_access_traversal_tag
|
boost::iterator_traversal<filter_iter>::type
|
||||||
, boost::traversal_category<filter_iter>::type
|
, boost::random_access_traversal_tag
|
||||||
>::value
|
>::value
|
||||||
));
|
));
|
||||||
|
|
||||||
//# endif
|
//# endif
|
||||||
|
|
||||||
|
@ -71,17 +71,17 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
|
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
|
||||||
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator<v*>::value);
|
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
|
||||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<v const*>::value);
|
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
|
||||||
BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator<std::deque<v>::iterator>::value);
|
BOOST_STATIC_ASSERT(boost::is_non_const_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_non_const_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_non_const_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_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<proxy_iterator>::value);
|
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator>::value);
|
||||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
#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
|
#endif
|
||||||
BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator<noncopyable_iterator>::value);
|
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,15 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
{
|
typedef boost::iterator_archetype<
|
||||||
typedef boost::iterator_archetype<int,
|
int
|
||||||
boost::writable_lvalue_iterator_tag,
|
, boost::iterator_archetypes::writable_lvalue_iterator_t
|
||||||
boost::random_access_traversal_tag> iter;
|
, boost::random_access_traversal_tag
|
||||||
|
> iter;
|
||||||
|
|
||||||
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
||||||
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
||||||
}
|
|
||||||
return 0; // keep msvc happy
|
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()));
|
|
@ -231,7 +231,7 @@ main()
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,29 +40,32 @@ void category_test()
|
|||||||
using namespace boost::detail;
|
using namespace boost::detail;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT((
|
||||||
!is_tag<
|
!boost::is_convertible<
|
||||||
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<
|
|
||||||
std::input_iterator_tag
|
std::input_iterator_tag
|
||||||
, input_output_iterator_tag>::value));
|
, input_output_iterator_tag>::value));
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT((
|
||||||
is_tag<
|
!boost::is_convertible<
|
||||||
std::output_iterator_tag
|
std::output_iterator_tag
|
||||||
, input_output_iterator_tag>::value));
|
, input_output_iterator_tag>::value));
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT((
|
||||||
is_tag<
|
boost::is_convertible<
|
||||||
input_output_iterator_tag
|
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<
|
int test = static_assert_min_cat<
|
||||||
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
|
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
|
||||||
@ -72,9 +75,11 @@ void category_test()
|
|||||||
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
|
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
|
||||||
>::value;
|
>::value;
|
||||||
|
|
||||||
|
#if 0
|
||||||
test = static_assert_min_cat<
|
test = static_assert_min_cat<
|
||||||
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
|
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
|
||||||
>::value;
|
>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
test = static_assert_min_cat<
|
test = static_assert_min_cat<
|
||||||
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
|
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
|
||||||
@ -84,29 +89,13 @@ void category_test()
|
|||||||
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
|
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
|
||||||
>::value;
|
>::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<
|
test = static_assert_min_cat<
|
||||||
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
||||||
>::value;
|
>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
(void)test;
|
(void)test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,32 +48,18 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/iterator/is_readable_iterator.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
// Uncomment to see static assert.
|
template <class It>
|
||||||
// #define PROVOKE_STATIC_ASSERT
|
struct pure_traversal
|
||||||
|
: boost::detail::pure_traversal_tag<
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
typename boost::iterator_traversal<It>::type
|
||||||
//
|
>
|
||||||
// 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Das Main Funktion
|
// Das Main Funktion
|
||||||
@ -871,25 +857,15 @@ int main( void )
|
|||||||
|
|
||||||
// The big iterator of the previous test has vector, list, and set iterators.
|
// The big iterator of the previous test has vector, list, and set iterators.
|
||||||
// Therefore, it must be bidirectional, but not random access.
|
// Therefore, it must be bidirectional, but not random access.
|
||||||
bool bBigItIsBidirectionalIterator = boost::is_same<
|
bool bBigItIsBidirectionalIterator = boost::is_convertible<
|
||||||
boost::bidirectional_traversal_tag,
|
boost::iterator_traversal<zip_it_12_type>::type
|
||||||
boost::traversal_category<zip_it_12_type>::type
|
, boost::bidirectional_traversal_tag
|
||||||
>::value;
|
>::value;
|
||||||
//
|
|
||||||
bool bBigItIsRandomAccessIterator = boost::is_same<
|
bool bBigItIsRandomAccessIterator = boost::is_convertible<
|
||||||
boost::random_access_traversal_tag,
|
boost::iterator_traversal<zip_it_12_type>::type
|
||||||
boost::traversal_category<zip_it_12_type>::type
|
, boost::random_access_traversal_tag
|
||||||
>::value;
|
>::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
|
|
||||||
>::value;
|
|
||||||
|
|
||||||
// A combining iterator with all vector iterators must have random access
|
// A combining iterator with all vector iterators must have random access
|
||||||
// traversal.
|
// traversal.
|
||||||
@ -901,63 +877,15 @@ int main( void )
|
|||||||
>
|
>
|
||||||
> all_vects_type;
|
> all_vects_type;
|
||||||
|
|
||||||
bool bAllVectsIsRandomAccessIterator = boost::is_same<
|
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
|
||||||
boost::random_access_traversal_tag,
|
boost::iterator_traversal<all_vects_type>::type
|
||||||
boost::traversal_category<all_vects_type>::type
|
, boost::random_access_traversal_tag
|
||||||
>::value;
|
>::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.
|
// The big test.
|
||||||
if( bBigItIsBidirectionalIterator &&
|
if( bBigItIsBidirectionalIterator &&
|
||||||
! bBigItIsRandomAccessIterator &&
|
! bBigItIsRandomAccessIterator &&
|
||||||
bBigItIsReadableIterator &&
|
bAllVectsIsRandomAccessIterator
|
||||||
! bBigItIsReadableLValueIterator &&
|
|
||||||
bAllVectsIsRandomAccessIterator &&
|
|
||||||
! bAllVectsIsReadableLValueIterator &&
|
|
||||||
bAllVectsIsReadableIterator &&
|
|
||||||
bAllIteratorsReadable1 &&
|
|
||||||
! bAllIteratorsReadable2
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
++num_successful_tests;
|
++num_successful_tests;
|
||||||
@ -977,6 +905,6 @@ int main( void )
|
|||||||
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
|
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return 0;
|
return num_failed_tests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user