-// (C) Copyright David Abrahams 2002. 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
//
# define ITERATOR_DWA122600_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 <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
// partial specialization: instead of an iterator_category typedef, the standard
# 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) \
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_MSVC_STD_ITERATOR)
+
+namespace boost { namespace detail {
+
// Define a new template so it can be specialized
template <class Iterator>
struct iterator_traits
: std::iterator_traits<Iterator>
{};
using std::distance;
-# elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
- && !defined(BOOST_MSVC_STD_ITERATOR)
+
+}} // namespace boost::detail
+
+# else
+
+# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+ && !defined(BOOST_MSVC_STD_ITERATOR)
+
+// 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
// specialization is missing on some platforms (e.g. Sun), so fails to
typedef std::random_access_iterator_tag iterator_category;
};
-# else
+}} // 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 --
//
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>
{
static T t;
- BOOST_STATIC_CONSTANT(bool, value = sizeof(
- detail::is_mutable_iterator_helper((T*)0, &*t))
- == sizeof(type_traits::yes_type)
- );
+ 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_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl<T>::value)
-# 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 --
typedef typename T::difference_type difference_type;
typedef typename T::_Iterator_category iterator_category;
};
-# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
template <class T> struct pointer_iterator_traits;
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct pointer_iterator_traits<T*>
{
- typedef remove_const<T>::type value_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 Ptr>
-struct must_manually_specialize_boost_detail_iterator_traits;
+# else
+
+// 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
+ >
+{
+};
+
+
+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 T>
struct pointer_iterator_traits
typedef std::random_access_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- // Makes MSVC6 happy under some circumstances
- typedef must_manually_specialize_boost_detail_iterator_traits<T> value_type;
- typedef must_manually_specialize_boost_detail_iterator_traits<T> reference;
+ typedef typename pointer_value_type<T>::type value_type;
+ typedef typename pointer_reference<T>::type 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
// can determine the difference_type, pointer, reference, and value_type
: std::iterator_traits<Iterator>
{
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
- typedef value_type* pointer;
- typedef value_type& reference;
+ typedef typename std::iterator_traits<Iterator>::value_type* pointer;
+ typedef typename std::iterator_traits<Iterator>::value_type& reference;
};
template <class Iterator>
: std::iterator_traits<Iterator>
{
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
- typedef const value_type* pointer;
- typedef const value_type& reference;
+ typedef const typename std::iterator_traits<Iterator>::value_type* pointer;
+ typedef const typename std::iterator_traits<Iterator>::value_type& reference;
};
-# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
+# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
template <class Iterator>
struct is_bad_output_iterator
: is_base_and_derived<
typedef void pointer;
typedef void reference;
};
-# endif
+# endif
// If we're looking at an MSVC6 (old Dinkumware) ``standard''
// iterator, this will generate an appropriate traits class.
is_full_iterator_traits<Iterator>
// Use a standard iterator_traits implementation
, standard_iterator_traits<Iterator>
-# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+# 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
+# endif
// Otherwise, assume it's a Dinkum iterator
, msvc_stdlib_iterator_traits<Iterator>
-# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
+# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
>::type
-# endif
+# endif
>::type
{
};
// Explicit forwarding from base class needed to keep MSVC6 happy
// under some circumstances.
private:
-# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
+# 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
+# else
typedef iterator_traits_aux<Iterator> base;
-# endif
+# endif
public:
typedef typename base::value_type value_type;
typedef typename base::pointer pointer;
};
// This specialization cuts off ETI (Early Template Instantiation) for MSVC.
-template <> struct iterator_traits<int>{};
+template <> struct iterator_traits<int>
+{
+ typedef int value_type;
+ typedef int pointer;
+ typedef int reference;
+ typedef int difference_type;
+ typedef int iterator_category;
+};
+
+}} // namespace boost::detail
+
+# endif // workarounds
+
+namespace boost { namespace detail {
namespace iterator_traits_
{
{
static Difference execute(Iterator i1, const Iterator i2, ...)
{
- typename Difference result = 0;
+ Difference result = 0;
while (i1 != i2)
{
++i1;
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