• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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*
addressof(T & o)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>
52 class addrof_ref {
53 public:
addrof_ref(T & o)54     BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT
55         : o_(o) { }
operator T&() const56     BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
57         return o_;
58     }
59 private:
60     addrof_ref& operator=(const addrof_ref&);
61     T& o_;
62 };
63 
64 template<class T>
65 struct addrof {
getboost::detail::addrof66     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     }
getboost::detail::addrof70     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)))
79 typedef decltype(nullptr) addrof_null_t;
80 #else
81 typedef std::nullptr_t addrof_null_t;
82 #endif
83 
84 template<>
85 struct addrof<addrof_null_t> {
86     typedef addrof_null_t type;
getboost::detail::addrof87     static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
88         return &o;
89     }
90 };
91 
92 template<>
93 struct addrof<const addrof_null_t> {
94     typedef const addrof_null_t type;
getboost::detail::addrof95     static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
96         return &o;
97     }
98 };
99 
100 template<>
101 struct addrof<volatile addrof_null_t> {
102     typedef volatile addrof_null_t type;
getboost::detail::addrof103     static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
104         return &o;
105     }
106 };
107 
108 template<>
109 struct addrof<const volatile addrof_null_t> {
110     typedef const volatile addrof_null_t type;
getboost::detail::addrof111     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*
addressof(T & o)126 addressof(T& o) BOOST_NOEXCEPT
127 {
128 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \
129     BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
130     return boost::detail::addrof<T>::get(o, 0);
131 #else
132     return boost::detail::addrof<T>::get(boost::detail::addrof_ref<T>(o), 0);
133 #endif
134 }
135 
136 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
137 namespace detail {
138 
139 template<class T>
140 struct addrof_result {
141     typedef T* type;
142 };
143 
144 } /* detail */
145 
146 template<class T, std::size_t N>
147 BOOST_FORCEINLINE typename boost::detail::addrof_result<T[N]>::type
addressof(T (& o)[N])148 addressof(T (&o)[N]) BOOST_NOEXCEPT
149 {
150     return &o;
151 }
152 #endif
153 
154 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
155 template<class T, std::size_t N>
156 BOOST_FORCEINLINE
157 T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
__anonbd5656b70102null158 {
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]
__anonbd5656b70202null165 {
166    return reinterpret_cast<const T(*)[N]>(&o);
167 }
168 #endif
169 #else
170 namespace detail {
171 
172 template<class T>
173 T addrof_declval() BOOST_NOEXCEPT;
174 
175 template<class>
176 struct addrof_void {
177     typedef void type;
178 };
179 
180 template<class T, class E = void>
181 struct addrof_member_operator {
182     static constexpr bool value = false;
183 };
184 
185 template<class T>
186 struct addrof_member_operator<T, typename
187     addrof_void<decltype(addrof_declval<T&>().operator&())>::type> {
188     static constexpr bool value = true;
189 };
190 
191 #if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
192 struct addrof_addressable { };
193 
194 addrof_addressable*
195 operator&(addrof_addressable&) BOOST_NOEXCEPT;
196 #endif
197 
198 template<class T, class E = void>
199 struct addrof_non_member_operator {
200     static constexpr bool value = false;
201 };
202 
203 template<class T>
204 struct addrof_non_member_operator<T, typename
205     addrof_void<decltype(operator&(addrof_declval<T&>()))>::type> {
206     static constexpr bool value = true;
207 };
208 
209 template<class T, class E = void>
210 struct addrof_expression {
211     static constexpr bool value = false;
212 };
213 
214 template<class T>
215 struct addrof_expression<T,
216     typename addrof_void<decltype(&addrof_declval<T&>())>::type> {
217     static constexpr bool value = true;
218 };
219 
220 template<class T>
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;
225 };
226 
227 template<bool E, class T>
228 struct addrof_if { };
229 
230 template<class T>
231 struct addrof_if<true, T> {
232     typedef T* type;
233 };
234 
235 template<class T>
236 BOOST_FORCEINLINE
237 typename addrof_if<!addrof_is_constexpr<T>::value, T>::type
addressof(T & o)238 addressof(T& o) BOOST_NOEXCEPT
239 {
240     return addrof<T>::get(addrof_ref<T>(o), 0);
241 }
242 
243 template<class T>
244 constexpr BOOST_FORCEINLINE
245 typename addrof_if<addrof_is_constexpr<T>::value, T>::type
addressof(T & o)246 addressof(T& o) BOOST_NOEXCEPT
247 {
248     return &o;
249 }
250 
251 } /* detail */
252 
253 template<class T>
254 constexpr BOOST_FORCEINLINE T*
addressof(T & o)255 addressof(T& o) BOOST_NOEXCEPT
256 {
257     return boost::detail::addressof(o);
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
275