Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Pablo Halpern 2009. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
8 //
|
Chris@16
|
9 // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
Chris@16
|
10 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
12 //
|
Chris@16
|
13 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@16
|
14 //
|
Chris@16
|
15 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
16
|
Chris@16
|
17 #ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
Chris@16
|
18 #define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
Chris@16
|
19
|
Chris@16
|
20 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
21 # pragma once
|
Chris@16
|
22 #endif
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/intrusive/detail/config_begin.hpp>
|
Chris@16
|
25 #include <boost/intrusive/detail/workaround.hpp>
|
Chris@16
|
26 #include <boost/intrusive/detail/memory_util.hpp>
|
Chris@16
|
27 #include <boost/type_traits/integral_constant.hpp>
|
Chris@16
|
28 #include <cstddef>
|
Chris@16
|
29
|
Chris@16
|
30 namespace boost {
|
Chris@16
|
31 namespace intrusive {
|
Chris@16
|
32
|
Chris@16
|
33 //! pointer_traits is the implementation of C++11 std::pointer_traits class with some
|
Chris@16
|
34 //! extensions like castings.
|
Chris@16
|
35 //!
|
Chris@16
|
36 //! pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
|
Chris@16
|
37 template <typename Ptr>
|
Chris@16
|
38 struct pointer_traits
|
Chris@16
|
39 {
|
Chris@16
|
40 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
Chris@16
|
41 //!The pointer type
|
Chris@16
|
42 //!queried by this pointer_traits instantiation
|
Chris@16
|
43 typedef Ptr pointer;
|
Chris@16
|
44
|
Chris@16
|
45 //!Ptr::element_type if such a type exists; otherwise, T if Ptr is a class
|
Chris@16
|
46 //!template instantiation of the form SomePointer<T, Args>, where Args is zero or
|
Chris@16
|
47 //!more type arguments ; otherwise , the specialization is ill-formed.
|
Chris@16
|
48 typedef unspecified_type element_type;
|
Chris@16
|
49
|
Chris@16
|
50 //!Ptr::difference_type if such a type exists; otherwise,
|
Chris@16
|
51 //!std::ptrdiff_t.
|
Chris@16
|
52 typedef unspecified_type difference_type;
|
Chris@16
|
53
|
Chris@16
|
54 //!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
|
Chris@16
|
55 //!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
|
Chris@16
|
56 //!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
|
Chris@16
|
57 //!
|
Chris@16
|
58 //!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
|
Chris@16
|
59 //!shall be used instead of rebind<U> to obtain a pointer to U.
|
Chris@16
|
60 template <class U> using rebind = unspecified;
|
Chris@16
|
61
|
Chris@16
|
62 //!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
|
Chris@16
|
63 //!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
|
Chris@16
|
64 //!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
|
Chris@16
|
65 //!
|
Chris@16
|
66 typedef element_type &reference;
|
Chris@16
|
67 #else
|
Chris@16
|
68 typedef Ptr pointer;
|
Chris@16
|
69 //
|
Chris@16
|
70 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT
|
Chris@16
|
71 ( boost::intrusive::detail::, Ptr, element_type
|
Chris@16
|
72 , boost::intrusive::detail::first_param<Ptr>) element_type;
|
Chris@16
|
73 //
|
Chris@16
|
74 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
Chris@16
|
75 (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
|
Chris@16
|
76 //
|
Chris@16
|
77 typedef typename boost::intrusive::detail::unvoid_ref<element_type>::type reference;
|
Chris@16
|
78 //
|
Chris@16
|
79 template <class U> struct rebind_pointer
|
Chris@16
|
80 {
|
Chris@16
|
81 typedef typename boost::intrusive::detail::type_rebinder<Ptr, U>::type type;
|
Chris@16
|
82 };
|
Chris@16
|
83
|
Chris@16
|
84 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
Chris@16
|
85 template <class U> using rebind = typename boost::intrusive::detail::type_rebinder<Ptr, U>::type;
|
Chris@16
|
86 #endif
|
Chris@16
|
87 #endif //#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
Chris@16
|
88
|
Chris@16
|
89 //! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
|
Chris@16
|
90 //! it is element_type &.
|
Chris@16
|
91 //!
|
Chris@16
|
92 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(r).
|
Chris@16
|
93 //! Non-standard extension: If such function does not exist, returns pointer(addressof(r));
|
Chris@16
|
94 static pointer pointer_to(reference r)
|
Chris@16
|
95 {
|
Chris@16
|
96 //Non-standard extension, it does not require Ptr::pointer_to. If not present
|
Chris@16
|
97 //tries to converts &r to pointer.
|
Chris@16
|
98 const bool value = boost::intrusive::detail::
|
Chris@16
|
99 has_member_function_callable_with_pointer_to
|
Chris@16
|
100 <Ptr, typename boost::intrusive::detail::unvoid<element_type &>::type>::value;
|
Chris@16
|
101 ::boost::integral_constant<bool, value> flag;
|
Chris@16
|
102 return pointer_traits::priv_pointer_to(flag, r);
|
Chris@16
|
103 }
|
Chris@16
|
104
|
Chris@16
|
105 //! <b>Remark</b>: Non-standard extension.
|
Chris@16
|
106 //!
|
Chris@16
|
107 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::static_cast_from(r).
|
Chris@16
|
108 //! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr))
|
Chris@16
|
109 template<class UPtr>
|
Chris@16
|
110 static pointer static_cast_from(const UPtr &uptr)
|
Chris@16
|
111 {
|
Chris@16
|
112 const bool value = boost::intrusive::detail::
|
Chris@16
|
113 has_member_function_callable_with_static_cast_from
|
Chris@16
|
114 <Ptr, const UPtr>::value;
|
Chris@16
|
115 ::boost::integral_constant<bool, value> flag;
|
Chris@16
|
116 return pointer_traits::priv_static_cast_from(flag, uptr);
|
Chris@16
|
117 }
|
Chris@16
|
118
|
Chris@16
|
119 //! <b>Remark</b>: Non-standard extension.
|
Chris@16
|
120 //!
|
Chris@16
|
121 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::const_cast_from(r).
|
Chris@16
|
122 //! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
|
Chris@16
|
123 template<class UPtr>
|
Chris@16
|
124 static pointer const_cast_from(const UPtr &uptr)
|
Chris@16
|
125 {
|
Chris@16
|
126 const bool value = boost::intrusive::detail::
|
Chris@16
|
127 has_member_function_callable_with_const_cast_from
|
Chris@16
|
128 <Ptr, const UPtr>::value;
|
Chris@16
|
129 ::boost::integral_constant<bool, value> flag;
|
Chris@16
|
130 return pointer_traits::priv_const_cast_from(flag, uptr);
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 //! <b>Remark</b>: Non-standard extension.
|
Chris@16
|
134 //!
|
Chris@16
|
135 //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::dynamic_cast_from(r).
|
Chris@16
|
136 //! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
|
Chris@16
|
137 template<class UPtr>
|
Chris@16
|
138 static pointer dynamic_cast_from(const UPtr &uptr)
|
Chris@16
|
139 {
|
Chris@16
|
140 const bool value = boost::intrusive::detail::
|
Chris@16
|
141 has_member_function_callable_with_dynamic_cast_from
|
Chris@16
|
142 <Ptr, const UPtr>::value;
|
Chris@16
|
143 ::boost::integral_constant<bool, value> flag;
|
Chris@16
|
144 return pointer_traits::priv_dynamic_cast_from(flag, uptr);
|
Chris@16
|
145 }
|
Chris@16
|
146
|
Chris@16
|
147 ///@cond
|
Chris@16
|
148 private:
|
Chris@16
|
149 //priv_to_raw_pointer
|
Chris@16
|
150 template <class T>
|
Chris@16
|
151 static T* to_raw_pointer(T* p)
|
Chris@16
|
152 { return p; }
|
Chris@16
|
153
|
Chris@16
|
154 template <class Pointer>
|
Chris@16
|
155 static typename pointer_traits<Pointer>::element_type*
|
Chris@16
|
156 to_raw_pointer(const Pointer &p)
|
Chris@16
|
157 { return pointer_traits::to_raw_pointer(p.operator->()); }
|
Chris@16
|
158
|
Chris@16
|
159 //priv_pointer_to
|
Chris@16
|
160 static pointer priv_pointer_to(boost::true_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
|
Chris@16
|
161 { return Ptr::pointer_to(r); }
|
Chris@16
|
162
|
Chris@16
|
163 static pointer priv_pointer_to(boost::false_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
|
Chris@16
|
164 { return pointer(boost::intrusive::detail::addressof(r)); }
|
Chris@16
|
165
|
Chris@16
|
166 //priv_static_cast_from
|
Chris@16
|
167 template<class UPtr>
|
Chris@16
|
168 static pointer priv_static_cast_from(boost::true_type, const UPtr &uptr)
|
Chris@16
|
169 { return Ptr::static_cast_from(uptr); }
|
Chris@16
|
170
|
Chris@16
|
171 template<class UPtr>
|
Chris@16
|
172 static pointer priv_static_cast_from(boost::false_type, const UPtr &uptr)
|
Chris@16
|
173 { return pointer_to(*static_cast<element_type*>(to_raw_pointer(uptr))); }
|
Chris@16
|
174
|
Chris@16
|
175 //priv_const_cast_from
|
Chris@16
|
176 template<class UPtr>
|
Chris@16
|
177 static pointer priv_const_cast_from(boost::true_type, const UPtr &uptr)
|
Chris@16
|
178 { return Ptr::const_cast_from(uptr); }
|
Chris@16
|
179
|
Chris@16
|
180 template<class UPtr>
|
Chris@16
|
181 static pointer priv_const_cast_from(boost::false_type, const UPtr &uptr)
|
Chris@16
|
182 { return pointer_to(const_cast<element_type&>(*uptr)); }
|
Chris@16
|
183
|
Chris@16
|
184 //priv_dynamic_cast_from
|
Chris@16
|
185 template<class UPtr>
|
Chris@16
|
186 static pointer priv_dynamic_cast_from(boost::true_type, const UPtr &uptr)
|
Chris@16
|
187 { return Ptr::dynamic_cast_from(uptr); }
|
Chris@16
|
188
|
Chris@16
|
189 template<class UPtr>
|
Chris@16
|
190 static pointer priv_dynamic_cast_from(boost::false_type, const UPtr &uptr)
|
Chris@16
|
191 { return pointer_to(*dynamic_cast<element_type*>(&*uptr)); }
|
Chris@16
|
192 ///@endcond
|
Chris@16
|
193 };
|
Chris@16
|
194
|
Chris@16
|
195 ///@cond
|
Chris@16
|
196
|
Chris@16
|
197 // Remove cv qualification from Ptr parameter to pointer_traits:
|
Chris@16
|
198 template <typename Ptr>
|
Chris@16
|
199 struct pointer_traits<const Ptr> : pointer_traits<Ptr> {};
|
Chris@16
|
200 template <typename Ptr>
|
Chris@16
|
201 struct pointer_traits<volatile Ptr> : pointer_traits<Ptr> { };
|
Chris@16
|
202 template <typename Ptr>
|
Chris@16
|
203 struct pointer_traits<const volatile Ptr> : pointer_traits<Ptr> { };
|
Chris@16
|
204 // Remove reference from Ptr parameter to pointer_traits:
|
Chris@16
|
205 template <typename Ptr>
|
Chris@16
|
206 struct pointer_traits<Ptr&> : pointer_traits<Ptr> { };
|
Chris@16
|
207
|
Chris@16
|
208 ///@endcond
|
Chris@16
|
209
|
Chris@16
|
210 //! Specialization of pointer_traits for raw pointers
|
Chris@16
|
211 //!
|
Chris@16
|
212 template <typename T>
|
Chris@16
|
213 struct pointer_traits<T*>
|
Chris@16
|
214 {
|
Chris@16
|
215 typedef T element_type;
|
Chris@16
|
216 typedef T* pointer;
|
Chris@16
|
217 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
218
|
Chris@16
|
219 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
Chris@16
|
220 typedef T & reference;
|
Chris@16
|
221 //!typedef for <pre>U *</pre>
|
Chris@16
|
222 //!
|
Chris@16
|
223 //!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
|
Chris@16
|
224 //!shall be used instead of rebind<U> to obtain a pointer to U.
|
Chris@16
|
225 template <class U> using rebind = U*;
|
Chris@16
|
226 #else
|
Chris@16
|
227 typedef typename boost::intrusive::detail::unvoid_ref<element_type>::type reference;
|
Chris@16
|
228 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
Chris@16
|
229 template <class U> using rebind = U*;
|
Chris@16
|
230 #endif
|
Chris@16
|
231 #endif
|
Chris@16
|
232
|
Chris@16
|
233 template <class U> struct rebind_pointer
|
Chris@16
|
234 { typedef U* type; };
|
Chris@16
|
235
|
Chris@16
|
236 //! <b>Returns</b>: addressof(r)
|
Chris@16
|
237 //!
|
Chris@16
|
238 static pointer pointer_to(reference r)
|
Chris@16
|
239 { return boost::intrusive::detail::addressof(r); }
|
Chris@16
|
240
|
Chris@16
|
241 //! <b>Returns</b>: static_cast<pointer>(uptr)
|
Chris@16
|
242 //!
|
Chris@16
|
243 template<class U>
|
Chris@16
|
244 static pointer static_cast_from(U *uptr)
|
Chris@16
|
245 { return static_cast<pointer>(uptr); }
|
Chris@16
|
246
|
Chris@16
|
247 //! <b>Returns</b>: const_cast<pointer>(uptr)
|
Chris@16
|
248 //!
|
Chris@16
|
249 template<class U>
|
Chris@16
|
250 static pointer const_cast_from(U *uptr)
|
Chris@16
|
251 { return const_cast<pointer>(uptr); }
|
Chris@16
|
252
|
Chris@16
|
253 //! <b>Returns</b>: dynamic_cast<pointer>(uptr)
|
Chris@16
|
254 //!
|
Chris@16
|
255 template<class U>
|
Chris@16
|
256 static pointer dynamic_cast_from(U *uptr)
|
Chris@16
|
257 { return dynamic_cast<pointer>(uptr); }
|
Chris@16
|
258 };
|
Chris@16
|
259
|
Chris@16
|
260 } //namespace container {
|
Chris@16
|
261 } //namespace boost {
|
Chris@16
|
262
|
Chris@16
|
263 #include <boost/intrusive/detail/config_end.hpp>
|
Chris@16
|
264
|
Chris@16
|
265 #endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)
|