diff --git a/include/boost/iterator/filter_iterator.hpp b/include/boost/iterator/filter_iterator.hpp index cd490dc..fee0184 100644 --- a/include/boost/iterator/filter_iterator.hpp +++ b/include/boost/iterator/filter_iterator.hpp @@ -13,28 +13,42 @@ #include #include +#include +#include + namespace boost { + template + class filter_iterator; + namespace detail + { + template + struct filter_iterator_base + { + typedef iterator_adaptor< + filter_iterator + , Iterator + , use_default + , typename mpl::if_< + is_convertible< + typename iterator_traversal::type + , bidirectional_traversal_tag + > + , forward_traversal_tag + , use_default + >::type + > type; + }; + } + template class filter_iterator - : public iterator_adaptor< - filter_iterator, Iterator - , use_default - , typename detail::minimum_category< - bidirectional_traversal_tag - , typename traversal_category::type - >::type - > + : public detail::filter_iterator_base::type { - typedef iterator_adaptor< - filter_iterator, Iterator - , use_default - , typename detail::minimum_category< - bidirectional_traversal_tag - , typename traversal_category::type - >::type - > super_t; + typedef typename detail::filter_iterator_base< + Predicate, Iterator + >::type super_t; friend class iterator_core_access; diff --git a/include/boost/iterator/iterator_archetypes.hpp b/include/boost/iterator/iterator_archetypes.hpp index e9439e7..9ebac63 100644 --- a/include/boost/iterator/iterator_archetypes.hpp +++ b/include/boost/iterator/iterator_archetypes.hpp @@ -8,341 +8,430 @@ #define BOOST_ITERATOR_ARCHETYPES_HPP #include -#include -#include #include #include + #include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include + +#include #include -namespace boost +namespace boost { + +template +struct access_archetype; + +template +struct traversal_archetype; + +namespace iterator_archetypes { - - template - struct access_archetype; - - template - struct traversal_archetype; - - namespace detail { - - template - struct assign_proxy - { - assign_proxy& operator=(T); - }; - - template - struct read_write_proxy : - assign_proxy - { - operator T(); - }; - - template - struct arrow_proxy - { - T const* operator->() const; - }; - - struct no_operator_brackets {}; - - template - struct readable_operator_brackets - { - ValueType operator[](std::ptrdiff_t n) const; - }; - - template - struct writable_operator_brackets - { - read_write_proxy operator[](std::ptrdiff_t n) const; - }; - - template - struct operator_brackets : - mpl::if_< is_tag, - mpl::if_< is_tag, - writable_operator_brackets< Value >, - mpl::if_< is_tag, - readable_operator_brackets, - no_operator_brackets > >, - no_operator_brackets >::type - { - }; - - template - struct traversal_archetype_impl - { - template struct archetype; - }; - - template - struct traversal_archetype_ - : mpl::aux::msvc_eti_base< - typename traversal_archetype_impl::template archetype - >::type - {}; - - template <> - struct traversal_archetype_impl - { - template - struct archetype - { - typedef void difference_type; - - Derived& operator++(); - Derived operator++(int) const; - }; - }; - - template <> - struct traversal_archetype_impl - { - template - struct archetype - : public equality_comparable< traversal_archetype_ >, - public traversal_archetype_ - { - }; - }; - - template - bool operator==(traversal_archetype_ const&, - traversal_archetype_ const&); - -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - // doesn't seem to pick up != from equality_comparable - template - bool operator!=(traversal_archetype_ const&, - traversal_archetype_ const&); -#endif - template <> - struct traversal_archetype_impl - { - template - struct archetype - : public traversal_archetype_ - { - typedef std::ptrdiff_t difference_type; - }; - }; - - template <> - struct traversal_archetype_impl - { - template - struct archetype - : public traversal_archetype_ - { - Derived& operator--(); - Derived operator--(int) const; - }; - }; - - template <> - struct traversal_archetype_impl - { - template - struct archetype - : public partially_ordered >, - public traversal_archetype_ - { - Derived& operator+=(std::ptrdiff_t); - Derived& operator-=(std::ptrdiff_t); - }; - }; - - template - Derived& operator+(traversal_archetype_ const&, - std::ptrdiff_t); - - template - Derived& operator+(std::ptrdiff_t, - traversal_archetype_ const&); - - template - Derived& operator-(traversal_archetype_ const&, - std::ptrdiff_t); - - template - std::ptrdiff_t operator-(traversal_archetype_ const&, - traversal_archetype_ const&); - - template - bool operator<(traversal_archetype_ const&, - traversal_archetype_ const&); - - struct bogus_type; - - template - struct convertible_type - : mpl::if_< is_const, - typename remove_const::type, - bogus_type > - {}; - - } // namespace detail - - - template struct undefined; - - template - struct access_archetype_impl - { - template struct archetype; + enum { + readable_iterator_bit = 1 + , writable_iterator_bit = 2 + , swappable_iterator_bit = 4 + , lvalue_iterator_bit = 8 }; - template - struct access_archetype - : mpl::aux::msvc_eti_base< - typename access_archetype_impl::template archetype + // Not quite tags, since dispatching wouldn't work. + typedef mpl::int_::type readable_iterator_t; + typedef mpl::int_::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_::type swappable_iterator_t; + typedef mpl::int_::type lvalue_iterator_t; + + template + struct has_access + : mpl::equal_to< + mpl::bitand_ + , Base + > + {}; +} + +namespace detail +{ + template + struct assign_proxy + { + assign_proxy& operator=(T); + }; + + template + struct read_proxy + { + operator T(); + }; + + template + struct read_write_proxy + : assign_proxy + , read_proxy + { + }; + + template + struct arrow_proxy + { + T const* operator->() const; + }; + + struct no_operator_brackets {}; + + template + struct readable_operator_brackets + { + read_proxy operator[](std::ptrdiff_t n) const; + }; + + template + struct writable_operator_brackets + { + read_write_proxy operator[](std::ptrdiff_t n) const; + }; + + template + struct operator_brackets + : mpl::apply_if< + is_convertible + , mpl::apply_if< + iterator_archetypes::has_access< + AccessCategory + , iterator_archetypes::writable_iterator_t + > + , mpl::identity > + , mpl::if_< + iterator_archetypes::has_access< + AccessCategory + , iterator_archetypes::readable_iterator_t + > + , readable_operator_brackets + , no_operator_brackets + > + > + , mpl::identity >::type { }; - template <> - struct access_archetype_impl + template + struct traversal_archetype_impl { - template + template struct archetype; + }; + + template + struct traversal_archetype_ + : mpl::aux::msvc_eti_base< + typename traversal_archetype_impl::template archetype + >::type + {}; + + template <> + struct traversal_archetype_impl + { + template struct archetype { - typedef typename remove_cv::type value_type; - typedef Value reference; - typedef Value* pointer; + typedef void difference_type; - value_type operator*() const; - - detail::arrow_proxy operator->() const; + Derived& operator++(); + Derived operator++(int) const; }; }; template <> - struct access_archetype_impl + struct traversal_archetype_impl { - template + template struct archetype + : public equality_comparable< traversal_archetype_ >, + public traversal_archetype_ { + }; + }; + + template + bool operator==(traversal_archetype_ const&, + traversal_archetype_ const&); + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // doesn't seem to pick up != from equality_comparable + template + bool operator!=(traversal_archetype_ const&, + traversal_archetype_ const&); +#endif + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + typedef std::ptrdiff_t difference_type; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + Derived& operator--(); + Derived operator--(int) const; + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public partially_ordered >, + public traversal_archetype_ + { + Derived& operator+=(std::ptrdiff_t); + Derived& operator-=(std::ptrdiff_t); + }; + }; + + template + Derived& operator+(traversal_archetype_ const&, + std::ptrdiff_t); + + template + Derived& operator+(std::ptrdiff_t, + traversal_archetype_ const&); + + template + Derived& operator-(traversal_archetype_ const&, + std::ptrdiff_t); + + template + std::ptrdiff_t operator-(traversal_archetype_ const&, + traversal_archetype_ const&); + + template + bool operator<(traversal_archetype_ const&, + traversal_archetype_ const&); + + struct bogus_type; + + template + struct convertible_type + : mpl::if_< is_const, + typename remove_const::type, + bogus_type > + {}; + +} // namespace detail + + +template struct undefined; + +template +struct iterator_access_archetype_impl +{ + template struct archetype; +}; + +template +struct iterator_access_archetype + : mpl::aux::msvc_eti_base< + typename iterator_access_archetype_impl< + AccessCategory + >::template archetype + >::type +{ +}; + +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::readable_iterator_t +> +{ + template + struct archetype + { + typedef typename remove_cv::type value_type; + typedef Value reference; + typedef Value* pointer; + + value_type operator*() const; + + detail::arrow_proxy operator->() const; + }; +}; + +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::writable_iterator_t +> +{ + template + struct archetype + { # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - BOOST_STATIC_ASSERT(!is_const::value); + BOOST_STATIC_ASSERT(!is_const::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 operator*() const; - }; - }; + detail::assign_proxy operator*() const; + }; +}; - template <> - struct access_archetype_impl - { - template - struct archetype - : public virtual access_archetype - { - typedef detail::read_write_proxy reference; - - detail::read_write_proxy operator*() const; - }; - }; - - template <> - struct access_archetype_impl - { - template - struct archetype - : public virtual access_archetype - { - typedef Value& reference; - - Value& operator*() const; - Value* operator->() const; - }; - }; - - template <> - struct access_archetype_impl - { - template - struct archetype - : public virtual access_archetype - { -# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - BOOST_STATIC_ASSERT((!is_const::value)); -# endif - }; - }; - - - template - struct iterator_archetype; - - template - struct traversal_archetype_base - : detail::operator_brackets< - typename remove_cv::type - , AccessCategory - , TraversalCategory - > - , detail::traversal_archetype_< - iterator_archetype - , Value - , TraversalCategory +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::readable_writable_iterator_t +> +{ + template + struct archetype + : public virtual iterator_access_archetype< + Value, iterator_archetypes::readable_iterator_t > - { - }; + { + typedef detail::read_write_proxy reference; - template - struct iterator_archetype - : public traversal_archetype_base - , public access_archetype + detail::read_write_proxy 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 - , typename access_archetype::value_type - , typename traversal_archetype_base< - Value, AccessCategory, TraversalCategory - >::difference_type - > +template <> +struct iterator_access_archetype_impl +{ + template + 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 +{ + template + 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)); # endif - { - // Derivation from std::iterator above caused ambiguity, so now - // we have to declare all the types here. + }; +}; + + +template +struct iterator_archetype; + +template +struct traversal_archetype_base + : detail::operator_brackets< + typename remove_cv::type + , AccessCategory + , TraversalCategory + > + , detail::traversal_archetype_< + iterator_archetype + , Value + , TraversalCategory + > +{ +}; + +template +struct iterator_archetype + : public traversal_archetype_base + , public iterator_access_archetype + + // 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_type value_type; + + , public std::iterator< + iterator_tag + , typename iterator_access_archetype::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_type value_type; - typedef typename access_archetype::pointer pointer; + typedef typename iterator_access_archetype::pointer pointer; - typedef typename access_archetype::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::reference reference; - typedef iterator_tag 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 + , add_const + >::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::type, AccessCategory, TraversalCategory> const&); - }; + // Optional conversion from mutable + // iterator_archetype(iterator_archetype::type, AccessCategory, TraversalCategory> const&); +}; } // namespace boost diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index bb11cc6..cf5ac39 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -17,17 +17,12 @@ # include # include # include +# include # include +# include -# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include -# include -# else -# include -# endif -# endif +# include 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 + struct minimum_category_impl; + + template + struct error_not_related_by_convertibility; + + template <> + struct minimum_category_impl + { + template struct apply + { + typedef T2 type; + }; + }; + + template <> + struct minimum_category_impl + { + template struct apply + { + typedef T1 type; + }; + }; + + template <> + struct minimum_category_impl + { + template struct apply + { + BOOST_STATIC_ASSERT((is_same::value)); + typedef T1 type; + }; + }; + + template <> + struct minimum_category_impl + { + template struct apply + : error_not_related_by_convertibility + { + }; + }; + + template + struct minimum_category + { + typedef minimum_category_impl< + ::boost::is_convertible::value + , ::boost::is_convertible::value + > outer; + + typedef typename outer::template apply 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 + { + 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 + struct pure_traversal_tag + : mpl::apply_if< + is_convertible + , mpl::identity + , mpl::apply_if< + is_convertible + , mpl::identity + , mpl::apply_if< + is_convertible + , mpl::identity + , mpl::apply_if< + is_convertible + , mpl::identity + , mpl::apply_if< + is_convertible + , mpl::identity + , void + > + > + > + > + > + { + }; + } // namespace detail diff --git a/include/boost/iterator/iterator_concepts.hpp b/include/boost/iterator/iterator_concepts.hpp index 31dd265..208fd84 100644 --- a/include/boost/iterator/iterator_concepts.hpp +++ b/include/boost/iterator/iterator_concepts.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include // 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::value_type value_type; typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits::reference reference; - typedef BOOST_DEDUCED_TYPENAME ::boost::access_category::type access_category; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); @@ -64,8 +64,6 @@ namespace boost_concepts { boost::function_requires< boost::DefaultConstructibleConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::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 class WritableIteratorConcept { public: - typedef typename boost::access_category::type access_category; - + void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); - *i = v; // a good alternative could be something like write(x, v) } ValueType v; @@ -95,11 +90,8 @@ namespace boost_concepts { template class SwappableIteratorConcept { public: - typedef typename boost::access_category::type access_category; void constraints() { - BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); - std::iter_swap(i1, i2); } Iterator i1; @@ -107,25 +99,25 @@ namespace boost_concepts { }; template - class ReadableLvalueIteratorConcept { - public: - typedef typename boost::detail::iterator_traits::value_type value_type; - typedef typename boost::detail::iterator_traits::reference reference; - typedef typename boost::access_category::type access_category; + class ReadableLvalueIteratorConcept + { + public: + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; - void constraints() { - boost::function_requires< ReadableIteratorConcept >(); + void constraints() + { + boost::function_requires< ReadableIteratorConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); - - typedef boost::mpl::or_< - boost::is_same, - boost::is_same > correct_reference; + typedef boost::mpl::or_< + boost::is_same + , boost::is_same + > 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::value_type value_type; typedef typename boost::detail::iterator_traits::reference reference; - typedef typename boost::access_category::type access_category; void constraints() { boost::function_requires< @@ -145,7 +136,6 @@ namespace boost_concepts { boost::function_requires< SwappableIteratorConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); } @@ -157,14 +147,19 @@ namespace boost_concepts { template class IncrementableIteratorConcept { public: - typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::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 class SinglePassIteratorConcept { public: - typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< IncrementableIteratorConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::value)); + BOOST_STATIC_ASSERT( + (boost::is_convertible< + traversal_category + , boost::single_pass_traversal_tag + >::value + )); } }; template class ForwardTraversalConcept { public: - typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::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::value)); + BOOST_STATIC_ASSERT( + (boost::is_convertible< + traversal_category + , boost::forward_traversal_tag + >::value + )); } }; template class BidirectionalTraversalConcept { public: - typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; void constraints() { boost::function_requires< ForwardTraversalConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::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 class RandomAccessTraversalConcept { public: - typedef typename boost::traversal_category::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< BidirectionalTraversalConcept >(); - BOOST_STATIC_ASSERT((boost::detail::is_tag::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::type traversal_category; + typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; - typedef typename boost::traversal_category::type + typedef typename boost::iterator_traversal::type const_traversal_category; typedef typename boost::detail::iterator_traits::difference_type const_difference_type; diff --git a/include/boost/iterator/new_iterator_tests.hpp b/include/boost/iterator/new_iterator_tests.hpp index 2f904ce..6169080 100644 --- a/include/boost/iterator/new_iterator_tests.hpp +++ b/include/boost/iterator/new_iterator_tests.hpp @@ -160,9 +160,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2) readable_iterator_test(i2, v2); } -template -void id_type(T const&) { T::no_SuchMember x; } - // random access // Preconditions: [i,i+N) is a valid range template @@ -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::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::value_type x = j[N - 1 - c]; + assert(*i == x); Iterator q = k - c; assert(*i == *q); assert(i > j); diff --git a/include/boost/iterator/transform_iterator.hpp b/include/boost/iterator/transform_iterator.hpp index cb41f07..3474ccf 100644 --- a/include/boost/iterator/transform_iterator.hpp +++ b/include/boost/iterator/transform_iterator.hpp @@ -24,6 +24,8 @@ #include #include +#include + namespace boost { template @@ -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 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 + >::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::type >::value)); -#endif - - typedef typename mpl::apply_if< - is_same< Reference, use_default > - , function_object_result - , mpl::identity - >::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 + >::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::type - >::type access_category; - - public: - typedef iterator_adaptor< - transform_iterator - , Iterator - , cv_value_type - , access_category - , result_type - > type; + public: + typedef iterator_adaptor< + transform_iterator + , Iterator + , cv_value_type + , use_default // Leave the traversal category alone + , reference + > type; }; } @@ -150,12 +137,16 @@ namespace boost return transform_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 - // 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 + is_class // We should probably find a cheaper test than is_class<> , transform_iterator >::type make_transform_iterator(Iterator it) @@ -174,4 +165,6 @@ namespace boost } // namespace boost +#include + #endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index cc12591..8d60894 100755 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -26,7 +26,7 @@ #include #include // for enable_if_convertible #include -#include +#include #include @@ -380,7 +380,7 @@ namespace boost { { typedef typename tuple_impl_specific::tuple_meta_transform< IteratorTuple - , traversal_category + , iterator_traversal >::type tuple_of_traversal_tags; typedef typename tuple_impl_specific::tuple_meta_accumulate< @@ -398,31 +398,6 @@ namespace boost { }; #endif - template - struct iterator_is_readable - : is_tag< - readable_iterator_tag - , typename access_category::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 - { - template - struct apply : iterator_is_readable - {}; - }; -# 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 - struct all_iterators_in_tuple_readable - { - - typedef typename tuple_impl_specific::tuple_meta_transform< - IteratorTuple, - iterator_is_readable - >::type tuple_of_readability_bools; - - typedef typename tuple_impl_specific::tuple_meta_accumulate< - tuple_of_readability_bools, - and_with_two_args - , mpl::bool_ - >::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, value_type, - access_category, traversal_category, reference, difference_type diff --git a/test/Jamfile b/test/Jamfile index 1a7b9a1..639541c 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -34,7 +34,6 @@ test-suite iterator [ run counting_iterator_test.cpp ] [ run permutation_iterator_test.cpp : : : # on ] - [ compile iterator_categories.cpp ] [ run zip_iterator_test.cpp ] [ run ../../utility/iterator_adaptor_examples.cpp ] diff --git a/test/concept_tests.cpp b/test/concept_tests.cpp index 5370f76..4f850a1 100644 --- a/test/concept_tests.cpp +++ b/test/concept_tests.cpp @@ -10,10 +10,13 @@ #include #include "static_assert_same.hpp" // remove +struct new_random_access + : std::random_access_iterator_tag + , boost::random_access_traversal_tag +{}; + struct new_iterator - : public boost::iterator< boost::iterator_tag< - boost::writable_lvalue_iterator_tag - , boost::random_access_traversal_tag>, int> + : public boost::iterator< new_random_access, int > { int& operator*() const { return *m_x; } new_iterator& operator++() { return *this; } @@ -52,103 +55,15 @@ struct old_iterator }; old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; } -struct my_writable_lvalue_iterator_tag -{ - operator boost::writable_lvalue_iterator_tag() const; -}; - -struct my_single_pass_traversal_tag -{ - operator boost::single_pass_traversal_tag() const; -}; - -void test_tag_convertibility() -{ - // This set of tests is by no means complete. - - // Test that this is an input/output iterator -#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - { - typedef boost::iterator_tag< - boost::writable_lvalue_iterator_tag - , boost::single_pass_traversal_tag - > tag; - - BOOST_STATIC_ASSERT(( - boost::is_convertible::value - )); - BOOST_STATIC_ASSERT(( - boost::is_convertible::value - )); - BOOST_STATIC_ASSERT(( - !boost::is_convertible::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::value - )); - BOOST_STATIC_ASSERT(( - boost::is_convertible::value - )); - BOOST_STATIC_ASSERT(( - !boost::is_convertible::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::value - )); - BOOST_STATIC_ASSERT(( - !boost::is_convertible::value - )); - BOOST_STATIC_ASSERT(( - !boost::is_convertible::value - )); - } -#endif -} - int main() { - test_tag_convertibility(); - - typedef boost::iterator_tag< boost::writable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag; - - // BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator::value)); - int test = static_assert_same::value; - test = static_assert_same::value; - - // BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator::value)); - test = static_assert_same::value; - test = static_assert_same::value; - - typedef boost::traversal_category::type traversal_category; - - // BOOST_STATIC_ASSERT(boost::detail::has_traversal::value); - BOOST_STATIC_ASSERT(boost::detail::is_new_iterator_tag::value); - - - test = static_assert_same::value; - (void)test; + typedef boost::iterator_traversal::type traversal_category; + BOOST_STATIC_ASSERT( + (boost::is_convertible::value + )); + boost::function_requires< boost_concepts::WritableLvalueIteratorConcept >(); boost::function_requires< diff --git a/test/filter_iterator_test.cpp b/test/filter_iterator_test.cpp index a00af95..c09a1b6 100644 --- a/test/filter_iterator_test.cpp +++ b/test/filter_iterator_test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -38,12 +39,12 @@ int main() filter_iter(one_or_four(), array, array+N) , dummyT(1), dummyT(4)); - BOOST_STATIC_ASSERT(( - !boost::detail::is_tag< - boost::random_access_traversal_tag - , boost::traversal_category::type - >::value - )); + BOOST_STATIC_ASSERT( + (!boost::is_convertible< + boost::iterator_traversal::type + , boost::random_access_traversal_tag + >::value + )); //# endif diff --git a/test/is_lvalue_iterator.cpp b/test/is_lvalue_iterator.cpp index 9c23c9c..86026e8 100755 --- a/test/is_lvalue_iterator.cpp +++ b/test/is_lvalue_iterator.cpp @@ -71,17 +71,17 @@ int main() BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::value); - BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator::value); - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); - BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator::iterator>::value); - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::const_iterator>::value); - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator > >::value); - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator >::value); - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator::iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator::const_iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator > >::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator >::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator::value); #ifndef BOOST_NO_LVALUE_RETURN_DETECTION - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator::value); #endif - BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator::value); return 0; } diff --git a/test/iterator_archetype_cc.cpp b/test/iterator_archetype_cc.cpp index 1edf5e5..b5badea 100644 --- a/test/iterator_archetype_cc.cpp +++ b/test/iterator_archetype_cc.cpp @@ -12,14 +12,15 @@ int main() { - { - typedef boost::iterator_archetype iter; + typedef boost::iterator_archetype< + int + , boost::iterator_archetypes::writable_lvalue_iterator_t + , boost::random_access_traversal_tag + > iter; boost::function_requires< boost_concepts::WritableLvalueIteratorConcept >(); boost::function_requires< boost_concepts::RandomAccessTraversalConcept >(); - } - return 0; // keep msvc happy + + return 0; // keep msvc happy } diff --git a/test/iterator_categories.cpp b/test/iterator_categories.cpp deleted file mode 100755 index e36f2c9..0000000 --- a/test/iterator_categories.cpp +++ /dev/null @@ -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 - -using namespace boost; - -// Utility function which converts an iterator_category into a -// traversal tag -template -typename iterator_category_to_traversal::type c2t(C) -{ - typedef typename iterator_category_to_traversal::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()); -random_access_iter x2 = cat(iterator_tag()); -bidirectional_iter x3 = cat(iterator_tag()); -forward_iter x4 = cat(iterator_tag()); -input_output_iter x5 = cat(iterator_tag()); -input_iter x6 = cat(iterator_tag()); -output_iter x7 = cat(iterator_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 yz1 - = c2t(iterator_tag()); - -// Test traversal extraction from both old-style and new-style tags -random_access_traversal yy1 = trav(c2t(iterator_tag())); -bidirectional_traversal yy2 = trav(c2t(iterator_tag())); -forward_traversal yy3 = trav(c2t(iterator_tag())); -single_pass_traversal yy4 = trav(c2t(iterator_tag())); -incrementable_traversal yy5 = trav(c2t(iterator_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())); diff --git a/test/transform_iterator_test.cpp b/test/transform_iterator_test.cpp index cc73846..1551e38 100644 --- a/test/transform_iterator_test.cpp +++ b/test/transform_iterator_test.cpp @@ -231,7 +231,7 @@ main() 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); } diff --git a/test/unit_tests.cpp b/test/unit_tests.cpp index ed6c279..b74a6cf 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.cpp @@ -40,29 +40,32 @@ void category_test() using namespace boost::detail; BOOST_STATIC_ASSERT(( - !is_tag< - input_output_iterator_tag - , std::input_iterator_tag>::value)); - - BOOST_STATIC_ASSERT(( - !is_tag< - input_output_iterator_tag - , std::output_iterator_tag>::value)); - - BOOST_STATIC_ASSERT(( - is_tag< + !boost::is_convertible< std::input_iterator_tag , input_output_iterator_tag>::value)); BOOST_STATIC_ASSERT(( - is_tag< + !boost::is_convertible< std::output_iterator_tag , input_output_iterator_tag>::value)); - + BOOST_STATIC_ASSERT(( - is_tag< + boost::is_convertible< input_output_iterator_tag - , std::forward_iterator_tag>::value)); + , std::input_iterator_tag>::value)); + + BOOST_STATIC_ASSERT(( + boost::is_convertible< + input_output_iterator_tag + , std::output_iterator_tag>::value)); + +#if 0 // This seems wrong; we're not advertising + // input_output_iterator_tag are we? + BOOST_STATIC_ASSERT(( + boost::is_convertible< + std::forward_iterator_tag + , input_output_iterator_tag>::value)); +#endif int test = static_assert_min_cat< std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag @@ -72,9 +75,11 @@ void category_test() input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag >::value; +#if 0 test = static_assert_min_cat< input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag >::value; +#endif test = static_assert_min_cat< std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag @@ -84,29 +89,13 @@ void category_test() std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag >::value; +#if 0 // This would be wrong: a random access iterator is not + // neccessarily writable, as is an output iterator. test = static_assert_min_cat< std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag >::value; +#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; } diff --git a/test/zip_iterator_test.cpp b/test/zip_iterator_test.cpp index d6fcc2b..f33dbd9 100755 --- a/test/zip_iterator_test.cpp +++ b/test/zip_iterator_test.cpp @@ -48,32 +48,18 @@ #include #include #include +#include #include #include #include -// Uncomment to see static assert. -// #define PROVOKE_STATIC_ASSERT - -///////////////////////////////////////////////////////////////////////////// -// -// Fake iterator for testing zip iterator categories -// -///////////////////////////////////////////////////////////////////////////// - -class fake_writable_iterator -{ -public: - typedef int& reference; - typedef int value_type; - typedef int* pointer; - typedef ptrdiff_t difference_type; - typedef boost::iterator_tag< - boost::writable_iterator_tag, - boost::forward_traversal_tag - > iterator_category; -}; - +template +struct pure_traversal + : boost::detail::pure_traversal_tag< + typename boost::iterator_traversal::type + > +{}; + ///////////////////////////////////////////////////////////////////////////// // // Das Main Funktion @@ -871,25 +857,15 @@ int main( void ) // The big iterator of the previous test has vector, list, and set iterators. // Therefore, it must be bidirectional, but not random access. - bool bBigItIsBidirectionalIterator = boost::is_same< - boost::bidirectional_traversal_tag, - boost::traversal_category::type - >::value; - // - bool bBigItIsRandomAccessIterator = boost::is_same< - boost::random_access_traversal_tag, - boost::traversal_category::type - >::value; - // - bool bBigItIsReadableIterator = boost::is_same< - boost::readable_iterator_tag, - boost::access_category::type - >::value; - // - bool bBigItIsReadableLValueIterator = boost::is_same< - boost::readable_lvalue_iterator_tag, - boost::access_category::type - >::value; + bool bBigItIsBidirectionalIterator = boost::is_convertible< + boost::iterator_traversal::type + , boost::bidirectional_traversal_tag + >::value; + + bool bBigItIsRandomAccessIterator = boost::is_convertible< + boost::iterator_traversal::type + , boost::random_access_traversal_tag + >::value; // A combining iterator with all vector iterators must have random access // traversal. @@ -901,63 +877,15 @@ int main( void ) > > all_vects_type; - bool bAllVectsIsRandomAccessIterator = boost::is_same< - boost::random_access_traversal_tag, - boost::traversal_category::type + bool bAllVectsIsRandomAccessIterator = boost::is_convertible< + boost::iterator_traversal::type + , boost::random_access_traversal_tag >::value; - // - bool bAllVectsIsReadableIterator = boost::is_same< - boost::readable_iterator_tag, - boost::access_category::type - >::value; - // - bool bAllVectsIsReadableLValueIterator = boost::is_same< - boost::readable_lvalue_iterator_tag, - boost::access_category::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::const_iterator, - std::set::iterator - > - >::type::value; - - bool bAllIteratorsReadable2 = - boost::detail::all_iterators_in_tuple_readable< - boost::tuples::tuple< - std::vector::const_iterator, - fake_writable_iterator, - std::set::iterator - > - >::type::value; - - // Compile-time assert because of non-readable iterator. - // -#ifdef PROVOKE_STATIC_ASSERT - typedef boost::zip_iterator< - boost::tuples::tuple< - fake_writable_iterator - > - >no_compile_type; - - no_compile_type no_compile; -#endif // The big test. if( bBigItIsBidirectionalIterator && ! bBigItIsRandomAccessIterator && - bBigItIsReadableIterator && - ! bBigItIsReadableLValueIterator && - bAllVectsIsRandomAccessIterator && - ! bAllVectsIsReadableLValueIterator && - bAllVectsIsReadableIterator && - bAllIteratorsReadable1 && - ! bAllIteratorsReadable2 + bAllVectsIsRandomAccessIterator ) { ++num_successful_tests; @@ -977,6 +905,6 @@ int main( void ) << "\nNumber of failed tests: " << static_cast(num_failed_tests) << std::endl; - return 0; + return num_failed_tests; }