]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | /* |
2 | Copyright (C) 2002 Brad King (brad.king@kitware.com) | |
3 | Douglas Gregor (gregod@cs.rpi.edu) | |
4 | ||
5 | Copyright (C) 2002, 2008, 2013 Peter Dimov | |
6 | ||
7 | Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com) | |
8 | ||
9 | Distributed under the Boost Software License, Version 1.0. | |
10 | (See accompanying file LICENSE_1_0.txt or copy at | |
11 | http://www.boost.org/LICENSE_1_0.txt) | |
12 | */ | |
13 | ||
14 | #ifndef BOOST_CORE_ADDRESSOF_HPP | |
15 | #define BOOST_CORE_ADDRESSOF_HPP | |
16 | ||
17 | #include <boost/config.hpp> | |
18 | ||
19 | #if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 | |
20 | #define BOOST_CORE_HAS_BUILTIN_ADDRESSOF | |
21 | #elif defined(BOOST_GCC) && BOOST_GCC >= 70000 | |
22 | #define BOOST_CORE_HAS_BUILTIN_ADDRESSOF | |
23 | #elif defined(__has_builtin) | |
24 | #if __has_builtin(__builtin_addressof) | |
25 | #define BOOST_CORE_HAS_BUILTIN_ADDRESSOF | |
26 | #endif | |
27 | #endif | |
28 | ||
29 | #if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF) | |
30 | #if defined(BOOST_NO_CXX11_CONSTEXPR) | |
31 | #define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF | |
32 | #endif | |
33 | ||
34 | namespace boost { | |
35 | ||
36 | template<class T> | |
37 | BOOST_CONSTEXPR inline T* | |
38 | addressof(T& o) BOOST_NOEXCEPT | |
39 | { | |
40 | return __builtin_addressof(o); | |
41 | } | |
42 | ||
43 | } /* boost */ | |
44 | #else | |
45 | #include <boost/config/workaround.hpp> | |
46 | #include <cstddef> | |
47 | ||
48 | namespace boost { | |
49 | namespace detail { | |
50 | ||
51 | template<class T> | |
11fdf7f2 | 52 | class addrof_ref { |
b32b8144 | 53 | public: |
11fdf7f2 | 54 | BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT |
b32b8144 FG |
55 | : o_(o) { } |
56 | BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT { | |
57 | return o_; | |
58 | } | |
59 | private: | |
11fdf7f2 | 60 | addrof_ref& operator=(const addrof_ref&); |
b32b8144 FG |
61 | T& o_; |
62 | }; | |
63 | ||
64 | template<class T> | |
11fdf7f2 | 65 | struct addrof { |
b32b8144 FG |
66 | static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT { |
67 | return reinterpret_cast<T*>(& | |
68 | const_cast<char&>(reinterpret_cast<const volatile char&>(o))); | |
69 | } | |
70 | static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT { | |
71 | return p; | |
72 | } | |
73 | }; | |
74 | ||
75 | #if !defined(BOOST_NO_CXX11_NULLPTR) | |
76 | #if !defined(BOOST_NO_CXX11_DECLTYPE) && \ | |
77 | (defined(__INTEL_COMPILER) || \ | |
78 | (defined(__clang__) && !defined(_LIBCPP_VERSION))) | |
11fdf7f2 | 79 | typedef decltype(nullptr) addrof_null_t; |
b32b8144 | 80 | #else |
11fdf7f2 | 81 | typedef std::nullptr_t addrof_null_t; |
b32b8144 FG |
82 | #endif |
83 | ||
84 | template<> | |
11fdf7f2 TL |
85 | struct addrof<addrof_null_t> { |
86 | typedef addrof_null_t type; | |
b32b8144 FG |
87 | static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { |
88 | return &o; | |
89 | } | |
90 | }; | |
91 | ||
92 | template<> | |
11fdf7f2 TL |
93 | struct addrof<const addrof_null_t> { |
94 | typedef const addrof_null_t type; | |
b32b8144 FG |
95 | static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { |
96 | return &o; | |
97 | } | |
98 | }; | |
99 | ||
100 | template<> | |
11fdf7f2 TL |
101 | struct addrof<volatile addrof_null_t> { |
102 | typedef volatile addrof_null_t type; | |
b32b8144 FG |
103 | static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { |
104 | return &o; | |
105 | } | |
106 | }; | |
107 | ||
108 | template<> | |
11fdf7f2 TL |
109 | struct addrof<const volatile addrof_null_t> { |
110 | typedef const volatile addrof_null_t type; | |
b32b8144 FG |
111 | static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { |
112 | return &o; | |
113 | } | |
114 | }; | |
115 | #endif | |
116 | ||
117 | } /* detail */ | |
118 | ||
119 | #if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \ | |
120 | defined(BOOST_NO_CXX11_CONSTEXPR) || \ | |
121 | defined(BOOST_NO_CXX11_DECLTYPE) | |
122 | #define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF | |
123 | ||
124 | template<class T> | |
125 | BOOST_FORCEINLINE T* | |
126 | addressof(T& o) BOOST_NOEXCEPT | |
127 | { | |
20effc67 | 128 | #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \ |
b32b8144 | 129 | BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120) |
11fdf7f2 | 130 | return boost::detail::addrof<T>::get(o, 0); |
b32b8144 | 131 | #else |
11fdf7f2 | 132 | return boost::detail::addrof<T>::get(boost::detail::addrof_ref<T>(o), 0); |
b32b8144 FG |
133 | #endif |
134 | } | |
135 | ||
136 | #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) | |
137 | namespace detail { | |
138 | ||
139 | template<class T> | |
11fdf7f2 | 140 | struct addrof_result { |
b32b8144 FG |
141 | typedef T* type; |
142 | }; | |
143 | ||
144 | } /* detail */ | |
145 | ||
146 | template<class T, std::size_t N> | |
11fdf7f2 | 147 | BOOST_FORCEINLINE typename boost::detail::addrof_result<T[N]>::type |
b32b8144 FG |
148 | addressof(T (&o)[N]) BOOST_NOEXCEPT |
149 | { | |
150 | return &o; | |
151 | } | |
152 | #endif | |
153 | ||
20effc67 | 154 | #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
b32b8144 FG |
155 | template<class T, std::size_t N> |
156 | BOOST_FORCEINLINE | |
157 | T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N] | |
158 | { | |
159 | return reinterpret_cast<T(*)[N]>(&o); | |
160 | } | |
161 | ||
162 | template<class T, std::size_t N> | |
163 | BOOST_FORCEINLINE | |
164 | const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N] | |
165 | { | |
166 | return reinterpret_cast<const T(*)[N]>(&o); | |
167 | } | |
168 | #endif | |
169 | #else | |
170 | namespace detail { | |
171 | ||
172 | template<class T> | |
11fdf7f2 | 173 | T addrof_declval() BOOST_NOEXCEPT; |
b32b8144 FG |
174 | |
175 | template<class> | |
11fdf7f2 | 176 | struct addrof_void { |
b32b8144 FG |
177 | typedef void type; |
178 | }; | |
179 | ||
180 | template<class T, class E = void> | |
11fdf7f2 | 181 | struct addrof_member_operator { |
b32b8144 FG |
182 | static constexpr bool value = false; |
183 | }; | |
184 | ||
185 | template<class T> | |
11fdf7f2 TL |
186 | struct addrof_member_operator<T, typename |
187 | addrof_void<decltype(addrof_declval<T&>().operator&())>::type> { | |
b32b8144 FG |
188 | static constexpr bool value = true; |
189 | }; | |
190 | ||
191 | #if BOOST_WORKAROUND(BOOST_INTEL, < 1600) | |
11fdf7f2 | 192 | struct addrof_addressable { }; |
b32b8144 | 193 | |
11fdf7f2 TL |
194 | addrof_addressable* |
195 | operator&(addrof_addressable&) BOOST_NOEXCEPT; | |
b32b8144 FG |
196 | #endif |
197 | ||
198 | template<class T, class E = void> | |
11fdf7f2 | 199 | struct addrof_non_member_operator { |
b32b8144 FG |
200 | static constexpr bool value = false; |
201 | }; | |
202 | ||
203 | template<class T> | |
11fdf7f2 TL |
204 | struct addrof_non_member_operator<T, typename |
205 | addrof_void<decltype(operator&(addrof_declval<T&>()))>::type> { | |
b32b8144 FG |
206 | static constexpr bool value = true; |
207 | }; | |
208 | ||
209 | template<class T, class E = void> | |
11fdf7f2 | 210 | struct addrof_expression { |
b32b8144 FG |
211 | static constexpr bool value = false; |
212 | }; | |
213 | ||
214 | template<class T> | |
11fdf7f2 TL |
215 | struct addrof_expression<T, |
216 | typename addrof_void<decltype(&addrof_declval<T&>())>::type> { | |
b32b8144 FG |
217 | static constexpr bool value = true; |
218 | }; | |
219 | ||
220 | template<class T> | |
11fdf7f2 TL |
221 | struct addrof_is_constexpr { |
222 | static constexpr bool value = addrof_expression<T>::value && | |
223 | !addrof_member_operator<T>::value && | |
224 | !addrof_non_member_operator<T>::value; | |
b32b8144 FG |
225 | }; |
226 | ||
227 | template<bool E, class T> | |
11fdf7f2 | 228 | struct addrof_if { }; |
b32b8144 FG |
229 | |
230 | template<class T> | |
11fdf7f2 | 231 | struct addrof_if<true, T> { |
b32b8144 FG |
232 | typedef T* type; |
233 | }; | |
234 | ||
235 | template<class T> | |
236 | BOOST_FORCEINLINE | |
11fdf7f2 | 237 | typename addrof_if<!addrof_is_constexpr<T>::value, T>::type |
b32b8144 FG |
238 | addressof(T& o) BOOST_NOEXCEPT |
239 | { | |
11fdf7f2 | 240 | return addrof<T>::get(addrof_ref<T>(o), 0); |
b32b8144 FG |
241 | } |
242 | ||
243 | template<class T> | |
244 | constexpr BOOST_FORCEINLINE | |
11fdf7f2 | 245 | typename addrof_if<addrof_is_constexpr<T>::value, T>::type |
b32b8144 FG |
246 | addressof(T& o) BOOST_NOEXCEPT |
247 | { | |
248 | return &o; | |
249 | } | |
250 | ||
251 | } /* detail */ | |
252 | ||
253 | template<class T> | |
254 | constexpr BOOST_FORCEINLINE T* | |
255 | addressof(T& o) BOOST_NOEXCEPT | |
256 | { | |
11fdf7f2 | 257 | return boost::detail::addressof(o); |
b32b8144 FG |
258 | } |
259 | #endif | |
260 | ||
261 | } /* boost */ | |
262 | #endif | |
263 | ||
264 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ | |
265 | !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | |
266 | namespace boost { | |
267 | ||
268 | template<class T> | |
269 | const T* addressof(const T&&) = delete; | |
270 | ||
271 | } /* boost */ | |
272 | #endif | |
273 | ||
274 | #endif |