diff --git a/include/boost/iterator/counting_iterator.hpp b/include/boost/iterator/counting_iterator.hpp index 120f884..d44be21 100644 --- a/include/boost/iterator/counting_iterator.hpp +++ b/include/boost/iterator/counting_iterator.hpp @@ -15,7 +15,12 @@ namespace boost { -template class counting_iterator; +template < + class Incrementable + , class CategoryOrTraversal + , class Difference +> +class counting_iterator; namespace detail { @@ -67,11 +72,12 @@ namespace detail }; BOOST_STATIC_ASSERT(is_numeric::value); - template + + template struct counting_iterator_base { typedef typename detail::ia_dflt_help< - Traversal + CategoryOrTraversal , mpl::apply_if< is_numeric , mpl::identity @@ -89,7 +95,7 @@ namespace detail >::type difference; typedef iterator_adaptor< - counting_iterator // self + counting_iterator // self , Incrementable // Base , Incrementable // Value # ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY @@ -130,11 +136,20 @@ namespace detail }; } -template +template < + class Incrementable + , class CategoryOrTraversal = use_default + , class Difference = use_default +> class counting_iterator - : public detail::counting_iterator_base::type + : public detail::counting_iterator_base< + Incrementable, CategoryOrTraversal, Difference + >::type { - typedef typename detail::counting_iterator_base::type super_t; + typedef typename detail::counting_iterator_base< + Incrementable, CategoryOrTraversal, Difference + >::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 f9f182a..c31d71c 100644 --- a/include/boost/iterator/detail/config_def.hpp +++ b/include/boost/iterator/detail/config_def.hpp @@ -25,8 +25,23 @@ #endif #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ - || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) + +// Recall that in general, compilers without partial specialization +// can't strip constness. Consider counting_iterator, which normally +// passes a const Value to iterator_facade. As a result, any code +// which makes a std::vector of the iterator's value_type will fail +// when its allocator declares functions overloaded on reference and +// const_reference (the same type). +// +// Furthermore, Borland 5.5.1 drops constness in enough ways that we +// end up using a proxy for operator[] when we otherwise shouldn't. +// Using reference constness gives it an extra hint that it can +// return the value_type from operator[] directly, but is not +// strictly neccessary. Not sure how best to resolve this one. + # define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1 + #endif #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ diff --git a/include/boost/iterator/detail/facade_iterator_category.hpp b/include/boost/iterator/detail/facade_iterator_category.hpp index 27bbc08..5766d0a 100755 --- a/include/boost/iterator/detail/facade_iterator_category.hpp +++ b/include/boost/iterator/detail/facade_iterator_category.hpp @@ -119,11 +119,6 @@ struct is_iterator_category { }; -template <> -struct is_iterator_category - : mpl::false_ -{}; - template struct is_iterator_traversal : is_convertible @@ -164,10 +159,6 @@ struct iterator_category_with_traversal # endif }; -template <> -struct iterator_category_with_traversal -{}; - // Computes an iterator_category tag whose traversal is Traversal and // which is appropriate for an iterator template @@ -191,9 +182,6 @@ struct facade_iterator_category_impl >::type type; }; -template <> -struct facade_iterator_category_impl {}; - // // Compute an iterator_category for iterator_facade // @@ -207,12 +195,6 @@ struct facade_iterator_category { }; -template <> -struct facade_iterator_category -{ - typedef int type; -}; - }} // namespace boost::detail # include diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 9a52799..bb11cc6 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -58,7 +58,7 @@ namespace detail // for new-style types. // template - struct category_to_traversal + struct old_category_to_traversal : mpl::apply_if< is_convertible , mpl::identity @@ -84,7 +84,7 @@ namespace detail # if BOOST_WORKAROUND(BOOST_MSVC, == 1200) template <> - struct category_to_traversal + struct old_category_to_traversal { typedef int type; }; @@ -100,7 +100,7 @@ struct iterator_category_to_traversal : mpl::apply_if< // if already convertible to a traversal tag, we're done. is_convertible , mpl::identity - , detail::category_to_traversal + , detail::old_category_to_traversal > {}; diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index da489c4..1de4e0f 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -12,9 +12,9 @@ #include #include -#include #include +#include #include #include @@ -32,7 +32,7 @@ namespace boost { // This forward declaration is required for the friend declaration // in iterator_core_access - template class iterator_facade; + template class iterator_facade; namespace detail { @@ -92,11 +92,13 @@ namespace boost || 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 base; @@ -208,18 +210,18 @@ namespace boost // Macros which describe the declarations of binary operators # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ template < \ - class Derived1, class V1, class C1, class R1, class D1 \ - , class Derived2, class V2, class C2, class R2, class D2 \ + class Derived1, class V1, class TC1, class R1, class D1 \ + , class Derived2, class V2, class TC2, class R2, class D2 \ > \ prefix typename detail::enable_if_interoperable< \ Derived1, Derived2, result_type \ >::type \ operator op( \ - iterator_facade 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 // @@ -240,7 +242,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); @@ -260,7 +262,7 @@ namespace boost BOOST_ITERATOR_FACADE_PLUS_HEAD( friend - , (iterator_facade const& + , (iterator_facade const& , typename Derived::difference_type) ) ; @@ -268,7 +270,7 @@ namespace boost BOOST_ITERATOR_FACADE_PLUS_HEAD( friend , (typename Derived::difference_type - , iterator_facade const&) + , iterator_facade const&) ) ; @@ -385,9 +387,13 @@ namespace boost typename detail::operator_brackets_result::type operator[](difference_type n) const { - typedef detail::iterator_writability_disabled not_writable; + typedef detail::iterator_writability_disabled + not_writable; - return detail::make_operator_brackets_result(this->derived() + n, not_writable()); + return detail::make_operator_brackets_result( + this->derived() + n + , not_writable() + ); } Derived& operator++() @@ -565,13 +571,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 48b7b63..2f904ce 100644 --- a/include/boost/iterator/new_iterator_tests.hpp +++ b/include/boost/iterator/new_iterator_tests.hpp @@ -77,11 +77,12 @@ void constant_lvalue_iterator_test(Iterator i, T v1) assert(v1 == v2); # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) BOOST_STATIC_ASSERT(is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator::value); # endif } template -void writable_lvalue_iterator_test(Iterator i, T v1, T v2) +void non_const_lvalue_iterator_test(Iterator i, T v1, T v2) { Iterator i2(i); typedef typename detail::iterator_traits::value_type value_type; @@ -89,11 +90,12 @@ void writable_lvalue_iterator_test(Iterator i, T v1, T v2) BOOST_STATIC_ASSERT((is_same::value)); T& v3 = *i2; assert(v1 == v3); - *i = v2; + // *i = v2; -- A non-const lvalue iterator is not neccessarily writable T& v4 = *i2; assert(v2 == v4); # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) BOOST_STATIC_ASSERT(is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator::value); # endif } @@ -158,6 +160,8 @@ 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 @@ -168,6 +172,7 @@ 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) { assert(i == j + c); assert(*i == vals[c]);