mirror of
https://github.com/boostorg/detail.git
synced 2025-07-30 04:17:14 +02:00
Cleanups on boost::iterator_traits<>
Broke MSVC though :( [SVN r16157]
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
|
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify,
|
||||||
// sell and distribute this software is granted provided this
|
// sell and distribute this software is granted provided this
|
||||||
// copyright notice appears in all copies. This software is provided
|
// copyright notice appears in all copies. This software is provided
|
||||||
// "as is" without express or implied warranty, and with no claim as
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
@ -20,11 +20,6 @@
|
|||||||
// std::iterator_traits<X>::pointer
|
// std::iterator_traits<X>::pointer
|
||||||
// std::iterator_traits<X>::reference
|
// 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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
@ -57,17 +52,17 @@
|
|||||||
# define ITERATOR_DWA122600_HPP_
|
# define ITERATOR_DWA122600_HPP_
|
||||||
|
|
||||||
# include <boost/config.hpp>
|
# include <boost/config.hpp>
|
||||||
# include <boost/type_traits.hpp>
|
# include <boost/mpl/apply_if.hpp>
|
||||||
# include <boost/iterator.hpp>
|
# include <boost/mpl/identity.hpp>
|
||||||
|
# include <boost/type_traits/remove_const.hpp>
|
||||||
|
# include <boost/type_traits/detail/yes_no_type.hpp>
|
||||||
|
# include <boost/type_traits/is_pointer.hpp>
|
||||||
|
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||||
# include <iterator>
|
# include <iterator>
|
||||||
# include <cstddef>
|
# include <cstddef>
|
||||||
|
|
||||||
# if defined(BOOST_MSVC_STD_ITERATOR) && !defined(__SGI_STL_PORT)
|
// should be the last #include
|
||||||
# include <xtree>
|
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
||||||
# include <deque>
|
|
||||||
# include <list>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
// STLPort 4.0 and betas have a bug when debugging is enabled and there is no
|
// 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
|
// partial specialization: instead of an iterator_category typedef, the standard
|
||||||
@ -76,9 +71,9 @@
|
|||||||
// Also, whether debugging is enabled or not, there is a broken specialization
|
// 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
|
// of std::iterator<output_iterator_tag,void,void,void,void> which has no
|
||||||
// typedefs but iterator_category.
|
// 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
|
# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -87,293 +82,264 @@
|
|||||||
# endif // STLPort <= 4.1b4 && no partial specialization
|
# endif // STLPort <= 4.1b4 && no partial specialization
|
||||||
|
|
||||||
namespace boost { namespace detail {
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
|
# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
using std::iterator_traits;
|
using std::iterator_traits;
|
||||||
using std::distance;
|
using std::distance;
|
||||||
# else
|
# else
|
||||||
|
|
||||||
namespace iterator_traits_ {
|
// is_mutable_iterator --
|
||||||
|
//
|
||||||
|
// A metafunction returning true iff T is a mutable iterator
|
||||||
|
// type with a nested value_type.
|
||||||
|
|
||||||
// Workarounds for less-capable implementations
|
// This one detects ordinary mutable iterators - the result of
|
||||||
template <bool is_ptr> struct iterator_traits_select;
|
// 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*);
|
||||||
|
|
||||||
template <class T> struct undefined;
|
// This one detects output iterators such as ostream_iterator which
|
||||||
template <> struct iterator_traits_select<true>
|
// 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
|
||||||
{
|
{
|
||||||
template <class Ptr>
|
static T t;
|
||||||
struct traits
|
|
||||||
{
|
BOOST_STATIC_CONSTANT(bool, value = sizeof(
|
||||||
typedef std::ptrdiff_t difference_type;
|
detail::is_mutable_iterator_helper((T*)0, &*t))
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
== sizeof(type_traits::yes_type)
|
||||||
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
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||||
|
is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl<T>::value)
|
||||||
|
|
||||||
typedef char yes_type;
|
|
||||||
typedef double no_type;
|
|
||||||
|
|
||||||
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
// 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>
|
||||||
|
type_traits::yes_type is_full_iterator_traits_helper(
|
||||||
|
T const volatile*
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::value_type* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::reference (*)() = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::pointer* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::difference_type* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::iterator_category* = 0
|
||||||
|
);
|
||||||
|
|
||||||
no_type bad_category_helper(...);
|
type_traits::no_type is_full_iterator_traits_helper(...);
|
||||||
template <class C, class T> yes_type bad_category_helper(std::_DBG_iter<C,T>*);
|
|
||||||
|
|
||||||
template <bool has_bad_category_typedef> struct bad_category_select;
|
template <class T>
|
||||||
template <>
|
struct is_full_iterator_traits_impl
|
||||||
struct bad_category_select<true>
|
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
enum { value = sizeof(
|
||||||
struct category { typedef typename Iterator::_Iterator_category type; };
|
is_full_iterator_traits_helper((T*)0)) == sizeof(type_traits::yes_type) };
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct bad_category_select<false>
|
|
||||||
{
|
|
||||||
template <class Iterator>
|
|
||||||
struct category { typedef typename Iterator::iterator_category type; };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Iterator>
|
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||||
struct iterator_category_select
|
is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl<T>::value)
|
||||||
|
|
||||||
|
|
||||||
|
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
|
// 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>
|
||||||
|
type_traits::yes_type is_stlport_40_debug_iterator_helper(
|
||||||
|
T const volatile*
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::value_type* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::reference (*)() = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::pointer* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::difference_type* = 0
|
||||||
|
, BOOST_DEDUCED_TYPENAME T::_Iterator_category* = 0
|
||||||
|
);
|
||||||
|
|
||||||
|
type_traits::no_type is_stlport_40_debug_iterator_helper(...);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct is_stlport_40_debug_iterator_impl
|
||||||
{
|
{
|
||||||
private:
|
enum { value = sizeof(
|
||||||
static Iterator p;
|
is_stlport_40_debug_iterator_helper((T*)0)) == sizeof(type_traits::yes_type) };
|
||||||
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
|
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||||
|
is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl<T>::value)
|
||||||
|
|
||||||
# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
template <class T>
|
||||||
template <bool is_bad_output_iterator> struct bad_output_iterator_select;
|
struct stlport_40_debug_iterator_traits
|
||||||
template <>
|
|
||||||
struct bad_output_iterator_select<true>
|
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
typedef typename T::value_type value_type;
|
||||||
struct non_category_traits {
|
typedef typename T::reference reference;
|
||||||
typedef void value_type;
|
typedef typename T::pointer pointer;
|
||||||
typedef void difference_type;
|
typedef typename T::difference_type difference_type;
|
||||||
typedef void pointer;
|
typedef typename T::_Iterator_category iterator_category;
|
||||||
typedef void reference;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
template <>
|
# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
struct bad_output_iterator_select<false>
|
|
||||||
|
template <class T>
|
||||||
|
struct pointer_iterator_traits
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
typedef T pointer;
|
||||||
struct non_category_traits {
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
typedef typename Iterator::value_type value_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
typedef typename Iterator::difference_type difference_type;
|
};
|
||||||
typedef typename Iterator::pointer pointer;
|
|
||||||
typedef typename Iterator::reference reference;
|
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
};
|
template <class T>
|
||||||
|
struct pointer_iterator_traits<T*>
|
||||||
|
{
|
||||||
|
typedef 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;
|
||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if defined(BOOST_MSVC_STD_ITERATOR) && !defined(__SGI_STL_PORT)
|
|
||||||
|
|
||||||
// We'll sort iterator types into one of these classifications, from which we
|
// We'll sort iterator types into one of these classifications, from which we
|
||||||
// can determine the difference_type, pointer, reference, and value_type
|
// can determine the difference_type, pointer, reference, and value_type
|
||||||
enum {
|
template <class Iterator>
|
||||||
not_msvc_stdlib_iterator,
|
struct standard_iterator_traits
|
||||||
msvc_stdlib_const_iterator,
|
|
||||||
msvc_stdlib_mutable_iterator,
|
|
||||||
msvc_stdlib_ostream_iterator
|
|
||||||
};
|
|
||||||
|
|
||||||
template <unsigned> struct msvc_traits_select;
|
|
||||||
|
|
||||||
template <> struct msvc_traits_select<not_msvc_stdlib_iterator>
|
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
typedef typename Iterator::difference_type difference_type;
|
||||||
struct traits_ // calling this "traits" will confuse VC.
|
typedef typename Iterator::value_type value_type;
|
||||||
{
|
typedef typename Iterator::pointer pointer;
|
||||||
typedef typename Iterator::difference_type difference_type;
|
typedef typename Iterator::reference reference;
|
||||||
typedef typename Iterator::value_type value_type;
|
typedef typename Iterator::iterator_category iterator_category;
|
||||||
typedef typename Iterator::pointer pointer;
|
|
||||||
typedef typename Iterator::reference reference;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct msvc_traits_select<msvc_stdlib_mutable_iterator>
|
template <class Iterator>
|
||||||
|
struct msvc_stdlib_mutable_traits
|
||||||
|
: std::iterator_traits<Iterator>
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
|
||||||
struct traits_
|
typedef value_type* pointer;
|
||||||
{
|
typedef value_type& reference;
|
||||||
typedef typename Iterator::distance_type difference_type;
|
|
||||||
typedef typename Iterator::value_type value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct msvc_traits_select<msvc_stdlib_const_iterator>
|
template <class Iterator>
|
||||||
|
struct msvc_stdlib_const_traits
|
||||||
|
: std::iterator_traits<Iterator>
|
||||||
{
|
{
|
||||||
template <class Iterator>
|
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
|
||||||
struct traits_
|
typedef const value_type* pointer;
|
||||||
{
|
typedef const value_type& reference;
|
||||||
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>
|
# 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 void pointer;
|
|
||||||
typedef void reference;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// These functions allow us to detect which classification a given iterator type
|
struct bad_output_iterator_traits
|
||||||
// falls into.
|
{
|
||||||
|
typedef void value_type;
|
||||||
// Is the iterator derived from std::iterator?
|
typedef void difference_type;
|
||||||
no_type is_std_iterator_helper(...);
|
typedef std::output_iterator_tag iterator_category;
|
||||||
template <class V, class D, class C>
|
typedef void pointer;
|
||||||
yes_type is_std_iterator_helper(const volatile std::iterator<V,D,C>*);
|
typedef void reference;
|
||||||
|
|
||||||
// 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(...);
|
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
template <> struct iterator_traits_select<false>
|
template <class Iterator>
|
||||||
|
struct non_pointer_iterator_traits
|
||||||
|
: mpl::if_<
|
||||||
|
is_full_iterator_traits<Iterator>
|
||||||
|
, standard_iterator_traits<Iterator>
|
||||||
|
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
|
, mpl::if_<
|
||||||
|
is_stlport_40_debug_iterator<Iterator>
|
||||||
|
, stlport_40_debug_iterator_traits<Iterator>
|
||||||
|
# endif
|
||||||
|
, mpl::if_<
|
||||||
|
is_mutable_iterator<Iterator>
|
||||||
|
, msvc_stdlib_mutable_traits<Iterator>
|
||||||
|
, msvc_stdlib_const_traits<Iterator>
|
||||||
|
>::type
|
||||||
|
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
|
>::type
|
||||||
|
# endif
|
||||||
|
>::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_aux
|
||||||
|
: mpl::if_<
|
||||||
|
is_pointer<Iterator>
|
||||||
|
, pointer_iterator_traits<Iterator>
|
||||||
|
, non_pointer_iterator_traits<Iterator>
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
struct iterator_traits
|
struct iterator_traits
|
||||||
: iterator_traits_::iterator_traits_select<is_pointer<Iterator>::value>::template traits<Iterator>
|
# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
||||||
|
: mpl::if_<
|
||||||
|
is_bad_output_iterator<Iterator>
|
||||||
|
, bad_output_iterator_traits
|
||||||
|
, iterator_traits_aux<Iterator>
|
||||||
|
>::type
|
||||||
|
# else
|
||||||
|
: iterator_traits_aux<Iterator>
|
||||||
|
# endif
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
typedef typename iterator_traits_::iterator_traits_select<
|
|
||||||
is_pointer<remove_cv<Iterator>::type>::value>::template traits<Iterator> 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace iterator_traits_ {
|
namespace iterator_traits_
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct iterator_difference
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<T>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Category>
|
template <class Iterator, class Difference>
|
||||||
struct distance_select {
|
struct distance_select
|
||||||
template <class Iterator>
|
{
|
||||||
static typename ::boost::detail::iterator_traits<Iterator>::difference_type
|
static Difference execute(Iterator i1, const Iterator i2, ...)
|
||||||
distance(Iterator i1, const Iterator i2)
|
{
|
||||||
{
|
typename Difference result = 0;
|
||||||
typename ::boost::detail::iterator_traits<Iterator>::difference_type result = 0;
|
while (i1 != i2)
|
||||||
while (i1 != i2)
|
{
|
||||||
{
|
++i1;
|
||||||
++i1;
|
++result;
|
||||||
++result;
|
}
|
||||||
}
|
return result;
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*)
|
||||||
|
{
|
||||||
|
return i2 - i1;
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace boost::detail::iterator_traits_
|
} // namespace boost::detail::iterator_traits_
|
||||||
|
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
inline typename ::boost::detail::iterator_traits<Iterator>::difference_type
|
inline typename iterator_traits_::iterator_difference<Iterator>::type
|
||||||
distance(const Iterator& first, const Iterator& last)
|
distance(Iterator first, Iterator last)
|
||||||
{
|
{
|
||||||
|
typedef typename iterator_traits_::iterator_difference<Iterator>::type diff_t;
|
||||||
typedef typename ::boost::detail::iterator_traits<Iterator>::iterator_category iterator_category;
|
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
|
# endif // workarounds
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user