diff --git a/include/boost/detail/iterator.hpp b/include/boost/detail/iterator.hpp new file mode 100644 index 0000000..8652b8f --- /dev/null +++ b/include/boost/detail/iterator.hpp @@ -0,0 +1,207 @@ +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// Boost versions of +// +// std::iterator_traits<>::iterator_category +// std::iterator_traits<>::difference_type +// std::distance() +// +// ...for all compilers and iterators + +#ifndef ITERATOR_DWA122600_HPP_ +# define ITERATOR_DWA122600_HPP_ + +# include +# include +# include +# include + +// 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 +// container iterators have _Iterator_category. +// +// Also, whether debugging is enabled or not, there is a broken specialization +// of std::iterator which has no +// typedefs but iterator_category. +// the proper typedef. +# if defined(__SGI_STL_PORT) && (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) + +# ifdef __STL_DEBUG +# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# endif + +# define BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +# endif // STLPort <= 4.1b4 && no partial specialization + +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif + +namespace boost { namespace detail { +# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +using std::iterator_traits; +using std::distance; +# else +// Workarounds for less-capable implementations +template struct iterator_traits_select; +template <> struct iterator_traits_select +{ + template + struct traits + { + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + }; +}; + + +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +no_result bad_category_helper(...); +template yes_result bad_category_helper(std::_DBG_iter*); + +template struct bad_category_select; +template <> +struct bad_category_select +{ + template + struct category { typedef typename Iterator::_Iterator_category type; }; +}; +template <> +struct bad_category_select +{ + template + struct category { typedef typename Iterator::iterator_category type; }; +}; + +template +struct iterator_category_select +{ + private: + static Iterator p; + enum { has_bad_category + = sizeof(bad_category_helper(&p)) == sizeof(yes_result) }; + typedef bad_category_select category_select; + public: + typedef typename category_select::template category::type type; +}; + +# endif + +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +template struct bad_difference_select; +template <> +struct bad_difference_select +{ + template + struct difference { typedef void type; }; +}; +template <> +struct bad_difference_select +{ + template + struct difference { typedef typename Iterator::difference_type type; }; +}; +yes_result bad_output_iterator_helper(std::iterator*); +no_result bad_output_iterator_helper(...); +# endif + +template <> struct iterator_traits_select +{ + template + struct traits +# if defined(BOOST_NO_STD_ITERATOR_TRAITS) + { +# if defined(BOOST_MSVC) && !defined(__SGI_STL_PORT) + typedef typename Iterator::distance_type difference_type; +# elif !defined(BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION) + typedef typename Iterator::difference_type difference_type; +# else + private: + // static Iterator *p; + typedef bad_difference_select< + is_convertible* + >::value> difference_type_select; + public: + typedef typename difference_type_select::template difference::type difference_type; +# endif + +# if !defined(BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF) + typedef typename Iterator::iterator_category iterator_category; +# else + typedef typename iterator_category_select::type iterator_category; +# endif + }; +# else + { + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + }; +# endif +}; + +template +struct iterator_traits +{ + private: + typedef iterator_traits_select::type>::value> select; + typedef typename select::template traits traits; + public: + typedef typename traits::difference_type difference_type; + typedef typename traits::iterator_category iterator_category; +}; + +template +struct distance_select { + template + static typename ::boost::detail::iterator_traits::difference_type + distance(Iterator i1, const Iterator i2) + { + typename ::boost::detail::iterator_traits::difference_type result = 0; + while (i1 != i2) + { + ++i1; + ++result; + } + return result; + } +}; + +template <> +struct distance_select { + template + static typename ::boost::detail::iterator_traits::difference_type + distance(const Iterator i1, const Iterator i2) + { + return i2 - i1; + } +}; + +template +inline typename ::boost::detail::iterator_traits::difference_type +distance(const Iterator& first, const Iterator& last) +{ + typedef typename ::boost::detail::iterator_traits::iterator_category iterator_category; + return distance_select::distance(first, last); +} +# endif // workarounds + +}} + +# undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +#endif // ITERATOR_DWA122600_HPP_