File indexing completed on 2025-01-30 09:35:14
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_CORE_POINTER_TRAITS_HPP
0009 #define BOOST_CORE_POINTER_TRAITS_HPP
0010
0011 #include <boost/config.hpp>
0012 #include <boost/core/addressof.hpp>
0013 #include <cstddef>
0014
0015 namespace boost {
0016 namespace detail {
0017
0018 struct ptr_none { };
0019
0020 template<class>
0021 struct ptr_valid {
0022 typedef void type;
0023 };
0024
0025 template<class>
0026 struct ptr_first {
0027 typedef ptr_none type;
0028 };
0029
0030 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0031 template<template<class, class...> class T, class U, class... Args>
0032 struct ptr_first<T<U, Args...> > {
0033 typedef U type;
0034 };
0035 #else
0036 template<template<class> class T, class U>
0037 struct ptr_first<T<U> > {
0038 typedef U type;
0039 };
0040
0041 template<template<class, class> class T, class U1, class U2>
0042 struct ptr_first<T<U1, U2> > {
0043 typedef U1 type;
0044 };
0045
0046 template<template<class, class, class> class T, class U1, class U2, class U3>
0047 struct ptr_first<T<U1, U2, U3> > {
0048 typedef U1 type;
0049 };
0050 #endif
0051
0052 template<class T, class = void>
0053 struct ptr_element {
0054 typedef typename ptr_first<T>::type type;
0055 };
0056
0057 template<class T>
0058 struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
0059 typedef typename T::element_type type;
0060 };
0061
0062 template<class, class = void>
0063 struct ptr_difference {
0064 typedef std::ptrdiff_t type;
0065 };
0066
0067 template<class T>
0068 struct ptr_difference<T,
0069 typename ptr_valid<typename T::difference_type>::type> {
0070 typedef typename T::difference_type type;
0071 };
0072
0073 template<class, class>
0074 struct ptr_transform { };
0075
0076 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0077 template<template<class, class...> class T, class U, class... Args, class V>
0078 struct ptr_transform<T<U, Args...>, V> {
0079 typedef T<V, Args...> type;
0080 };
0081 #else
0082 template<template<class> class T, class U, class V>
0083 struct ptr_transform<T<U>, V> {
0084 typedef T<V> type;
0085 };
0086
0087 template<template<class, class> class T, class U1, class U2, class V>
0088 struct ptr_transform<T<U1, U2>, V> {
0089 typedef T<V, U2> type;
0090 };
0091
0092 template<template<class, class, class> class T,
0093 class U1, class U2, class U3, class V>
0094 struct ptr_transform<T<U1, U2, U3>, V> {
0095 typedef T<V, U2, U3> type;
0096 };
0097 #endif
0098
0099 template<class T, class U, class = void>
0100 struct ptr_rebind
0101 : ptr_transform<T, U> { };
0102
0103 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
0104 template<class T, class U>
0105 struct ptr_rebind<T, U,
0106 typename ptr_valid<typename T::template rebind<U> >::type> {
0107 typedef typename T::template rebind<U> type;
0108 };
0109 #else
0110 template<class T, class U>
0111 struct ptr_rebind<T, U,
0112 typename ptr_valid<typename T::template rebind<U>::other>::type> {
0113 typedef typename T::template rebind<U>::other type;
0114 };
0115 #endif
0116
0117 #if !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
0118 template<class T, class E>
0119 class ptr_to_expr {
0120 template<class>
0121 struct result {
0122 char x, y;
0123 };
0124
0125 static E& source();
0126
0127 template<class O>
0128 static auto check(int) -> result<decltype(O::pointer_to(source()))>;
0129
0130 template<class>
0131 static char check(long);
0132
0133 public:
0134 BOOST_STATIC_CONSTEXPR bool value = sizeof(check<T>(0)) > 1;
0135 };
0136
0137 template<class T, class E>
0138 struct ptr_to_expr<T*, E> {
0139 BOOST_STATIC_CONSTEXPR bool value = true;
0140 };
0141
0142 template<class T, class E>
0143 struct ptr_has_to {
0144 BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr<T, E>::value;
0145 };
0146 #else
0147 template<class, class>
0148 struct ptr_has_to {
0149 BOOST_STATIC_CONSTEXPR bool value = true;
0150 };
0151 #endif
0152
0153 template<class T>
0154 struct ptr_has_to<T, void> {
0155 BOOST_STATIC_CONSTEXPR bool value = false;
0156 };
0157
0158 template<class T>
0159 struct ptr_has_to<T, const void> {
0160 BOOST_STATIC_CONSTEXPR bool value = false;
0161 };
0162
0163 template<class T>
0164 struct ptr_has_to<T, volatile void> {
0165 BOOST_STATIC_CONSTEXPR bool value = false;
0166 };
0167
0168 template<class T>
0169 struct ptr_has_to<T, const volatile void> {
0170 BOOST_STATIC_CONSTEXPR bool value = false;
0171 };
0172
0173 template<class T, class E, bool = ptr_has_to<T, E>::value>
0174 struct ptr_to { };
0175
0176 template<class T, class E>
0177 struct ptr_to<T, E, true> {
0178 static T pointer_to(E& v) {
0179 return T::pointer_to(v);
0180 }
0181 };
0182
0183 template<class T>
0184 struct ptr_to<T*, T, true> {
0185 static T* pointer_to(T& v) BOOST_NOEXCEPT {
0186 return boost::addressof(v);
0187 }
0188 };
0189
0190 template<class T, class E>
0191 struct ptr_traits
0192 : ptr_to<T, E> {
0193 typedef T pointer;
0194 typedef E element_type;
0195 typedef typename ptr_difference<T>::type difference_type;
0196
0197 template<class U>
0198 struct rebind_to
0199 : ptr_rebind<T, U> { };
0200
0201 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
0202 template<class U>
0203 using rebind = typename rebind_to<U>::type;
0204 #endif
0205 };
0206
0207 template<class T>
0208 struct ptr_traits<T, ptr_none> { };
0209
0210 }
0211
0212 template<class T>
0213 struct pointer_traits
0214 : detail::ptr_traits<T, typename detail::ptr_element<T>::type> { };
0215
0216 template<class T>
0217 struct pointer_traits<T*>
0218 : detail::ptr_to<T*, T> {
0219 typedef T* pointer;
0220 typedef T element_type;
0221 typedef std::ptrdiff_t difference_type;
0222
0223 template<class U>
0224 struct rebind_to {
0225 typedef U* type;
0226 };
0227
0228 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
0229 template<class U>
0230 using rebind = typename rebind_to<U>::type;
0231 #endif
0232 };
0233
0234 template<class T>
0235 BOOST_CONSTEXPR inline T*
0236 to_address(T* v) BOOST_NOEXCEPT
0237 {
0238 return v;
0239 }
0240
0241 #if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)
0242 namespace detail {
0243
0244 template<class T>
0245 inline T*
0246 ptr_address(T* v, int) BOOST_NOEXCEPT
0247 {
0248 return v;
0249 }
0250
0251 template<class T>
0252 inline auto
0253 ptr_address(const T& v, int) BOOST_NOEXCEPT
0254 -> decltype(boost::pointer_traits<T>::to_address(v))
0255 {
0256 return boost::pointer_traits<T>::to_address(v);
0257 }
0258
0259 template<class T>
0260 inline auto
0261 ptr_address(const T& v, long) BOOST_NOEXCEPT
0262 {
0263 return boost::detail::ptr_address(v.operator->(), 0);
0264 }
0265
0266 }
0267
0268 template<class T>
0269 inline auto
0270 to_address(const T& v) BOOST_NOEXCEPT
0271 {
0272 return boost::detail::ptr_address(v, 0);
0273 }
0274 #else
0275 template<class T>
0276 inline typename pointer_traits<T>::element_type*
0277 to_address(const T& v) BOOST_NOEXCEPT
0278 {
0279 return boost::to_address(v.operator->());
0280 }
0281 #endif
0282
0283 }
0284
0285 #endif