Line data Source code
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 193216 : 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: 54 : BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT 55 : : o_(o) { } 56 : 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 { 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))) 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; 87 : 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; 95 : 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; 103 : 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; 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 : { 128 : #if BOOST_WORKAROUND(__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 148 : addressof(T (&o)[N]) BOOST_NOEXCEPT 149 : { 150 : return &o; 151 : } 152 : #endif 153 : 154 : #if BOOST_WORKAROUND(__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] 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> 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 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 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 : { 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