diff --git a/include/boost/detail/iterator.hpp b/include/boost/detail/iterator.hpp index 8601fbc..70d83f1 100644 --- a/include/boost/detail/iterator.hpp +++ b/include/boost/detail/iterator.hpp @@ -52,17 +52,7 @@ # define ITERATOR_DWA122600_HPP_ # include -# include -# include -# include -# include -# include -# include # include -# include - -// should be the last #include -# include "boost/type_traits/detail/bool_trait_def.hpp" // STLPort 4.0 and betas have a bug when debugging is enabled and there is no // partial specialization: instead of an iterator_category typedef, the standard @@ -81,18 +71,12 @@ # endif // STLPort <= 4.1b4 && no partial specialization -namespace boost { namespace detail { - -BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) -BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) -BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer) -BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type) -BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category) - # if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \ && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MSVC_STD_ITERATOR) +namespace boost { namespace detail { + // Define a new template so it can be specialized template struct iterator_traits @@ -100,12 +84,17 @@ struct iterator_traits {}; using std::distance; +}} // namespace boost::detail + # else + # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MSVC_STD_ITERATOR) // This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS +namespace boost { namespace detail { + // Rogue Wave Standard Library fools itself into thinking partial // specialization is missing on some platforms (e.g. Sun), so fails to // supply iterator_traits! @@ -139,8 +128,48 @@ struct iterator_traits typedef std::random_access_iterator_tag iterator_category; }; +}} // namespace boost::detail + # else +# include +# include +# include + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# include +# endif +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +# include +# endif + +# include + +# include +# if BOOST_MSVC == 1300 +# include +# include +# endif + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# include +# endif +# include +# include + +// should be the last #include +# include "boost/type_traits/detail/bool_trait_def.hpp" + +namespace boost { namespace detail { + +BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) +BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer) +BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category) + // is_mutable_iterator -- // // A metafunction returning true iff T is a mutable iterator type @@ -244,9 +273,65 @@ struct pointer_iterator_traits typedef std::random_access_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; }; -# else -template -struct must_manually_specialize_boost_detail_iterator_traits; +# else + +// In case of no template partial specialization, and if T is a +// pointer, iterator_traits::value_type can still be computed. For +// some basic types, remove_pointer is manually defined in +// type_traits/broken_compiler_spec.hpp. For others, do it yourself. + +template class please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee; + +template +struct pointer_value_type +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) || BOOST_WORKAROUND(__EDG_VERSION__, != 0) +// Special formulation required to get +// please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee +// to show up in vc7 errors. It's better to use the other one if +// possible because it means you can use the other members of +// iterator_traits + : mpl::apply_if< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , remove_const< + typename remove_pointer

::type + > + > +# else + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_const< + typename remove_pointer

::type + >::type + > +# endif +{ +}; + + +template +struct pointer_reference +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) || BOOST_WORKAROUND(__EDG_VERSION__, != 0) +// Special formulation required to get +// please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee to +// show up in vc7 errors. It's better to use the other one if +// possible because it means you can use the other members of +// iterator_traits + : mpl::apply_if< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , add_reference::type> + > +# else + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_pointer

::type& + > +# endif +{ +}; template struct pointer_iterator_traits @@ -255,24 +340,10 @@ struct pointer_iterator_traits typedef std::random_access_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - // Makes MSVC6 happy under some circumstances - typedef must_manually_specialize_boost_detail_iterator_traits value_type; - typedef must_manually_specialize_boost_detail_iterator_traits reference; + typedef typename pointer_value_type::type value_type; + typedef typename pointer_reference::type reference; }; -// Use this as a base class in manual iterator_traits specializations -// for pointer types. T should be the value_type. CV should be the -// cv-qualified value_type to which */& is added in order to produce -// pointer/reference. -template -struct ptr_iter_traits -{ - typedef T value_type; - typedef CV* pointer; - typedef CV& reference; - typedef std::random_access_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; -}; # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // We'll sort iterator types into one of these classifications, from which we @@ -394,7 +465,11 @@ struct iterator_traits // This specialization cuts off ETI (Early Template Instantiation) for MSVC. template <> struct iterator_traits{}; -# endif +}} // namespace boost::detail + +# endif // workarounds + +namespace boost { namespace detail { namespace iterator_traits_ { @@ -429,9 +504,11 @@ distance(Iterator first, Iterator last) return iterator_traits_::distance_select::execute( first, last, (iterator_category*)0); } -# endif // workarounds -}} // namespace boost::detail +}} + +# endif + # undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF # undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION