2 Copyright (C) 2002 Brad King (brad.king@kitware.com)
3 Douglas Gregor (gregod@cs.rpi.edu)
5 Copyright (C) 2002, 2008, 2013 Peter Dimov
7 Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
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)
14 #ifndef BOOST_CORE_ADDRESSOF_HPP
15 #define BOOST_CORE_ADDRESSOF_HPP
17 #include <boost/config.hpp>
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
29 #if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF)
30 #if defined(BOOST_NO_CXX11_CONSTEXPR)
31 #define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
37 BOOST_CONSTEXPR inline T*
38 addressof(T& o) BOOST_NOEXCEPT
40 return __builtin_addressof(o);
45 #include <boost/config/workaround.hpp>
54 BOOST_FORCEINLINE addressof_ref(T& o) BOOST_NOEXCEPT
56 BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
60 addressof_ref& operator=(const addressof_ref&);
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)));
70 static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT {
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) addressof_null_t;
81 typedef std::nullptr_t addressof_null_t;
85 struct address_of<addressof_null_t> {
86 typedef addressof_null_t type;
87 static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
93 struct address_of<const addressof_null_t> {
94 typedef const addressof_null_t type;
95 static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
101 struct address_of<volatile addressof_null_t> {
102 typedef volatile addressof_null_t type;
103 static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
109 struct address_of<const volatile addressof_null_t> {
110 typedef const volatile addressof_null_t type;
111 static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
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
126 addressof(T& o) BOOST_NOEXCEPT
128 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) || \
129 BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
130 return detail::address_of<T>::get(o, 0);
132 return detail::address_of<T>::get(detail::addressof_ref<T>(o), 0);
136 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
140 struct addressof_result {
146 template<class T, std::size_t N>
147 BOOST_FORCEINLINE typename detail::addressof_result<T[N]>::type
148 addressof(T (&o)[N]) BOOST_NOEXCEPT
154 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
155 template<class T, std::size_t N>
157 T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
159 return reinterpret_cast<T(*)[N]>(&o);
162 template<class T, std::size_t N>
164 const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
166 return reinterpret_cast<const T(*)[N]>(&o);
173 T addressof_declval() BOOST_NOEXCEPT;
176 struct addressof_void {
180 template<class T, class E = void>
181 struct addressof_member_operator {
182 static constexpr bool value = false;
186 struct addressof_member_operator<T, typename
187 addressof_void<decltype(addressof_declval<T&>().operator&())>::type> {
188 static constexpr bool value = true;
191 #if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
192 struct addressof_addressable { };
194 addressof_addressable*
195 operator&(addressof_addressable&) BOOST_NOEXCEPT;
198 template<class T, class E = void>
199 struct addressof_non_member_operator {
200 static constexpr bool value = false;
204 struct addressof_non_member_operator<T, typename
205 addressof_void<decltype(operator&(addressof_declval<T&>()))>::type> {
206 static constexpr bool value = true;
209 template<class T, class E = void>
210 struct addressof_expression {
211 static constexpr bool value = false;
215 struct addressof_expression<T,
216 typename addressof_void<decltype(&addressof_declval<T&>())>::type> {
217 static constexpr bool value = true;
221 struct addressof_is_constexpr {
222 static constexpr bool value = addressof_expression<T>::value &&
223 !addressof_member_operator<T>::value &&
224 !addressof_non_member_operator<T>::value;
227 template<bool E, class T>
228 struct addressof_if { };
231 struct addressof_if<true, T> {
237 typename addressof_if<!addressof_is_constexpr<T>::value, T>::type
238 addressof(T& o) BOOST_NOEXCEPT
240 return address_of<T>::get(addressof_ref<T>(o), 0);
244 constexpr BOOST_FORCEINLINE
245 typename addressof_if<addressof_is_constexpr<T>::value, T>::type
246 addressof(T& o) BOOST_NOEXCEPT
254 constexpr BOOST_FORCEINLINE T*
255 addressof(T& o) BOOST_NOEXCEPT
257 return detail::addressof(o);
264 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
265 !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
269 const T* addressof(const T&&) = delete;