]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/intrusive/include/boost/intrusive/pointer_traits.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / intrusive / include / boost / intrusive / pointer_traits.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Pablo Halpern 2009. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 //////////////////////////////////////////////////////////////////////////////
8 //
9 // (C) Copyright Ion Gaztanaga 2011-2014. Distributed under the Boost
10 // Software License, Version 1.0. (See accompanying file
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // See http://www.boost.org/libs/intrusive for documentation.
14 //
15 //////////////////////////////////////////////////////////////////////////////
16
17 #ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
18 #define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
19
20 #include <boost/intrusive/detail/config_begin.hpp>
21 #include <boost/intrusive/detail/workaround.hpp>
22 #include <boost/intrusive/pointer_rebind.hpp>
23 #include <boost/intrusive/detail/pointer_element.hpp>
24 #include <boost/intrusive/detail/mpl.hpp>
25 #include <cstddef>
26
27 #if defined(BOOST_HAS_PRAGMA_ONCE)
28 # pragma once
29 #endif
30
31 namespace boost {
32 namespace intrusive {
33 namespace detail {
34
35 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1310)
36 BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to)
37 BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from)
38 BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from)
39 BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from)
40 #else
41 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to)
42 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from)
43 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from)
44 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from)
45 #endif
46
47 BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(element_type)
48 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
49 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
50 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr)
51
52 } //namespace detail {
53
54
55 //! pointer_traits is the implementation of C++11 std::pointer_traits class with some
56 //! extensions like castings.
57 //!
58 //! pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
59 //!
60 //! <b>Note</b>: When defining a custom family of pointers or references to be used with BI
61 //! library, make sure the public static conversion functions accessed through
62 //! the `pointer_traits` interface (`*_cast_from` and `pointer_to`) can
63 //! properly convert between const and nonconst referred member types
64 //! <b>without the use of implicit constructor calls</b>. It is suggested these
65 //! conversions be implemented as function templates, where the template
66 //! argument is the type of the object being converted from.
67 template <typename Ptr>
68 struct pointer_traits
69 {
70 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
71 //!The pointer type
72 //!queried by this pointer_traits instantiation
73 typedef Ptr pointer;
74
75 //!Ptr::element_type if such a type exists; otherwise, T if Ptr is a class
76 //!template instantiation of the form SomePointer<T, Args>, where Args is zero or
77 //!more type arguments ; otherwise , the specialization is ill-formed.
78 typedef unspecified_type element_type;
79
80 //!Ptr::difference_type if such a type exists; otherwise,
81 //!std::ptrdiff_t.
82 typedef unspecified_type difference_type;
83
84 //!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
85 //!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
86 //!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
87 //!
88 //!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
89 //!shall be used instead of rebind<U> to obtain a pointer to U.
90 template <class U> using rebind = unspecified;
91
92 //!Ptr::reference if such a type exists (non-standard extension); otherwise, element_type &
93 //!
94 typedef unspecified_type reference;
95 #else
96 typedef Ptr pointer;
97 //
98 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT
99 ( boost::intrusive::detail::, Ptr, element_type
100 , boost::intrusive::detail::first_param<Ptr>) element_type;
101 //
102 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
103 (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
104
105 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
106 (boost::intrusive::detail::, Ptr, reference, typename boost::intrusive::detail::unvoid_ref<element_type>::type) reference;
107 //
108 template <class U> struct rebind_pointer
109 {
110 typedef typename boost::intrusive::pointer_rebind<Ptr, U>::type type;
111 };
112
113 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
114 template <class U> using rebind = typename boost::intrusive::pointer_rebind<Ptr, U>::type;
115 #endif
116 #endif //#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
117
118 //! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
119 //! it is element_type &.
120 //!
121 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(reference).
122 //! Non-standard extension: If such function does not exist, returns pointer(addressof(r));
123 //!
124 //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
125 //! <code>pointer_to</code> is checked.
126 static pointer pointer_to(reference r)
127 {
128 //Non-standard extension, it does not require Ptr::pointer_to. If not present
129 //tries to converts &r to pointer.
130 const bool value = boost::intrusive::detail::
131 has_member_function_callable_with_pointer_to
132 <Ptr, Ptr (*)(reference)>::value;
133 boost::intrusive::detail::bool_<value> flag;
134 return pointer_traits::priv_pointer_to(flag, r);
135 }
136
137 //! <b>Remark</b>: Non-standard extension.
138 //!
139 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
140 //! Ptr::static_cast_from(UPpr/const UPpr &).
141 //! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr))
142 //!
143 //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
144 //! <code>static_cast_from</code> is checked.
145 template<class UPtr>
146 static pointer static_cast_from(const UPtr &uptr)
147 {
148 typedef const UPtr &RefArg;
149 const bool value = boost::intrusive::detail::
150 has_member_function_callable_with_static_cast_from
151 <pointer, pointer(*)(RefArg)>::value
152 || boost::intrusive::detail::
153 has_member_function_callable_with_static_cast_from
154 <pointer, pointer(*)(UPtr)>::value;
155 return pointer_traits::priv_static_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
156 }
157
158 //! <b>Remark</b>: Non-standard extension.
159 //!
160 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
161 //! Ptr::const_cast_from<UPtr>(UPpr/const UPpr &).
162 //! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
163 //!
164 //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
165 //! <code>const_cast_from</code> is checked.
166 template<class UPtr>
167 static pointer const_cast_from(const UPtr &uptr)
168 {
169 typedef const UPtr &RefArg;
170 const bool value = boost::intrusive::detail::
171 has_member_function_callable_with_const_cast_from
172 <pointer, pointer(*)(RefArg)>::value
173 || boost::intrusive::detail::
174 has_member_function_callable_with_const_cast_from
175 <pointer, pointer(*)(UPtr)>::value;
176 return pointer_traits::priv_const_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
177 }
178
179 //! <b>Remark</b>: Non-standard extension.
180 //!
181 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
182 //! Ptr::dynamic_cast_from<UPtr>(UPpr/const UPpr &).
183 //! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
184 //!
185 //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
186 //! <code>dynamic_cast_from</code> is checked.
187 template<class UPtr>
188 static pointer dynamic_cast_from(const UPtr &uptr)
189 {
190 typedef const UPtr &RefArg;
191 const bool value = boost::intrusive::detail::
192 has_member_function_callable_with_dynamic_cast_from
193 <pointer, pointer(*)(RefArg)>::value
194 || boost::intrusive::detail::
195 has_member_function_callable_with_dynamic_cast_from
196 <pointer, pointer(*)(UPtr)>::value;
197 return pointer_traits::priv_dynamic_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
198 }
199
200 ///@cond
201 private:
202 //priv_to_raw_pointer
203 template <class T>
204 static T* to_raw_pointer(T* p)
205 { return p; }
206
207 template <class Pointer>
208 static typename pointer_traits<Pointer>::element_type*
209 to_raw_pointer(const Pointer &p)
210 { return pointer_traits::to_raw_pointer(p.operator->()); }
211
212 //priv_pointer_to
213 static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r)
214 { return Ptr::pointer_to(r); }
215
216 static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r)
217 { return pointer(boost::intrusive::detail::addressof(r)); }
218
219 //priv_static_cast_from
220 template<class UPtr>
221 static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
222 { return Ptr::static_cast_from(uptr); }
223
224 template<class UPtr>
225 static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
226 { return uptr ? pointer_to(*static_cast<element_type*>(to_raw_pointer(uptr))) : pointer(); }
227
228 //priv_const_cast_from
229 template<class UPtr>
230 static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
231 { return Ptr::const_cast_from(uptr); }
232
233 template<class UPtr>
234 static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
235 { return uptr ? pointer_to(const_cast<element_type&>(*uptr)) : pointer(); }
236
237 //priv_dynamic_cast_from
238 template<class UPtr>
239 static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
240 { return Ptr::dynamic_cast_from(uptr); }
241
242 template<class UPtr>
243 static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
244 { return uptr ? pointer_to(dynamic_cast<element_type&>(*uptr)) : pointer(); }
245 ///@endcond
246 };
247
248 ///@cond
249
250 // Remove cv qualification from Ptr parameter to pointer_traits:
251 template <typename Ptr>
252 struct pointer_traits<const Ptr> : pointer_traits<Ptr> {};
253 template <typename Ptr>
254 struct pointer_traits<volatile Ptr> : pointer_traits<Ptr> { };
255 template <typename Ptr>
256 struct pointer_traits<const volatile Ptr> : pointer_traits<Ptr> { };
257 // Remove reference from Ptr parameter to pointer_traits:
258 template <typename Ptr>
259 struct pointer_traits<Ptr&> : pointer_traits<Ptr> { };
260
261 ///@endcond
262
263 //! Specialization of pointer_traits for raw pointers
264 //!
265 template <typename T>
266 struct pointer_traits<T*>
267 {
268 typedef T element_type;
269 typedef T* pointer;
270 typedef std::ptrdiff_t difference_type;
271
272 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
273 typedef T & reference;
274 //!typedef for <pre>U *</pre>
275 //!
276 //!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
277 //!shall be used instead of rebind<U> to obtain a pointer to U.
278 template <class U> using rebind = U*;
279 #else
280 typedef typename boost::intrusive::detail::unvoid_ref<element_type>::type reference;
281 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
282 template <class U> using rebind = U*;
283 #endif
284 #endif
285
286 template <class U> struct rebind_pointer
287 { typedef U* type; };
288
289 //! <b>Returns</b>: addressof(r)
290 //!
291 BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r)
292 { return boost::intrusive::detail::addressof(r); }
293
294 //! <b>Returns</b>: static_cast<pointer>(uptr)
295 //!
296 template<class U>
297 BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr)
298 { return static_cast<pointer>(uptr); }
299
300 //! <b>Returns</b>: const_cast<pointer>(uptr)
301 //!
302 template<class U>
303 BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr)
304 { return const_cast<pointer>(uptr); }
305
306 //! <b>Returns</b>: dynamic_cast<pointer>(uptr)
307 //!
308 template<class U>
309 BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr)
310 { return dynamic_cast<pointer>(uptr); }
311 };
312
313 } //namespace container {
314 } //namespace boost {
315
316 #include <boost/intrusive/detail/config_end.hpp>
317
318 #endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)