]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/core/pointer_traits.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / core / pointer_traits.hpp
1 /*
2 Copyright 2017 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4
5 Distributed 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 #endif
17
18 namespace boost {
19
20 template<class T>
21 struct pointer_traits;
22
23 namespace detail {
24
25 template<class U>
26 inline typename boost::pointer_traits<U>::element_type*
27 ptr_traits_address(const U& v) BOOST_NOEXCEPT
28 {
29 return boost::pointer_traits<U>::to_address(v);
30 }
31
32 } /* detail */
33
34 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
35 template<class T>
36 struct pointer_traits
37 : std::pointer_traits<T> {
38 template<class U>
39 struct rebind_to {
40 typedef typename std::pointer_traits<T>::template rebind<U> type;
41 };
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->());
45 }
46 };
47
48 template<class T>
49 struct pointer_traits<T*>
50 : std::pointer_traits<T*> {
51 template<class U>
52 struct rebind_to {
53 typedef U* type;
54 };
55 static T* to_address(T* v) BOOST_NOEXCEPT {
56 return v;
57 }
58 };
59 #else
60 namespace detail {
61
62 struct ptr_traits_none { char first, second; };
63
64 template<class T>
65 struct ptr_traits_has_element {
66 private:
67 template<class U>
68 static ptr_traits_none call(...);
69 template<class U>
70 static char call(typename U::element_type* = 0);
71 public:
72 static const bool value = sizeof(call<T>(0)) == 1;
73 };
74
75 template<class T>
76 struct ptr_traits_first;
77
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...> > {
81 typedef U type;
82 };
83 #else
84 template<template<class> class T, class U>
85 struct ptr_traits_first<T<U> > {
86 typedef U type;
87 };
88
89 template<template<class, class> class T, class U1, class U2>
90 struct ptr_traits_first<T<U1, U2> > {
91 typedef U1 type;
92 };
93
94 template<template<class, class, class> class T, class U1, class U2, class U3>
95 struct ptr_traits_first<T<U1, U2, U3> > {
96 typedef U1 type;
97 };
98 #endif
99
100 template<class T, bool = ptr_traits_has_element<T>::value>
101 struct ptr_traits_element {
102 typedef typename T::element_type type;
103 };
104
105 template<class T>
106 struct ptr_traits_element<T, false> {
107 typedef typename ptr_traits_first<T>::type type;
108 };
109
110 template<class T>
111 struct ptr_traits_has_difference {
112 private:
113 template<class U>
114 static ptr_traits_none call(...);
115 template<class U>
116 static char call(typename U::difference_type* = 0);
117 public:
118 static const bool value = sizeof(call<T>(0)) == 1;
119 };
120
121 template<class T, bool = ptr_traits_has_difference<T>::value>
122 struct ptr_traits_difference {
123 typedef typename T::difference_type type;
124 };
125
126 template<class T>
127 struct ptr_traits_difference<T, false> {
128 typedef std::ptrdiff_t type;
129 };
130
131 template<class T, class V>
132 struct ptr_traits_has_rebind {
133 private:
134 template<class U>
135 static ptr_traits_none call(...);
136 template<class U>
137 static char call(typename U::template rebind<V>* = 0);
138 public:
139 static const bool value = sizeof(call<T>(0)) == 1;
140 };
141
142 template<class T, class V>
143 struct ptr_traits_rebind_to;
144
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;
149 };
150 #else
151 template<template<class> class T, class U, class V>
152 struct ptr_traits_rebind_to<T<U>, V> {
153 typedef T<V> type;
154 };
155
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;
159 };
160
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;
165 };
166 #endif
167
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;
172 };
173
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;
177 };
178 #else
179 template<class T, class U>
180 struct ptr_traits_rebind {
181 typedef typename ptr_traits_rebind_to<T, U>::type type;
182 };
183 #endif
184
185 template<class T>
186 struct ptr_traits_value {
187 typedef T type;
188 };
189
190 template<>
191 struct ptr_traits_value<void> {
192 typedef struct { } type;
193 };
194
195 } /* detail */
196
197 template<class T>
198 struct pointer_traits {
199 typedef T pointer;
200 typedef typename detail::ptr_traits_element<T>::type element_type;
201 typedef typename detail::ptr_traits_difference<T>::type difference_type;
202 template<class U>
203 struct rebind_to {
204 typedef typename detail::ptr_traits_rebind<T, U>::type type;
205 };
206 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
207 template<class U>
208 using rebind = typename detail::ptr_traits_rebind<T, U>::type;
209 #endif
210 static pointer
211 pointer_to(typename detail::ptr_traits_value<element_type>::type& v) {
212 return pointer::pointer_to(v);
213 }
214 static element_type* to_address(const pointer& v) BOOST_NOEXCEPT {
215 return detail::ptr_traits_address(v.operator->());
216 }
217 };
218
219 template<class T>
220 struct pointer_traits<T*> {
221 typedef T* pointer;
222 typedef T element_type;
223 typedef std::ptrdiff_t difference_type;
224 template<class U>
225 struct rebind_to {
226 typedef U* type;
227 };
228 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
229 template<class U>
230 using rebind = U*;
231 #endif
232 static T*
233 pointer_to(typename detail::ptr_traits_value<T>::type& v) BOOST_NOEXCEPT {
234 return addressof(v);
235 }
236 static T* to_address(T* v) BOOST_NOEXCEPT {
237 return v;
238 }
239 };
240 #endif
241
242 template<class T>
243 inline typename pointer_traits<T>::element_type*
244 to_address(const T& v) BOOST_NOEXCEPT
245 {
246 return pointer_traits<T>::to_address(v);
247 }
248
249 template<class T>
250 inline T*
251 to_address(T* v) BOOST_NOEXCEPT
252 {
253 return v;
254 }
255
256 } /* boost */
257
258 #endif