Got everything working with GCC

[SVN r20864]
This commit is contained in:
Dave Abrahams
2003-11-19 20:08:00 +00:00
parent 7ffe2601a9
commit eb73b8e0e2
16 changed files with 698 additions and 809 deletions
+30 -16
View File
@@ -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;
+379 -290
View File
@@ -8,341 +8,430 @@
#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/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 <boost/iterator/detail/facade_iterator_category.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
{
template <class Value, class AccessCategory>
struct access_archetype;
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
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;
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
: mpl::aux::msvc_eti_base<
typename access_archetype_impl<AccessCategory>::template archetype<Value>
// 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;
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
{
};
template <>
struct access_archetype_impl<readable_iterator_tag>
template <class TraversalCategory>
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
{
typedef typename remove_cv<Value>::type value_type;
typedef Value reference;
typedef Value* pointer;
typedef void difference_type;
value_type operator*() const;
detail::arrow_proxy<Value> operator->() const;
Derived& operator++();
Derived operator++(int) const;
};
};
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
: 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)
BOOST_STATIC_ASSERT(!is_const<Value>::value);
BOOST_STATIC_ASSERT(!is_const<Value>::value);
# endif
typedef void value_type;
typedef void reference;
typedef void pointer;
typedef void value_type;
typedef void reference;
typedef void pointer;
detail::assign_proxy<Value> operator*() const;
};
};
detail::assign_proxy<Value> operator*() const;
};
};
template <>
struct access_archetype_impl<readable_writable_iterator_tag>
{
template <class Value>
struct archetype
: public virtual access_archetype<Value, readable_iterator_tag>
{
typedef detail::read_write_proxy<Value> reference;
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
template <>
struct iterator_access_archetype_impl<
iterator_archetypes::readable_writable_iterator_t
>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, iterator_archetypes::readable_iterator_t
>
{
};
{
typedef detail::read_write_proxy<Value> reference;
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
, public access_archetype<Value, AccessCategory>
detail::read_write_proxy<Value> operator*() const;
};
};
// 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<
Value, AccessCategory, TraversalCategory
>::difference_type
>
template <>
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, iterator_archetypes::readable_iterator_t
>
{
typedef Value& reference;
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
{
// 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) \
|| 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
>::difference_type difference_type;
typedef typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
# 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 const&);
iterator_archetype();
iterator_archetype(iterator_archetype const&);
iterator_archetype& operator=(iterator_archetype const&);
iterator_archetype& operator=(iterator_archetype const&);
// Optional conversion from mutable
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
};
// Optional conversion from mutable
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
};
} // namespace boost
+106 -9
View File
@@ -17,17 +17,12 @@
# include <boost/mpl/identity.hpp>
# include <boost/mpl/placeholders.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_same.hpp>
# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY
# 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
# include <boost/static_assert.hpp>
namespace boost {
@@ -50,6 +45,81 @@ struct random_access_traversal_tag
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
@@ -88,7 +158,34 @@ namespace detail
{
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
+54 -39
View File
@@ -20,6 +20,7 @@
#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::detail::iterator_traits to work around some MSVC/Dinkumware problems.
@@ -56,7 +57,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 +64,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);
@@ -76,16 +74,13 @@ namespace boost_concepts {
template <typename Iterator, typename ValueType>
class WritableIteratorConcept {
public:
typedef typename boost::access_category<Iterator>::type access_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
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 +90,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,25 +99,25 @@ namespace boost_concepts {
};
template <typename Iterator>
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;
class ReadableLvalueIteratorConcept
{
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
void constraints() {
boost::function_requires< ReadableIteratorConcept<Iterator> >();
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;
typedef boost::mpl::or_<
boost::is_same<reference, value_type&>
, boost::is_same<reference, value_type const&>
> correct_reference;
BOOST_STATIC_ASSERT(correct_reference::value);
BOOST_STATIC_ASSERT(correct_reference::value);
reference v = *i;
boost::ignore_unused_variable_warning(v);
reference v = *i;
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
@@ -135,7 +127,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 +136,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 +147,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 +170,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 +201,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 +234,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 +341,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;
@@ -160,9 +160,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
readable_iterator_test(i2, v2);
}
template <class T>
void id_type(T const&) { T::no_SuchMember x; }
// random access
// Preconditions: [i,i+N) is a valid range
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;
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 == 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;
@@ -187,10 +185,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);
+39 -46
View File
@@ -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,53 +48,38 @@ 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:
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
#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 >
, function_object_result<UnaryFunction>
, mpl::identity<Reference>
>::type result_type;
// 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_same< Value, use_default >
, typename remove_reference< result_type >::type
, Value
>::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
> type;
public:
typedef iterator_adaptor<
transform_iterator<UnaryFunction, Iterator, Reference, Value>
, Iterator
, cv_value_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
+2 -63
View File
@@ -26,7 +26,7 @@
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
#include <boost/iterator/iterator_categories.hpp>
#include <boost/detail/iterator_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/tuple/tuple.hpp>
@@ -380,7 +380,7 @@ namespace boost {
{
typedef typename tuple_impl_specific::tuple_meta_transform<
IteratorTuple
, traversal_category<mpl::_1>
, iterator_traversal<mpl::_1>
>::type tuple_of_traversal_tags;
typedef typename tuple_impl_specific::tuple_meta_accumulate<
@@ -398,31 +398,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 +421,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 +432,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 +451,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 +458,6 @@ namespace boost {
typedef iterator_facade<
zip_iterator<IteratorTuple>,
value_type,
access_category,
traversal_category,
reference,
difference_type