diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index dbfc0f9..d96880d 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -169,15 +169,14 @@ namespace boost { template - type_traits::yes_type is_new_iter_cat(T*, typename T::traversal* = 0) { } + type_traits::yes_type is_new_iter_cat(T*, BOOST_DEDUCED_TYPENAME T::traversal* = 0); - type_traits::no_type is_new_iter_cat(...) { } + type_traits::no_type is_new_iter_cat(...); template struct is_new_iterator_tag { - static Tag* t; - enum { value = sizeof(is_new_iter_cat(t)) == sizeof(type_traits::yes_type) }; + enum { value = (sizeof(is_new_iter_cat((Tag*)0)) == sizeof(type_traits::yes_type)) }; }; #endif @@ -209,23 +208,22 @@ namespace boost { template struct return_category_tag + : mpl::apply_if< + is_new_iterator_tag + , get_return_category + , iter_category_to_return + > { - typedef typename - mpl::apply_if< - is_new_iterator_tag - , get_return_category - , iter_category_to_return - >::type type; }; + template struct traversal_category_tag - { - typedef typename - mpl::apply_if< + : mpl::apply_if< is_new_iterator_tag , get_traversal_category , iter_category_to_return - >::type type; + > + { }; } // namespace detail diff --git a/include/boost/iterator/iterator_concepts.hpp b/include/boost/iterator/iterator_concepts.hpp index 743b111..910ac3d 100644 --- a/include/boost/iterator/iterator_concepts.hpp +++ b/include/boost/iterator/iterator_concepts.hpp @@ -12,11 +12,26 @@ #include #include +// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. +#include + namespace boost_concepts { // Used a different namespace here (instead of "boost") so that the // concept descriptions do not take for granted the names in // namespace boost. + // We use this in place of STATIC_ASSERT((is_convertible<...>)) + // because some compilers (CWPro7.x) can't detect convertibility. + // + // Of course, that just gets us a different error at the moment with + // some tests, since new iterator category deduction still depends + // on convertibility detection. We might need some specializations + // to support this compiler. + template + struct static_assert_base_and_derived + { + static_assert_base_and_derived(Target* x = (Source*)0) {} + }; //=========================================================================== // Iterator Access Concepts @@ -24,8 +39,8 @@ namespace boost_concepts { template class ReadableIteratorConcept { public: - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; typedef typename boost::return_category::type return_category; void constraints() { @@ -33,9 +48,8 @@ namespace boost_concepts { boost::function_requires< boost::EqualityComparableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); - - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + + static_assert_base_and_derived(); reference r = *i; // or perhaps read(x) value_type v(r); @@ -55,8 +69,7 @@ namespace boost_concepts { boost::function_requires< boost::DefaultConstructibleConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); *i = v; // a good alternative could be something like write(x, v) } @@ -67,15 +80,14 @@ namespace boost_concepts { template class ConstantLvalueIteratorConcept { public: - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; typedef typename boost::return_category::type return_category; void constraints() { boost::function_requires< ReadableIteratorConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); BOOST_STATIC_ASSERT((boost::is_same::value)); @@ -89,8 +101,8 @@ namespace boost_concepts { template class MutableLvalueIteratorConcept { public: - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::reference reference; typedef typename boost::return_category::type return_category; void constraints() { @@ -98,8 +110,7 @@ namespace boost_concepts { boost::function_requires< WritableIteratorConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); BOOST_STATIC_ASSERT((boost::is_same::value)); @@ -123,8 +134,8 @@ namespace boost_concepts { boost::function_requires< boost::DefaultConstructibleConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); + ++i; (void)i++; } @@ -139,8 +150,7 @@ namespace boost_concepts { void constraints() { boost::function_requires< ForwardTraversalConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); --i; (void)i--; @@ -152,14 +162,14 @@ namespace boost_concepts { class RandomAccessTraversalConcept { public: typedef typename boost::traversal_category::type traversal_category; - typedef typename std::iterator_traits::difference_type + typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< BidirectionalTraversalConcept >(); - BOOST_STATIC_ASSERT((boost::is_convertible::value)); + static_assert_base_and_derived(); + i += n; i = i + n;