diff --git a/include/boost/python/suite/indexing/iterator_traits.hpp b/include/boost/python/suite/indexing/iterator_traits.hpp index 9d688730..dc487f6c 100755 --- a/include/boost/python/suite/indexing/iterator_traits.hpp +++ b/include/boost/python/suite/indexing/iterator_traits.hpp @@ -94,20 +94,67 @@ namespace boost { namespace python { namespace indexing { }; namespace iterator_detail { - typedef char input_iter_sizer[1]; - typedef char forward_iter_sizer[2]; - typedef char bidirectional_iter_sizer[3]; - typedef char random_access_iter_sizer[4]; + typedef char input_sizer[1]; + typedef char forward_sizer[2]; + typedef char bidirectional_sizer[3]; + typedef char random_access_sizer[4]; - input_iter_sizer &sizer (std::input_iterator_tag const &); - forward_iter_sizer &sizer (std::forward_iterator_tag const &); - bidirectional_iter_sizer &sizer (std::bidirectional_iterator_tag const &); - random_access_iter_sizer &sizer (std::random_access_iterator_tag const &); +#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + // Fix tested on "MIPSpro Compilers: Version 7.3.1.3m", where the + // overload resolution variant causes an "ambiguous by inheritance" + // error without even instantiating traits_by_category + + template struct is_random_access { + static bool const value = ::boost::is_convertible< + Category, std::random_access_iterator_tag>::value; + }; + + template struct is_bidirectional { + static bool const value = ::boost::is_convertible< + Category, std::bidirectional_iterator_tag>::value; + }; + + template struct is_forward { + static bool const value = ::boost::is_convertible< + Category, std::forward_iterator_tag>::value; + }; + + template struct is_input { + static bool const value = ::boost::is_convertible< + Category, std::input_iterator_tag>::value; + }; + + template struct sizer_struct { + BOOST_STATIC_CONSTANT (size_t, value = + (is_random_access::value + ? sizeof (random_access_sizer) + : (is_bidirectional::value + ? sizeof (bidirectional_sizer) + : (is_forward::value + ? sizeof (forward_sizer) + : (is_input::value + ? sizeof (input_sizer) + : 0))))); + }; + +#else + + input_sizer &sizer_fn (std::input_iterator_tag const &); + forward_sizer &sizer_fn (std::forward_iterator_tag const &); + bidirectional_sizer &sizer_fn (std::bidirectional_iterator_tag const &); + random_access_sizer &sizer_fn (std::random_access_iterator_tag const &); + + template struct sizer_struct { + BOOST_STATIC_CONSTANT (size_t, value = + sizeof (sizer_fn (Category()))); + }; + +#endif template struct traits_by_size { }; template<> - struct traits_by_size { + struct traits_by_size { template struct traits { typedef input_iterator_traits type; @@ -115,7 +162,7 @@ namespace boost { namespace python { namespace indexing { }; template<> - struct traits_by_size { + struct traits_by_size { template struct traits { typedef forward_iterator_traits type; @@ -123,7 +170,7 @@ namespace boost { namespace python { namespace indexing { }; template<> - struct traits_by_size { + struct traits_by_size { template struct traits { typedef bidirectional_iterator_traits type; @@ -131,7 +178,7 @@ namespace boost { namespace python { namespace indexing { }; template<> - struct traits_by_size { + struct traits_by_size { template struct traits { typedef random_access_iterator_traits type; @@ -143,7 +190,7 @@ namespace boost { namespace python { namespace indexing { typedef typename BOOST_ITERATOR_CATEGORY::type category; BOOST_STATIC_CONSTANT ( - size_t, size = sizeof (sizer (category()))); + size_t, size = sizer_struct::value); public: typedef typename traits_by_size