diff --git a/include/boost/detail/iterator.hpp b/include/boost/detail/iterator.hpp index 5c4ea17..4376006 100644 --- a/include/boost/detail/iterator.hpp +++ b/include/boost/detail/iterator.hpp @@ -12,10 +12,20 @@ // // ...for all compilers and iterators // +// Additionally, if partial specialization is supported or X is not a pointer +// std::iterator_traits::value_type +// +// And if partial specialization is supported or (X is not a pointer and the +// library isn't the VC6 standard library), +// std::iterator_traits::pointer +// std::iterator_traits::reference // See http://www.boost.org for most recent version including documentation. // Revision History +// 07 Feb 2001 - Support for more of the traits members where possible, making +// this useful as a replacement for std::iterator_traits when +// used as a default template parameter. // 06 Feb 2001 - Removed useless #includes of standard library headers // (David Abrahams) @@ -49,8 +59,10 @@ namespace boost { namespace detail { using std::iterator_traits; using std::distance; # else + // Workarounds for less-capable implementations template struct iterator_traits_select; + template <> struct iterator_traits_select { template @@ -95,23 +107,33 @@ struct iterator_category_select # endif # ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION -template struct bad_difference_select; +template struct bad_output_iterator_select; template <> -struct bad_difference_select +struct bad_output_iterator_select { template - struct difference { typedef void type; }; + struct non_category_traits { + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + }; }; template <> -struct bad_difference_select +struct bad_output_iterator_select { template - struct difference { typedef typename Iterator::difference_type type; }; + struct non_category_traits { + typedef typename Iterator::value_type value_type; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + }; }; -yes_result bad_output_iterator_helper(std::iterator*); -no_result bad_output_iterator_helper(...); # endif +template struct undefined; + template <> struct iterator_traits_select { template @@ -120,17 +142,24 @@ template <> struct iterator_traits_select { # if defined(BOOST_MSVC) && !defined(__SGI_STL_PORT) typedef typename Iterator::distance_type difference_type; + typedef typename Iterator::value_type value_type; # elif !defined(BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION) typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; # else - private: - // static Iterator *p; - typedef bad_difference_select< + typedef bad_output_iterator_select< is_convertible* - >::value> difference_type_select; + >::value> non_category_traits_select; + typedef non_category_traits_select::template non_category_traits non_category_traits; public: - typedef typename difference_type_select::template difference::type difference_type; + typedef typename non_category_traits::value_type value_type; + typedef typename non_category_traits::difference_type difference_type; + typedef typename non_category_traits::pointer pointer; + typedef typename non_category_traits::reference reference; # endif # if !defined(BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF) @@ -149,11 +178,14 @@ template <> struct iterator_traits_select template struct iterator_traits + : iterator_traits_select::type>::value>::template traits { private: - typedef iterator_traits_select::type>::value> select; - typedef typename select::template traits traits; + typedef typename iterator_traits_select< + is_pointer::type>::value>::template traits traits; public: + // Why do I need to define these typedefs? It keeps MSVC happy somehow. + // Why don't I need to define the other typedefs? Who knows?!? typedef typename traits::difference_type difference_type; typedef typename traits::iterator_category iterator_category; };