1/*
2Copyright 2017-2018 Glen Joseph Fernandes
3(glenjofe@gmail.com)
4
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7*/
8#ifndef BOOST_CORE_POINTER_TRAITS_HPP
9#define BOOST_CORE_POINTER_TRAITS_HPP
10
11#include <boost/config.hpp>
12#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
13#include <memory>
14#else
15#include <boost/core/addressof.hpp>
16#include <cstddef>
17#endif
18
19namespace boost {
20
21#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
22template<class T>
23struct pointer_traits
24 : std::pointer_traits<T> {
25 template<class U>
26 struct rebind_to {
27 typedef typename std::pointer_traits<T>::template rebind<U> type;
28 };
29};
30
31template<class T>
32struct pointer_traits<T*>
33 : std::pointer_traits<T*> {
34 template<class U>
35 struct rebind_to {
36 typedef U* type;
37 };
38};
39#else
40namespace detail {
41
42template<class>
43struct ptr_void {
44 typedef void type;
45};
46
47template<class T>
48struct ptr_first;
49
50#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
51template<template<class, class...> class T, class U, class... Args>
52struct ptr_first<T<U, Args...> > {
53 typedef U type;
54};
55#else
56template<template<class> class T, class U>
57struct ptr_first<T<U> > {
58 typedef U type;
59};
60
61template<template<class, class> class T, class U1, class U2>
62struct ptr_first<T<U1, U2> > {
63 typedef U1 type;
64};
65
66template<template<class, class, class> class T, class U1, class U2, class U3>
67struct ptr_first<T<U1, U2, U3> > {
68 typedef U1 type;
69};
70#endif
71
72template<class T, class = void>
73struct ptr_element {
74 typedef typename ptr_first<T>::type type;
75};
76
77template<class T>
78struct ptr_element<T, typename ptr_void<typename T::element_type>::type> {
79 typedef typename T::element_type type;
80};
81
82template<class, class = void>
83struct ptr_difference {
84 typedef std::ptrdiff_t type;
85};
86
87template<class T>
88struct ptr_difference<T,
89 typename ptr_void<typename T::difference_type>::type> {
90 typedef typename T::difference_type type;
91};
92
93template<class T, class V>
94struct ptr_transform;
95
96#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
97template<template<class, class...> class T, class U, class... Args, class V>
98struct ptr_transform<T<U, Args...>, V> {
99 typedef T<V, Args...> type;
100};
101#else
102template<template<class> class T, class U, class V>
103struct ptr_transform<T<U>, V> {
104 typedef T<V> type;
105};
106
107template<template<class, class> class T, class U1, class U2, class V>
108struct ptr_transform<T<U1, U2>, V> {
109 typedef T<V, U2> type;
110};
111
112template<template<class, class, class> class T,
113 class U1, class U2, class U3, class V>
114struct ptr_transform<T<U1, U2, U3>, V> {
115 typedef T<V, U2, U3> type;
116};
117#endif
118
119template<class T, class U, class = void>
120struct ptr_rebind {
121 typedef typename ptr_transform<T, U>::type type;
122};
123
124#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
125template<class T, class U>
126struct ptr_rebind<T, U,
127 typename ptr_void<typename T::template rebind<U> >::type> {
128 typedef typename T::template rebind<U> type;
129};
130#endif
131
132template<class T>
133struct ptr_value {
134 typedef T type;
135};
136
137template<>
138struct ptr_value<void> {
139 typedef struct { } type;
140};
141
142} /* detail */
143
144template<class T>
145struct pointer_traits {
146 typedef T pointer;
147 typedef typename detail::ptr_element<T>::type element_type;
148 typedef typename detail::ptr_difference<T>::type difference_type;
149 template<class U>
150 struct rebind_to {
151 typedef typename detail::ptr_rebind<T, U>::type type;
152 };
153#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
154 template<class U>
155 using rebind = typename detail::ptr_rebind<T, U>::type;
156#endif
157 static pointer
158 pointer_to(typename detail::ptr_value<element_type>::type& v) {
159 return pointer::pointer_to(v);
160 }
161};
162
163template<class T>
164struct pointer_traits<T*> {
165 typedef T* pointer;
166 typedef T element_type;
167 typedef std::ptrdiff_t difference_type;
168 template<class U>
169 struct rebind_to {
170 typedef U* type;
171 };
172#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
173 template<class U>
174 using rebind = U*;
175#endif
176 static T*
177 pointer_to(typename detail::ptr_value<T>::type& v) BOOST_NOEXCEPT {
178 return boost::addressof(v);
179 }
180};
181#endif
182
183template<class T>
184BOOST_CONSTEXPR inline T*
185to_address(T* v) BOOST_NOEXCEPT
186{
187 return v;
188}
189
190#if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)
191namespace detail {
192
193template<class T>
194inline T*
195ptr_address(T* v, int) BOOST_NOEXCEPT
196{
197 return v;
198}
199
200template<class T>
201inline auto
202ptr_address(const T& v, int) BOOST_NOEXCEPT
203-> decltype(boost::pointer_traits<T>::to_address(v))
204{
205 return boost::pointer_traits<T>::to_address(v);
206}
207
208template<class T>
209inline auto
210ptr_address(const T& v, long) BOOST_NOEXCEPT
211{
212 return boost::detail::ptr_address(v.operator->(), 0);
213}
214
215} /* detail */
216
217template<class T>
218inline auto
219to_address(const T& v) BOOST_NOEXCEPT
220{
221 return boost::detail::ptr_address(v, 0);
222}
223#else
224template<class T>
225inline typename pointer_traits<T>::element_type*
226to_address(const T& v) BOOST_NOEXCEPT
227{
228 return boost::to_address(v.operator->());
229}
230#endif
231
232} /* boost */
233
234#endif
235

source code of include/boost/core/pointer_traits.hpp