-// (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.
+// (C) Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
// Boost versions of
//
// std::iterator_traits<X>::pointer
// std::iterator_traits<X>::reference
//
-// CAVEAT: When using the VC6 standard library, an iterator derived from
-// std::iterator but not boost::iterator or from one supplied by the standard
-// will always have pointer == const value_type* and reference == const
-// value_type&, whether that's correct or not.
-
// See http://www.boost.org for most recent version including documentation.
// Revision History
# define ITERATOR_DWA122600_HPP_
# include <boost/config.hpp>
-# include <boost/type_traits.hpp>
-# include <boost/iterator.hpp>
# include <iterator>
-# include <cstddef>
-
-# if defined(BOOST_MSVC_STD_ITERATOR) && !defined(__SGI_STL_PORT)
-# include <xtree>
-# include <deque>
-# include <list>
-# endif
-
// 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
// Also, whether debugging is enabled or not, there is a broken specialization
// of std::iterator<output_iterator_tag,void,void,void,void> which has no
// typedefs but iterator_category.
-# if defined(__SGI_STL_PORT) && (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION)
+# if defined(__SGI_STL_PORT)
-# ifdef __STL_DEBUG
+# if (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && defined(__STL_DEBUG)
# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
# endif
# endif // STLPort <= 4.1b4 && no partial specialization
+# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \
+ && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+ && !defined(BOOST_MSVC_STD_ITERATOR)
+
namespace boost { namespace detail {
-# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
-using std::iterator_traits;
+
+// Define a new template so it can be specialized
+template <class Iterator>
+struct iterator_traits
+ : std::iterator_traits<Iterator>
+{};
using std::distance;
+
+}} // namespace boost::detail
+
# else
-namespace iterator_traits_ {
+# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+ && !defined(BOOST_MSVC_STD_ITERATOR)
-// Workarounds for less-capable implementations
-template <bool is_ptr> struct iterator_traits_select;
+// This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS
-template <class T> struct undefined;
-template <> struct iterator_traits_select<true>
+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!
+template <class Iterator>
+struct iterator_traits
{
- template <class Ptr>
- struct traits
- {
- typedef std::ptrdiff_t difference_type;
- typedef std::random_access_iterator_tag iterator_category;
- typedef Ptr pointer;
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-// Keeps MSVC happy under certain circumstances. It seems class template default
-// arguments are partly instantiated even when not used when the class template
-// is the return type of a function template.
- typedef undefined<void> value_type;
- typedef undefined<void> reference;
-#endif
+ typedef typename Iterator::value_type value_type;
+ typedef typename Iterator::reference reference;
+ typedef typename Iterator::pointer pointer;
+ typedef typename Iterator::difference_type difference_type;
+ typedef typename Iterator::iterator_category iterator_category;
+};
+
+template <class T>
+struct iterator_traits<T*>
+{
+ typedef T value_type;
+ typedef T& reference;
+ typedef T* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+
+template <class T>
+struct iterator_traits<T const*>
+{
+ typedef T value_type;
+ typedef T const& reference;
+ typedef T const* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+
+}} // namespace boost::detail
+
+# else
+
+# include <boost/type_traits/remove_const.hpp>
+# include <boost/type_traits/detail/yes_no_type.hpp>
+# include <boost/type_traits/is_pointer.hpp>
+
+# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+# include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/remove_pointer.hpp>
+# endif
+# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
+# include <boost/type_traits/is_base_and_derived.hpp>
+# endif
+
+# include <boost/mpl/if.hpp>
+# include <boost/mpl/has_xxx.hpp>
+# include <cstddef>
+
+// 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
+// with a nested value_type. Will only work portably with iterators
+// whose operator* returns a reference, but that seems to be OK for
+// the iterators supplied by Dinkumware. Some input iterators may
+// compile-time if they arrive here, and if the compiler is strict
+// about not taking the address of an rvalue.
+
+// This one detects ordinary mutable iterators - the result of
+// operator* is convertible to the value_type.
+template <class T>
+type_traits::yes_type is_mutable_iterator_helper(T const*, BOOST_DEDUCED_TYPENAME T::value_type*);
+
+// Since you can't take the address of an rvalue, the guts of
+// is_mutable_iterator_impl will fail if we use &*t directly. This
+// makes sure we can still work with non-lvalue iterators.
+template <class T> T* mutable_iterator_lvalue_helper(T& x);
+int mutable_iterator_lvalue_helper(...);
+
+
+// This one detects output iterators such as ostream_iterator which
+// return references to themselves.
+template <class T>
+type_traits::yes_type is_mutable_iterator_helper(T const*, T const*);
+
+type_traits::no_type is_mutable_iterator_helper(...);
+
+template <class T>
+struct is_mutable_iterator_impl
+{
+ static T t;
+
+ BOOST_STATIC_CONSTANT(
+ bool, value = sizeof(
+ detail::is_mutable_iterator_helper(
+ (T*)0
+ , mutable_iterator_lvalue_helper(*t) // like &*t
+ ))
+ == sizeof(type_traits::yes_type)
+ );
+};
+
+BOOST_TT_AUX_BOOL_TRAIT_DEF1(
+ is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl<T>::value)
+
+
+// is_full_iterator_traits --
+//
+// A metafunction returning true iff T has all the requisite nested
+// types to satisfy the requirements for a fully-conforming
+// iterator_traits implementation.
+template <class T>
+struct is_full_iterator_traits_impl
+{
+ enum { value =
+ has_value_type<T>::value
+ & has_reference<T>::value
+ & has_pointer<T>::value
+ & has_difference_type<T>::value
+ & has_iterator_category<T>::value
};
};
+BOOST_TT_AUX_BOOL_TRAIT_DEF1(
+ is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl<T>::value)
-typedef char yes_type;
-typedef double no_type;
-# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+BOOST_MPL_HAS_XXX_TRAIT_DEF(_Iterator_category)
+
+// is_stlport_40_debug_iterator --
+//
+// A metafunction returning true iff T has all the requisite nested
+// types to satisfy the requirements of an STLPort 4.0 debug iterator
+// iterator_traits implementation.
+template <class T>
+struct is_stlport_40_debug_iterator_impl
+{
+ enum { value =
+ has_value_type<T>::value
+ & has_reference<T>::value
+ & has_pointer<T>::value
+ & has_difference_type<T>::value
+ & has__Iterator_category<T>::value
+ };
+};
-no_type bad_category_helper(...);
-template <class C, class T> yes_type bad_category_helper(std::_DBG_iter<C,T>*);
+BOOST_TT_AUX_BOOL_TRAIT_DEF1(
+ is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl<T>::value)
-template <bool has_bad_category_typedef> struct bad_category_select;
-template <>
-struct bad_category_select<true>
+template <class T>
+struct stlport_40_debug_iterator_traits
{
- template <class Iterator>
- struct category { typedef typename Iterator::_Iterator_category type; };
+ typedef typename T::value_type value_type;
+ typedef typename T::reference reference;
+ typedef typename T::pointer pointer;
+ typedef typename T::difference_type difference_type;
+ typedef typename T::_Iterator_category iterator_category;
};
-template <>
-struct bad_category_select<false>
+# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+
+template <class T> struct pointer_iterator_traits;
+
+# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T>
+struct pointer_iterator_traits<T*>
{
- template <class Iterator>
- struct category { typedef typename Iterator::iterator_category type; };
+ typedef typename remove_const<T>::type value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
};
+# else
-template <class Iterator>
-struct iterator_category_select
+// In case of no template partial specialization, and if T is a
+// pointer, iterator_traits<T>::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 P> class please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee;
+
+template<class P>
+struct pointer_value_type
+ : mpl::if_<
+ is_same<P, typename remove_pointer<P>::type>
+ , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>
+ , typename remove_const<
+ typename remove_pointer<P>::type
+ >::type
+ >
{
- private:
- static Iterator p;
- enum { has_bad_category
- = sizeof(bad_category_helper(&p)) == sizeof(yes_type) };
- typedef bad_category_select<has_bad_category> category_select;
- public:
- typedef typename category_select::template category<Iterator>::type type;
};
-# endif
-# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
-template <bool is_bad_output_iterator> struct bad_output_iterator_select;
-template <>
-struct bad_output_iterator_select<true>
+template<class P>
+struct pointer_reference
+ : mpl::if_<
+ is_same<P, typename remove_pointer<P>::type>
+ , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>
+ , typename remove_pointer<P>::type&
+ >
{
- template <class Iterator>
- struct non_category_traits {
- typedef void value_type;
- typedef void difference_type;
- typedef void pointer;
- typedef void reference;
- };
};
-template <>
-struct bad_output_iterator_select<false>
+
+template <class T>
+struct pointer_iterator_traits
{
- template <class Iterator>
- 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;
- };
+ typedef T pointer;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef typename pointer_value_type<T>::type value_type;
+ typedef typename pointer_reference<T>::type reference;
};
-# endif
-# if defined(BOOST_MSVC_STD_ITERATOR) && !defined(__SGI_STL_PORT)
+# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// We'll sort iterator types into one of these classifications, from which we
// can determine the difference_type, pointer, reference, and value_type
-enum {
- not_msvc_stdlib_iterator,
- msvc_stdlib_const_iterator,
- msvc_stdlib_mutable_iterator,
- msvc_stdlib_ostream_iterator
+template <class Iterator>
+struct standard_iterator_traits
+{
+ typedef typename Iterator::difference_type difference_type;
+ typedef typename Iterator::value_type value_type;
+ typedef typename Iterator::pointer pointer;
+ typedef typename Iterator::reference reference;
+ typedef typename Iterator::iterator_category iterator_category;
};
-
-template <unsigned> struct msvc_traits_select;
-template <> struct msvc_traits_select<not_msvc_stdlib_iterator>
+template <class Iterator>
+struct msvc_stdlib_mutable_traits
+ : std::iterator_traits<Iterator>
{
- template <class Iterator>
- struct traits_ // calling this "traits" will confuse VC.
- {
- typedef typename Iterator::difference_type difference_type;
- typedef typename Iterator::value_type value_type;
- typedef typename Iterator::pointer pointer;
- typedef typename Iterator::reference reference;
- };
+ typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
+ typedef typename std::iterator_traits<Iterator>::value_type* pointer;
+ typedef typename std::iterator_traits<Iterator>::value_type& reference;
};
-template <> struct msvc_traits_select<msvc_stdlib_mutable_iterator>
+template <class Iterator>
+struct msvc_stdlib_const_traits
+ : std::iterator_traits<Iterator>
{
- template <class Iterator>
- struct traits_
- {
- typedef typename Iterator::distance_type difference_type;
- typedef typename Iterator::value_type value_type;
- typedef value_type* pointer;
- typedef value_type& reference;
- };
+ typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
+ typedef const typename std::iterator_traits<Iterator>::value_type* pointer;
+ typedef const typename std::iterator_traits<Iterator>::value_type& reference;
};
-template <> struct msvc_traits_select<msvc_stdlib_const_iterator>
+# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
+template <class Iterator>
+struct is_bad_output_iterator
+ : is_base_and_derived<
+ std::iterator<std::output_iterator_tag,void,void,void,void>
+ , Iterator>
{
- template <class Iterator>
- struct traits_
- {
- typedef typename Iterator::distance_type difference_type;
- typedef typename Iterator::value_type value_type;
- typedef const value_type* pointer;
- typedef const value_type& reference;
- };
};
-template <> struct msvc_traits_select<msvc_stdlib_ostream_iterator>
+struct bad_output_iterator_traits
{
- template <class Iterator>
- struct traits_
- {
- typedef typename Iterator::distance_type difference_type;
- typedef typename Iterator::value_type value_type;
- typedef void pointer;
- typedef void reference;
- };
+ typedef void value_type;
+ typedef void difference_type;
+ typedef std::output_iterator_tag iterator_category;
+ typedef void pointer;
+ typedef void reference;
};
+# endif
-// These functions allow us to detect which classification a given iterator type
-// falls into.
-
-// Is the iterator derived from std::iterator?
-no_type is_std_iterator_helper(...);
-template <class V, class D, class C>
-yes_type is_std_iterator_helper(const volatile std::iterator<V,D,C>*);
-
-// Is the iterator derived from boost::iterator?
-template <class C, class T, class D, class P, class R>
-yes_type is_boost_iterator_helper(const volatile boost::iterator<C,T,D,P,R>*);
-no_type is_boost_iterator_helper(...);
-
-// Is the iterator one of the known mutable container iterators?
-template<class K, class Ty, class Kfn, class Pr, class A>
-yes_type is_mutable_iterator_helper(const volatile typename std::_Tree<K,Ty,Kfn,Pr,A>::iterator*);
-template<class Ty, class A>
-yes_type is_mutable_iterator_helper(const volatile typename std::list<Ty,A>::iterator*);
-template<class Ty, class A>
-yes_type is_mutable_iterator_helper(const volatile typename std::deque<Ty,A>::iterator*);
-no_type is_mutable_iterator_helper(...);
-
-// Is the iterator an ostream_iterator?
-template<class T, class CharT, class Traits>
-yes_type is_ostream_iterator_helper(const volatile std::ostream_iterator<T,CharT,Traits>*);
-no_type is_ostream_iterator_helper(...);
+// If we're looking at an MSVC6 (old Dinkumware) ``standard''
+// iterator, this will generate an appropriate traits class.
+template <class Iterator>
+struct msvc_stdlib_iterator_traits
+ : mpl::if_<
+ is_mutable_iterator<Iterator>
+ , msvc_stdlib_mutable_traits<Iterator>
+ , msvc_stdlib_const_traits<Iterator>
+ >::type
+{};
-template <class T>
-struct msvc_iterator_classification {
- BOOST_STATIC_CONSTANT(unsigned,
- value = (sizeof(is_ostream_iterator_helper((T*)0)) == sizeof(yes_type))
- ? msvc_stdlib_ostream_iterator
- : (sizeof(is_mutable_iterator_helper((T*)0)) == sizeof(yes_type))
- ? msvc_stdlib_mutable_iterator
- : (sizeof(is_std_iterator_helper((T*)0)) == sizeof(yes_type)
- && sizeof(is_boost_iterator_helper((T*)0)) == sizeof(no_type))
- ? msvc_stdlib_const_iterator
- : not_msvc_stdlib_iterator
- );
+template <class Iterator>
+struct non_pointer_iterator_traits
+ : mpl::if_<
+ // if the iterator contains all the right nested types...
+ is_full_iterator_traits<Iterator>
+ // Use a standard iterator_traits implementation
+ , standard_iterator_traits<Iterator>
+# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+ // Check for STLPort 4.0 broken _Iterator_category type
+ , mpl::if_<
+ is_stlport_40_debug_iterator<Iterator>
+ , stlport_40_debug_iterator_traits<Iterator>
+# endif
+ // Otherwise, assume it's a Dinkum iterator
+ , msvc_stdlib_iterator_traits<Iterator>
+# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+ >::type
+# endif
+ >::type
+{
};
-# endif
-template <> struct iterator_traits_select<false>
+template <class Iterator>
+struct iterator_traits_aux
+ : mpl::if_<
+ is_pointer<Iterator>
+ , pointer_iterator_traits<Iterator>
+ , non_pointer_iterator_traits<Iterator>
+ >::type
{
- template <class Iterator>
- struct traits
- {
-# if defined(BOOST_MSVC_STD_ITERATOR) && !defined(__SGI_STL_PORT)
- typedef msvc_traits_select<(
- msvc_iterator_classification<Iterator>::value
- )>::template traits_<Iterator> inner_traits;
-
- typedef typename inner_traits::difference_type difference_type;
- typedef typename inner_traits::value_type value_type;
- typedef typename inner_traits::pointer pointer;
- typedef typename inner_traits::reference reference;
-# elif !defined(BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION)
- typedef typename Iterator::difference_type difference_type;
- typedef typename Iterator::value_type value_type;
- typedef typename Iterator::pointer pointer;
- typedef typename Iterator::reference reference;
-# else
- typedef bad_output_iterator_select<
- is_convertible<const volatile Iterator*,
- const volatile std::iterator<std::output_iterator_tag,void,void,void,void>*
- >::value> non_category_traits_select;
- typedef non_category_traits_select::template non_category_traits<Iterator> non_category_traits;
- public:
- 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)
- typedef typename Iterator::iterator_category iterator_category;
-# else
- typedef typename iterator_category_select<Iterator>::type iterator_category;
-# endif
- };
};
-} // namespace boost::detail::iterator_traits_
-
template <class Iterator>
struct iterator_traits
- : iterator_traits_::iterator_traits_select<is_pointer<Iterator>::value>::template traits<Iterator>
{
+ // Explicit forwarding from base class needed to keep MSVC6 happy
+ // under some circumstances.
private:
- typedef typename iterator_traits_::iterator_traits_select<
- is_pointer<remove_cv<Iterator>::type>::value>::template traits<Iterator> traits;
+# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
+ typedef
+ typename mpl::if_<
+ is_bad_output_iterator<Iterator>
+ , bad_output_iterator_traits
+ , iterator_traits_aux<Iterator>
+ >::type base;
+# else
+ typedef iterator_traits_aux<Iterator> base;
+# endif
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;
+ typedef typename base::value_type value_type;
+ typedef typename base::pointer pointer;
+ typedef typename base::reference reference;
+ typedef typename base::difference_type difference_type;
+ typedef typename base::iterator_category iterator_category;
};
-namespace iterator_traits_ {
-
-template <class Category>
-struct distance_select {
- template <class Iterator>
- static typename ::boost::detail::iterator_traits<Iterator>::difference_type
- distance(Iterator i1, const Iterator i2)
- {
- typename ::boost::detail::iterator_traits<Iterator>::difference_type result = 0;
- while (i1 != i2)
- {
- ++i1;
- ++result;
- }
- return result;
- }
+// This specialization cuts off ETI (Early Template Instantiation) for MSVC.
+template <> struct iterator_traits<int>
+{
+ typedef int value_type;
+ typedef int pointer;
+ typedef int reference;
+ typedef int difference_type;
+ typedef int iterator_category;
};
-template <>
-struct distance_select<std::random_access_iterator_tag> {
- template <class Iterator>
- static typename ::boost::detail::iterator_traits<Iterator>::difference_type
- distance(const Iterator i1, const Iterator i2)
- {
- return i2 - i1;
- }
-};
+}} // namespace boost::detail
+
+# endif // workarounds
+namespace boost { namespace detail {
+
+namespace iterator_traits_
+{
+ template <class Iterator, class Difference>
+ struct distance_select
+ {
+ static Difference execute(Iterator i1, const Iterator i2, ...)
+ {
+ Difference result = 0;
+ while (i1 != i2)
+ {
+ ++i1;
+ ++result;
+ }
+ return result;
+ }
+
+ static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*)
+ {
+ return i2 - i1;
+ }
+ };
} // namespace boost::detail::iterator_traits_
template <class Iterator>
-inline typename ::boost::detail::iterator_traits<Iterator>::difference_type
-distance(const Iterator& first, const Iterator& last)
+inline typename iterator_traits<Iterator>::difference_type
+distance(Iterator first, Iterator last)
{
+ typedef typename iterator_traits<Iterator>::difference_type diff_t;
typedef typename ::boost::detail::iterator_traits<Iterator>::iterator_category iterator_category;
- return iterator_traits_::distance_select<iterator_category>::distance(first, last);
+
+ return iterator_traits_::distance_select<Iterator,diff_t>::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