From 62b70f57a973dfb5dd909f406c42d900a152ba45 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Nov 2003 04:25:17 +0000 Subject: [PATCH] progress [SVN r20853] --- include/boost/iterator/counting_iterator.hpp | 40 ++-- include/boost/iterator/detail/config_def.hpp | 5 + .../detail/facade_iterator_category.hpp | 220 ++++++++++++++++++ include/boost/iterator/is_lvalue_iterator.hpp | 8 +- .../boost/iterator/is_readable_iterator.hpp | 4 + include/boost/iterator/iterator_adaptor.hpp | 58 ++--- .../boost/iterator/iterator_categories.hpp | 102 +------- include/boost/iterator/iterator_facade.hpp | 108 ++++----- include/boost/iterator/new_iterator_tests.hpp | 31 ++- test/counting_iterator_test.cpp | 2 +- test/iterator_adaptor_test.cpp | 23 +- 11 files changed, 369 insertions(+), 232 deletions(-) create mode 100755 include/boost/iterator/detail/facade_iterator_category.hpp diff --git a/include/boost/iterator/counting_iterator.hpp b/include/boost/iterator/counting_iterator.hpp index d168e2d..120f884 100644 --- a/include/boost/iterator/counting_iterator.hpp +++ b/include/boost/iterator/counting_iterator.hpp @@ -15,7 +15,7 @@ namespace boost { -template class counting_iterator; +template class counting_iterator; namespace detail { @@ -67,35 +67,37 @@ namespace detail }; BOOST_STATIC_ASSERT(is_numeric::value); - template + template struct counting_iterator_base { - typedef typename mpl::apply_if< - is_same + typedef typename detail::ia_dflt_help< + Traversal , mpl::apply_if< is_numeric - , mpl::identity - , BOOST_ITERATOR_CATEGORY + , mpl::identity + , iterator_traversal > - , mpl::identity - >::type category; + >::type traversal; - typedef typename mpl::apply_if< - is_same + typedef typename detail::ia_dflt_help< + Difference , mpl::apply_if< is_numeric , numeric_difference , iterator_difference > - , mpl::identity >::type difference; typedef iterator_adaptor< - counting_iterator // self - , Incrementable // Base - , Incrementable // value_type - , category - , Incrementable const& // reference + counting_iterator // self + , Incrementable // Base + , Incrementable // Value +# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + const // MSVC won't strip this. Instead we enable Thomas' + // criterion (see boost/iterator/detail/facade_iterator_category.hpp) +# endif + , traversal + , Incrementable const& // reference , difference > type; }; @@ -128,11 +130,11 @@ namespace detail }; } -template +template class counting_iterator - : public detail::counting_iterator_base::type + : public detail::counting_iterator_base::type { - typedef typename detail::counting_iterator_base::type super_t; + typedef typename detail::counting_iterator_base::type super_t; friend class iterator_core_access; public: diff --git a/include/boost/iterator/detail/config_def.hpp b/include/boost/iterator/detail/config_def.hpp index a2e7789..f9f182a 100644 --- a/include/boost/iterator/detail/config_def.hpp +++ b/include/boost/iterator/detail/config_def.hpp @@ -24,6 +24,11 @@ # define BOOST_ITERATOR_CONFIG_DEF #endif +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) +# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1 +#endif + #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \ || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) diff --git a/include/boost/iterator/detail/facade_iterator_category.hpp b/include/boost/iterator/detail/facade_iterator_category.hpp new file mode 100755 index 0000000..27bbc08 --- /dev/null +++ b/include/boost/iterator/detail/facade_iterator_category.hpp @@ -0,0 +1,220 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP +# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP + +# include + +# include + +# include // used in iterator_tag inheritance logic +# include +# include +# include +# include + +# include +# include +# include +# include + +# include + +# include // try to keep this last + +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY +# include +# endif + +// +// iterator_category deduction for iterator_facade +// + +// forward declaration +namespace boost { struct use_default; } + +namespace boost { namespace detail { + +struct input_output_iterator_tag + : std::input_iterator_tag, std::output_iterator_tag {}; + +// +// True iff the user has explicitly disabled writability of this +// iterator. Pass the iterator_facade's Value parameter and its +// nested ::reference type. +// +template +struct iterator_writability_disabled +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? + : mpl::or_< + is_const + , python::detail::is_reference_to_const + , is_const + > +# else + : is_const +# endif +{}; + + +// +// Convert an iterator_facade's traversal category, Value parameter, +// and ::reference type to an appropriate old-style category. +// +// If writability has been disabled per the above metafunction, the +// result will not be convertible to output_iterator_tag. +// +// Otherwise, if Traversal == single_pass_traversal_tag, the following +// conditions will result in a tag that is convertible both to +// input_iterator_tag and output_iterator_tag: +// +// 1. Reference is a reference to non-const +// 2. Reference is not a reference and is convertible to Value +// +template +struct iterator_facade_default_category + : mpl::apply_if< + mpl::and_< + is_reference + , is_convertible + > + , mpl::apply_if< + is_convertible + , mpl::identity + , mpl::if_< + is_convertible + , std::bidirectional_iterator_tag + , std::forward_iterator_tag + > + > + , typename mpl::apply_if< + mpl::and_< + is_convertible + + , mpl::or_< // check for readability + is_same + , is_convertible + > + > + , mpl::if_< + iterator_writability_disabled + , std::input_iterator_tag + , input_output_iterator_tag + > + + , mpl::identity + > + > +{ +}; + +// True iff T is convertible to an old-style iterator category. +template +struct is_iterator_category + : mpl::or_< + is_convertible + , is_convertible + > +{ +}; + +template <> +struct is_iterator_category + : mpl::false_ +{}; + +template +struct is_iterator_traversal + : is_convertible +{}; + +// +// A composite iterator_category tag convertible to Category (a pure +// old-style category) and Traversal (a pure traversal tag). +// Traversal must be a strict increase of the traversal power given by +// Category. +// +template +struct iterator_category_with_traversal + : Category, Traversal +{ +# if 0 + // Because of limitations on multiple user-defined conversions, + // this should be a good test of whether convertibility is enough + // in the spec, or whether we need to specify inheritance. + operator Category() const { return Category(); } + operator Traversal() const { return Traversal(); } +# endif + +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // Make sure this isn't used to build any categories where + // convertibility to Traversal is redundant. Should just use the + // Category element in that case. + BOOST_STATIC_ASSERT( + !(is_convertible< + typename iterator_category_to_traversal::type + , Traversal + >::value)); + + BOOST_STATIC_ASSERT(is_iterator_category::value); + BOOST_STATIC_ASSERT(!is_iterator_category::value); + BOOST_STATIC_ASSERT(!is_iterator_traversal::value); + BOOST_STATIC_ASSERT(is_iterator_traversal::value); +# endif +}; + +template <> +struct iterator_category_with_traversal +{}; + +// Computes an iterator_category tag whose traversal is Traversal and +// which is appropriate for an iterator +template +struct facade_iterator_category_impl +{ +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT(!is_iterator_category::value); +# endif + + typedef typename iterator_facade_default_category< + Traversal,ValueParam,Reference + >::type category; + + typedef typename mpl::if_< + is_same< + Traversal + , typename iterator_category_to_traversal::type + > + , category + , iterator_category_with_traversal + >::type type; +}; + +template <> +struct facade_iterator_category_impl {}; + +// +// Compute an iterator_category for iterator_facade +// +template +struct facade_iterator_category + : mpl::apply_if< + is_iterator_category + , mpl::identity // old-style categories are fine as-is + , facade_iterator_category_impl + > +{ +}; + +template <> +struct facade_iterator_category +{ + typedef int type; +}; + +}} // namespace boost::detail + +# include + +#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP diff --git a/include/boost/iterator/is_lvalue_iterator.hpp b/include/boost/iterator/is_lvalue_iterator.hpp index d77b977..0376d61 100755 --- a/include/boost/iterator/is_lvalue_iterator.hpp +++ b/include/boost/iterator/is_lvalue_iterator.hpp @@ -14,6 +14,8 @@ // should be the last #include #include +#ifndef BOOST_NO_IS_CONVERTIBLE + namespace boost { namespace detail @@ -122,7 +124,7 @@ namespace detail {}; template - struct is_mutable_lvalue_iterator_impl + struct is_non_const_lvalue_iterator_impl : is_lvalue_iterator_impl< BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type >::template rebind @@ -135,10 +137,12 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1( is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl::value) BOOST_TT_AUX_BOOL_TRAIT_DEF1( - is_mutable_lvalue_iterator,T,::boost::detail::is_mutable_lvalue_iterator_impl::value) + is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl::value) } // namespace boost +#endif + #include #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP diff --git a/include/boost/iterator/is_readable_iterator.hpp b/include/boost/iterator/is_readable_iterator.hpp index 52df758..60d6ff0 100755 --- a/include/boost/iterator/is_readable_iterator.hpp +++ b/include/boost/iterator/is_readable_iterator.hpp @@ -13,6 +13,8 @@ // should be the last #include #include +#ifndef BOOST_NO_IS_CONVERTIBLE + namespace boost { namespace detail @@ -99,6 +101,8 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1( } // namespace boost +#endif + #include #endif // IS_READABLE_ITERATOR_DWA2003112_HPP diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp index bff7062..68bdaec 100644 --- a/include/boost/iterator/iterator_adaptor.hpp +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -26,7 +26,7 @@ #include #include -#ifdef BOOST_ITERATOR_REFERENCE_PRIMACY +#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY # include #else # include @@ -38,6 +38,20 @@ namespace boost { + // Used as a default template argument internally, merely to + // indicate "use the default", this can also be passed by users + // explicitly in order to specify that the default should be used. + struct use_default; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // the incompleteness of use_default causes massive problems for + // is_convertible (naturally). This workaround is fortunately not + // needed for vc6/vc7. + template + struct is_convertible + : mpl::false_ {}; +# endif + namespace detail { @@ -157,7 +171,7 @@ namespace boost typedef iterator_facade< Derived -# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY , typename detail::ia_dflt_help< Value , mpl::apply_if< @@ -177,7 +191,7 @@ namespace boost , iterator_traversal >::type -# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY , typename detail::ia_dflt_help< Reference , iterator_reference @@ -199,6 +213,7 @@ namespace boost > type; }; + template int static_assert_convertible_to(T); } // @@ -287,17 +302,18 @@ namespace boost // ); return m_iterator == x.base(); } - + + typedef typename iterator_category_to_traversal< + typename super_t::iterator_category + >::type my_traversal; + +# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \ + typedef int assertion[sizeof(detail::static_assert_convertible_to(my_traversal()))]; +// BOOST_STATIC_ASSERT((is_convertible::value)); + void advance(typename super_t::difference_type n) { -# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly - BOOST_STATIC_ASSERT( - (is_convertible< - BOOST_DEDUCED_TYPENAME super_t::iterator_category - , random_access_traversal_tag - >::value) - ); -# endif + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) m_iterator += n; } @@ -305,14 +321,7 @@ namespace boost void decrement() { -# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly - BOOST_STATIC_ASSERT( - (is_convertible< - BOOST_DEDUCED_TYPENAME super_t::iterator_category - , bidirectional_traversal_tag - >::value) - ); -# endif + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag) --m_iterator; } @@ -322,12 +331,7 @@ namespace boost typename super_t::difference_type distance_to( iterator_adaptor const& y) const { - BOOST_STATIC_ASSERT( - (is_convertible< - BOOST_DEDUCED_TYPENAME super_t::iterator_category - , random_access_traversal_tag - >::value) - ); + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) // Maybe readd with same_distance // BOOST_STATIC_ASSERT( // (detail::same_category_and_difference::value) @@ -335,6 +339,8 @@ namespace boost return y.base() - m_iterator; } +# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL + private: // data members Base m_iterator; }; diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index a868714..9a52799 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -13,16 +13,12 @@ # include -# include -# include # include # include # include # include -# include # include -# include # ifdef BOOST_ITERATOR_REFERENCE_PRIMACY # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -54,70 +50,7 @@ struct random_access_traversal_tag namespace detail { - struct input_output_iterator_tag - : std::input_iterator_tag, std::output_iterator_tag {}; - - // - // Helper for iterator_tag and iterator_facade. True iff the user - // has explicitly disabled writability of this iterator. - // - template - struct iterator_writability_disabled -# ifdef BOOST_ITERATOR_REFERENCE_PRIMACY -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - : mpl::or_,python::detail::is_reference_to_const > -# else - : is_const::type> -# endif -# else - : is_const -# endif - {}; - template - struct old_iterator_category - { - typedef typename mpl:: -# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) - if_ -# else - apply_if -# endif - < - mpl::and_< - is_reference - , is_convertible - > - , mpl::apply_if< - is_convertible - , mpl::identity - , mpl::if_< - is_convertible - , std::bidirectional_iterator_tag - , std::forward_iterator_tag - > - > -# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) - ::type -# endif - , typename mpl::apply_if< - mpl::and_< - is_convertible - , is_convertible - > - , mpl::if_< - iterator_writability_disabled - , std::input_iterator_tag - , input_output_iterator_tag - > - , mpl::identity - > -# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) - ::type -# endif - >::type type; - }; - // // Convert a "strictly old-style" iterator category to a traversal // tag. This is broken out into a separate metafunction to reduce @@ -125,7 +58,7 @@ namespace detail // for new-style types. // template - struct old_style_category_to_traversal + struct category_to_traversal : mpl::apply_if< is_convertible , mpl::identity @@ -151,7 +84,7 @@ namespace detail # if BOOST_WORKAROUND(BOOST_MSVC, == 1200) template <> - struct old_style_category_to_traversal + struct category_to_traversal { typedef int type; }; @@ -167,38 +100,10 @@ struct iterator_category_to_traversal : mpl::apply_if< // if already convertible to a traversal tag, we're done. is_convertible , mpl::identity - , detail::old_style_category_to_traversal + , detail::category_to_traversal > {}; -// -// To be used for a new-style iterator's iterator_category; provides -// implicit conversion to the appropriate old-style iterator category. -// -// If Value is const the result will not be convertible to -// output_iterator_tag. -// -// Otherwise, if Traversal == single_pass_traversal_tag, the following -// conditions will result in a tag that is convertible both to -// input_iterator_tag and output_iterator_tag: -// -// 1. Reference is a reference to non-const -// 2. Reference is not a reference and is convertible to Value -// -template -struct iterator_tag - : detail::old_iterator_category::type -{ - operator Traversal() { return Traversal(); } -# if 0 - typedef typename detail::old_iterator_category< - Value, Reference, Traversal - >::type old_category; - - operator old_category() const { return old_category(); } -# endif -}; - // Trait to get an iterator's traversal category template struct iterator_traversal @@ -226,7 +131,6 @@ struct iterator_traversal {}; # endif - } // namespace boost #include diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index c58e8cb..da489c4 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -12,21 +12,17 @@ #include #include -#include +#include #include -#include #include #include +#include +#include #include #include -#ifdef BOOST_ITERATOR_REFERENCE_PRIMACY -# include -# include -#endif - #include #include @@ -36,22 +32,8 @@ namespace boost { // This forward declaration is required for the friend declaration // in iterator_core_access - template class iterator_facade; + template class iterator_facade; - // Used as a default template argument internally, merely to - // indicate "use the default", this can also be passed by users - // explicitly in order to specify that the default should be used. - struct use_default; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - // the incompleteness of use_default causes massive problems for - // is_convertible (naturally). This workaround is fortunately not - // needed for vc6/vc7. - template - struct is_convertible - : mpl::false_ {}; -# endif - namespace detail { // @@ -82,37 +64,41 @@ namespace boost }; // - // Generates the associated types for an iterator_facade with the - // given parameters. Additionally generates a 'base' type for - // compiler/library combinations which require user-defined - // iterators to inherit from std::iterator. + // Generates associated types for an iterator_facade with the + // given parameters. // template < - class Value - , class TraversalCategory + class ValueParam + , class CategoryOrTraversal , class Reference , class Difference > struct iterator_facade_types - { - typedef iterator_tag iterator_category; - - typedef typename remove_const::type value_type; + { + typedef typename facade_iterator_category< + CategoryOrTraversal, ValueParam, Reference + >::type iterator_category; + typedef typename remove_const::type value_type; + + typedef typename mpl::apply_if< + detail::iterator_writability_disabled + , add_pointer::type> + , add_pointer + >::type pointer; + # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310) - +# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1 // To interoperate with some broken library/compiler // combinations, user-defined iterators must be derived from // std::iterator. It is possible to implement a standard // library for broken compilers without this limitation. -# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1 - typedef - iterator + iterator base; # endif }; @@ -176,10 +162,10 @@ namespace boost public: operator_brackets_proxy(Iterator const& iter) - : m_iter(iter) + : m_iter(iter) {} - operator reference() + operator reference() const { return *m_iter; } @@ -222,18 +208,18 @@ namespace boost // Macros which describe the declarations of binary operators # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ template < \ - class Derived1, class V1, class TC1, class R1, class D1 \ - , class Derived2, class V2, class TC2, class R2, class D2 \ + class Derived1, class V1, class C1, class R1, class D1 \ + , class Derived2, class V2, class C2, class R2, class D2 \ > \ prefix typename detail::enable_if_interoperable< \ Derived1, Derived2, result_type \ >::type \ operator op( \ - iterator_facade const& lhs \ - , iterator_facade const& rhs) + iterator_facade const& lhs \ + , iterator_facade const& rhs) # define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ - template \ + template \ prefix Derived operator+ args // @@ -254,7 +240,7 @@ namespace boost public: # else - template friend class iterator_facade; + template friend class iterator_facade; # define BOOST_ITERATOR_FACADE_RELATION(op) \ BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool); @@ -274,7 +260,7 @@ namespace boost BOOST_ITERATOR_FACADE_PLUS_HEAD( friend - , (iterator_facade const& + , (iterator_facade const& , typename Derived::difference_type) ) ; @@ -282,7 +268,7 @@ namespace boost BOOST_ITERATOR_FACADE_PLUS_HEAD( friend , (typename Derived::difference_type - , iterator_facade const&) + , iterator_facade const&) ) ; @@ -337,14 +323,14 @@ namespace boost template < class Derived // The derived iterator type being constructed , class Value - , class TraversalCategory + , class CategoryOrTraversal , class Reference = Value& , class Difference = std::ptrdiff_t > class iterator_facade # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE : public detail::iterator_facade_types< - Value, TraversalCategory, Reference, Difference + Value, CategoryOrTraversal, Reference, Difference >::base # undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE # endif @@ -365,21 +351,17 @@ namespace boost return static_cast(*this); } + typedef detail::iterator_facade_types< + Value, CategoryOrTraversal, Reference, Difference + > associated_types; + public: - typedef typename remove_const::type value_type; + typedef typename associated_types::value_type value_type; typedef Reference reference; typedef Difference difference_type; -# if BOOST_ITERATOR_REFERENCE_PRIMACY - typedef typename mpl::apply_if< - detail::iterator_writability_disabled - , add_pointer::type> - , add_pointer - >::type pointer; -# else - typedef Value* pointer; -# endif - typedef iterator_tag iterator_category; + typedef typename associated_types::pointer pointer; + typedef typename associated_types::iterator_category iterator_category; reference operator*() const { @@ -403,9 +385,9 @@ namespace boost typename detail::operator_brackets_result::type operator[](difference_type n) const { - typedef detail::iterator_writability_disabled use_proxy; + typedef detail::iterator_writability_disabled not_writable; - return detail::make_operator_brackets_result(this->derived() + n, use_proxy()); + return detail::make_operator_brackets_result(this->derived() + n, not_writable()); } Derived& operator++() @@ -583,13 +565,13 @@ namespace boost } BOOST_ITERATOR_FACADE_PLUS(( - iterator_facade const& i + iterator_facade const& i , typename Derived::difference_type n )) BOOST_ITERATOR_FACADE_PLUS(( typename Derived::difference_type n - , iterator_facade const& i + , iterator_facade const& i )) # undef BOOST_ITERATOR_FACADE_PLUS # undef BOOST_ITERATOR_FACADE_PLUS_HEAD diff --git a/include/boost/iterator/new_iterator_tests.hpp b/include/boost/iterator/new_iterator_tests.hpp index 759f8de..48b7b63 100644 --- a/include/boost/iterator/new_iterator_tests.hpp +++ b/include/boost/iterator/new_iterator_tests.hpp @@ -24,15 +24,11 @@ # include // for detail::dummy_constructor # include # include +# include +# include namespace boost { -void is_readable(readable_iterator_tag) { } -void is_writable(writable_iterator_tag) { } -void is_swappable(swappable_iterator_tag) { } -void is_constant_lvalue(readable_lvalue_iterator_tag) { } -void is_mutable_lvalue(writable_lvalue_iterator_tag) { } - // Preconditions: *i == v template void readable_iterator_test(const Iterator i1, T v) @@ -45,8 +41,12 @@ void readable_iterator_test(const Iterator i1, T v) T v2 = r2; assert(v1 == v); assert(v2 == v); - typedef typename access_category::type result_category; - is_readable(result_category()); + +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + // I think we don't really need this as it checks the same things as + // the above code. + BOOST_STATIC_ASSERT(is_readable_iterator::value); +# endif } template @@ -54,7 +54,6 @@ void writable_iterator_test(Iterator i, T v) { Iterator i2(i); // Copy Constructible *i2 = v; - is_writable(typename access_category::type()); } template @@ -65,8 +64,6 @@ void swappable_iterator_test(Iterator i, Iterator j) iter_swap(i2, j2); typename detail::iterator_traits::value_type ai = *i, aj = *j; assert(bi == aj && bj == ai); - typedef typename access_category::type result_category; - is_swappable(result_category()); } template @@ -78,12 +75,13 @@ void constant_lvalue_iterator_test(Iterator i, T v1) BOOST_STATIC_ASSERT((is_same::value)); const T& v2 = *i2; assert(v1 == v2); - typedef typename access_category::type result_category; - is_constant_lvalue(result_category()); +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + BOOST_STATIC_ASSERT(is_lvalue_iterator::value); +# endif } template -void mutable_lvalue_iterator_test(Iterator i, T v1, T v2) +void writable_lvalue_iterator_test(Iterator i, T v1, T v2) { Iterator i2(i); typedef typename detail::iterator_traits::value_type value_type; @@ -94,8 +92,9 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2) *i = v2; T& v4 = *i2; assert(v2 == v4); - typedef typename access_category::type result_category; - is_mutable_lvalue(result_category()); +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + BOOST_STATIC_ASSERT(is_lvalue_iterator::value); +# endif } template diff --git a/test/counting_iterator_test.cpp b/test/counting_iterator_test.cpp index fbfe70b..73f69f9 100644 --- a/test/counting_iterator_test.cpp +++ b/test/counting_iterator_test.cpp @@ -286,7 +286,7 @@ int main() # ifndef BOOST_NO_SLIST test_container >(); # endif - + // Also prove that we can handle raw pointers. int array[2000]; test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1)); diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index 9ab3583..362642a 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -181,11 +181,22 @@ struct constant_iterator : base_t(it) {} }; -char (& traversal(boost::incrementable_traversal_tag) )[1]; -char (& traversal(boost::single_pass_traversal_tag ) )[2]; -char (& traversal(boost::forward_traversal_tag ) )[3]; -char (& traversal(boost::bidirectional_traversal_tag) )[4]; -char (& traversal(boost::random_access_traversal_tag) )[5]; +char (& traversal2(boost::incrementable_traversal_tag) )[1]; +char (& traversal2(boost::single_pass_traversal_tag ) )[2]; +char (& traversal2(boost::forward_traversal_tag ) )[3]; +char (& traversal2(boost::bidirectional_traversal_tag) )[4]; +char (& traversal2(boost::random_access_traversal_tag) )[5]; + +template +struct traversal3 +{ + static typename boost::iterator_category_to_traversal::type x; + BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x))); + typedef char (&type)[value]; +}; + +template +typename traversal3::type traversal(Cat); int main() @@ -244,7 +255,7 @@ main() test = static_assert_same::value; #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator::value); BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::value); #endif