mirror of
https://github.com/boostorg/detail.git
synced 2025-07-30 12:27:15 +02:00
Moved to much cleaner system of using BOOST_TT_BROKEN_COMPILER_SPEC
for handling vc6/7 deficiencies with iterator_traits. Fixed a bug in iterator_facade which was causing incomplete types to be passed through is_convertible. Reinstated libs/utility/iterator_traits_test.cpp [SVN r19840]
This commit is contained in:
@ -52,17 +52,7 @@
|
|||||||
# define ITERATOR_DWA122600_HPP_
|
# define ITERATOR_DWA122600_HPP_
|
||||||
|
|
||||||
# include <boost/config.hpp>
|
# include <boost/config.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 <boost/mpl/if.hpp>
|
|
||||||
# include <boost/mpl/aux_/has_xxx.hpp>
|
|
||||||
# include <iterator>
|
# include <iterator>
|
||||||
# include <cstddef>
|
|
||||||
|
|
||||||
// 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
|
// 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
|
||||||
@ -81,18 +71,12 @@
|
|||||||
|
|
||||||
# endif // STLPort <= 4.1b4 && no partial specialization
|
# 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) \
|
# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \
|
||||||
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||||
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
|
|
||||||
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
// Define a new template so it can be specialized
|
// Define a new template so it can be specialized
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
struct iterator_traits
|
struct iterator_traits
|
||||||
@ -100,12 +84,17 @@ struct iterator_traits
|
|||||||
{};
|
{};
|
||||||
using std::distance;
|
using std::distance;
|
||||||
|
|
||||||
|
}} // namespace boost::detail
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||||
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
|
|
||||||
// This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS
|
// 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
|
// Rogue Wave Standard Library fools itself into thinking partial
|
||||||
// specialization is missing on some platforms (e.g. Sun), so fails to
|
// specialization is missing on some platforms (e.g. Sun), so fails to
|
||||||
// supply iterator_traits!
|
// supply iterator_traits!
|
||||||
@ -139,8 +128,48 @@ struct iterator_traits<T const*>
|
|||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}} // namespace boost::detail
|
||||||
|
|
||||||
# else
|
# 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/detail/workaround.hpp>
|
||||||
|
# if BOOST_MSVC == 1300
|
||||||
|
# include <boost/type_traits/add_reference.hpp>
|
||||||
|
# include <boost/mpl/apply_if.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
# include <boost/mpl/or.hpp>
|
||||||
|
# include <boost/mpl/and.hpp>
|
||||||
|
# endif
|
||||||
|
# include <boost/mpl/aux_/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 --
|
// is_mutable_iterator --
|
||||||
//
|
//
|
||||||
// A metafunction returning true iff T is a mutable iterator type
|
// A metafunction returning true iff T is a mutable iterator type
|
||||||
@ -244,9 +273,65 @@ struct pointer_iterator_traits<T*>
|
|||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
};
|
};
|
||||||
# else
|
# else
|
||||||
template <class Ptr>
|
|
||||||
struct must_manually_specialize_boost_detail_iterator_traits;
|
// 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
|
||||||
|
# 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<P, typename remove_pointer<P>::type>
|
||||||
|
, please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>
|
||||||
|
, remove_const<
|
||||||
|
typename remove_pointer<P>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
# else
|
||||||
|
: 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
|
||||||
|
>
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class P>
|
||||||
|
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<P, typename remove_pointer<P>::type>
|
||||||
|
, please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>
|
||||||
|
, add_reference<typename remove_pointer<P>::type>
|
||||||
|
>
|
||||||
|
# else
|
||||||
|
: 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&
|
||||||
|
>
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct pointer_iterator_traits
|
struct pointer_iterator_traits
|
||||||
@ -255,24 +340,10 @@ struct pointer_iterator_traits
|
|||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
// Makes MSVC6 happy under some circumstances
|
typedef typename pointer_value_type<T>::type value_type;
|
||||||
typedef must_manually_specialize_boost_detail_iterator_traits<T> value_type;
|
typedef typename pointer_reference<T>::type reference;
|
||||||
typedef must_manually_specialize_boost_detail_iterator_traits<T> 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 <class T, class CV = T>
|
|
||||||
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
|
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
// 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
|
||||||
@ -394,7 +465,11 @@ struct iterator_traits
|
|||||||
// This specialization cuts off ETI (Early Template Instantiation) for MSVC.
|
// This specialization cuts off ETI (Early Template Instantiation) for MSVC.
|
||||||
template <> struct iterator_traits<int>{};
|
template <> struct iterator_traits<int>{};
|
||||||
|
|
||||||
# endif
|
}} // namespace boost::detail
|
||||||
|
|
||||||
|
# endif // workarounds
|
||||||
|
|
||||||
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
namespace iterator_traits_
|
namespace iterator_traits_
|
||||||
{
|
{
|
||||||
@ -429,9 +504,11 @@ distance(Iterator first, Iterator last)
|
|||||||
return iterator_traits_::distance_select<Iterator,diff_t>::execute(
|
return iterator_traits_::distance_select<Iterator,diff_t>::execute(
|
||||||
first, last, (iterator_category*)0);
|
first, last, (iterator_category*)0);
|
||||||
}
|
}
|
||||||
# endif // workarounds
|
|
||||||
|
|
||||||
}} // namespace boost::detail
|
}}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
# undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
# undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||||
# undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
# undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
||||||
|
Reference in New Issue
Block a user