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/detail/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_RVALUE_REFERENCES) || \
121 defined(BOOST_NO_CXX11_CONSTEXPR) || \
122 defined(BOOST_NO_CXX11_DECLTYPE)
123 #define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
127 addressof(T& o) BOOST_NOEXCEPT
129 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) || \
130 BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
131 return detail::address_of<T>::get(o, 0);
133 return detail::address_of<T>::get(detail::addressof_ref<T>(o), 0);
137 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
141 struct addressof_result {
147 template<class T, std::size_t N>
148 BOOST_FORCEINLINE typename detail::addressof_result<T[N]>::type
149 addressof(T (&o)[N]) BOOST_NOEXCEPT
155 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
156 template<class T, std::size_t N>
158 T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
160 return reinterpret_cast<T(*)[N]>(&o);
163 template<class T, std::size_t N>
165 const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
167 return reinterpret_cast<const T(*)[N]>(&o);
174 T&& addressof_declval() BOOST_NOEXCEPT;
177 struct addressof_void {
181 template<class T, class E = void>
182 struct addressof_member_operator {
183 static constexpr bool value = false;
187 struct addressof_member_operator<T, typename
188 addressof_void<decltype(addressof_declval<T&>().operator&())>::type> {
189 static constexpr bool value = true;
192 #if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
193 struct addressof_addressable { };
195 addressof_addressable*
196 operator&(addressof_addressable&) BOOST_NOEXCEPT;
199 template<class T, class E = void>
200 struct addressof_non_member_operator {
201 static constexpr bool value = false;
205 struct addressof_non_member_operator<T, typename
206 addressof_void<decltype(operator&(addressof_declval<T&>()))>::type> {
207 static constexpr bool value = true;
210 template<class T, class E = void>
211 struct addressof_expression {
212 static constexpr bool value = false;
216 struct addressof_expression<T,
217 typename addressof_void<decltype(&addressof_declval<T&>())>::type> {
218 static constexpr bool value = true;
222 struct addressof_is_constexpr {
223 static constexpr bool value = addressof_expression<T>::value &&
224 !addressof_member_operator<T>::value &&
225 !addressof_non_member_operator<T>::value;
228 template<bool E, class T>
229 struct addressof_if { };
232 struct addressof_if<true, T> {
238 typename addressof_if<!addressof_is_constexpr<T>::value, T>::type
239 addressof(T& o) BOOST_NOEXCEPT
241 return address_of<T>::get(addressof_ref<T>(o), 0);
245 constexpr BOOST_FORCEINLINE
246 typename addressof_if<addressof_is_constexpr<T>::value, T>::type
247 addressof(T& o) BOOST_NOEXCEPT
255 constexpr BOOST_FORCEINLINE T*
256 addressof(T& o) BOOST_NOEXCEPT
258 return detail::addressof(o);