2 Copyright 2017 Glen Joseph Fernandes
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_CORE_POINTER_TRAITS_HPP
9 #define BOOST_CORE_POINTER_TRAITS_HPP
11 #include <boost/config.hpp>
12 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
15 #include <boost/core/addressof.hpp>
21 struct pointer_traits;
26 inline typename boost::pointer_traits<U>::element_type*
27 ptr_traits_address(const U& v) BOOST_NOEXCEPT
29 return boost::pointer_traits<U>::to_address(v);
34 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
37 : std::pointer_traits<T> {
40 typedef typename std::pointer_traits<T>::template rebind<U> type;
42 static typename std::pointer_traits<T>::element_type*
43 to_address(const T& v) BOOST_NOEXCEPT {
44 return detail::ptr_traits_address(v.operator->());
49 struct pointer_traits<T*>
50 : std::pointer_traits<T*> {
55 static T* to_address(T* v) BOOST_NOEXCEPT {
62 struct ptr_traits_none { char first, second; };
65 struct ptr_traits_has_element {
68 static ptr_traits_none call(...);
70 static char call(typename U::element_type* = 0);
72 static const bool value = sizeof(call<T>(0)) == 1;
76 struct ptr_traits_first;
78 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
79 template<template<class, class...> class T, class U, class... Args>
80 struct ptr_traits_first<T<U, Args...> > {
84 template<template<class> class T, class U>
85 struct ptr_traits_first<T<U> > {
89 template<template<class, class> class T, class U1, class U2>
90 struct ptr_traits_first<T<U1, U2> > {
94 template<template<class, class, class> class T, class U1, class U2, class U3>
95 struct ptr_traits_first<T<U1, U2, U3> > {
100 template<class T, bool = ptr_traits_has_element<T>::value>
101 struct ptr_traits_element {
102 typedef typename T::element_type type;
106 struct ptr_traits_element<T, false> {
107 typedef typename ptr_traits_first<T>::type type;
111 struct ptr_traits_has_difference {
114 static ptr_traits_none call(...);
116 static char call(typename U::difference_type* = 0);
118 static const bool value = sizeof(call<T>(0)) == 1;
121 template<class T, bool = ptr_traits_has_difference<T>::value>
122 struct ptr_traits_difference {
123 typedef typename T::difference_type type;
127 struct ptr_traits_difference<T, false> {
128 typedef std::ptrdiff_t type;
131 template<class T, class V>
132 struct ptr_traits_has_rebind {
135 static ptr_traits_none call(...);
137 static char call(typename U::template rebind<V>* = 0);
139 static const bool value = sizeof(call<T>(0)) == 1;
142 template<class T, class V>
143 struct ptr_traits_rebind_to;
145 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
146 template<template<class, class...> class T, class U, class... Args, class V>
147 struct ptr_traits_rebind_to<T<U, Args...>, V> {
148 typedef T<V, Args...> type;
151 template<template<class> class T, class U, class V>
152 struct ptr_traits_rebind_to<T<U>, V> {
156 template<template<class, class> class T, class U1, class U2, class V>
157 struct ptr_traits_rebind_to<T<U1, U2>, V> {
158 typedef T<V, U2> type;
161 template<template<class, class, class> class T,
162 class U1, class U2, class U3, class V>
163 struct ptr_traits_rebind_to<T<U1, U2, U3>, V> {
164 typedef T<V, U2, U3> type;
168 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
169 template<class T, class U, bool = ptr_traits_has_rebind<T, U>::value>
170 struct ptr_traits_rebind {
171 typedef typename T::template rebind<U> type;
174 template<class T, class U>
175 struct ptr_traits_rebind<T, U, false> {
176 typedef typename ptr_traits_rebind_to<T, U>::type type;
179 template<class T, class U>
180 struct ptr_traits_rebind {
181 typedef typename ptr_traits_rebind_to<T, U>::type type;
186 struct ptr_traits_value {
191 struct ptr_traits_value<void> {
192 typedef struct { } type;
198 struct pointer_traits {
200 typedef typename detail::ptr_traits_element<T>::type element_type;
201 typedef typename detail::ptr_traits_difference<T>::type difference_type;
204 typedef typename detail::ptr_traits_rebind<T, U>::type type;
206 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
208 using rebind = typename detail::ptr_traits_rebind<T, U>::type;
211 pointer_to(typename detail::ptr_traits_value<element_type>::type& v) {
212 return pointer::pointer_to(v);
214 static element_type* to_address(const pointer& v) BOOST_NOEXCEPT {
215 return detail::ptr_traits_address(v.operator->());
220 struct pointer_traits<T*> {
222 typedef T element_type;
223 typedef std::ptrdiff_t difference_type;
228 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
233 pointer_to(typename detail::ptr_traits_value<T>::type& v) BOOST_NOEXCEPT {
236 static T* to_address(T* v) BOOST_NOEXCEPT {
243 inline typename pointer_traits<T>::element_type*
244 to_address(const T& v) BOOST_NOEXCEPT
246 return pointer_traits<T>::to_address(v);
251 to_address(T* v) BOOST_NOEXCEPT