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