| 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> | 
| 52 | class addressof_ref { | 
| 53 | public: | 
| 54 |     BOOST_FORCEINLINE addressof_ref(T& o) BOOST_NOEXCEPT | 
| 55 |         : o_(o) { } | 
| 56 |     BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT { | 
| 57 |         return o_; | 
| 58 |     } | 
| 59 | private: | 
| 60 |     addressof_ref& operator=(const addressof_ref&); | 
| 61 |     T& o_; | 
| 62 | }; | 
| 63 |  | 
| 64 | template<class T> | 
| 65 | struct address_of { | 
| 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) addressof_null_t; | 
| 80 | #else | 
| 81 | typedef std::nullptr_t addressof_null_t; | 
| 82 | #endif | 
| 83 |  | 
| 84 | template<> | 
| 85 | struct address_of<addressof_null_t> { | 
| 86 |     typedef addressof_null_t type; | 
| 87 |     static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { | 
| 88 |         return &o; | 
| 89 |     } | 
| 90 | }; | 
| 91 |  | 
| 92 | template<> | 
| 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 { | 
| 96 |         return &o; | 
| 97 |     } | 
| 98 | }; | 
| 99 |  | 
| 100 | template<> | 
| 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 { | 
| 104 |         return &o; | 
| 105 |     } | 
| 106 | }; | 
| 107 |  | 
| 108 | template<> | 
| 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 { | 
| 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 detail::address_of<T>::get(o, 0); | 
| 131 | #else | 
| 132 |     return detail::address_of<T>::get(detail::addressof_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 addressof_result { | 
| 141 |     typedef T* type; | 
| 142 | }; | 
| 143 |  | 
| 144 | } /* detail */ | 
| 145 |  | 
| 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 | 
| 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 addressof_declval() BOOST_NOEXCEPT; | 
| 174 |  | 
| 175 | template<class> | 
| 176 | struct addressof_void { | 
| 177 |     typedef void type; | 
| 178 | }; | 
| 179 |  | 
| 180 | template<class T, class E = void> | 
| 181 | struct addressof_member_operator { | 
| 182 |     static constexpr bool value = false; | 
| 183 | }; | 
| 184 |  | 
| 185 | template<class T> | 
| 186 | struct addressof_member_operator<T, typename | 
| 187 |     addressof_void<decltype(addressof_declval<T&>().operator&())>::type> { | 
| 188 |     static constexpr bool value = true; | 
| 189 | }; | 
| 190 |  | 
| 191 | #if BOOST_WORKAROUND(BOOST_INTEL, < 1600) | 
| 192 | struct addressof_addressable { }; | 
| 193 |  | 
| 194 | addressof_addressable* | 
| 195 | operator&(addressof_addressable&) BOOST_NOEXCEPT; | 
| 196 | #endif | 
| 197 |  | 
| 198 | template<class T, class E = void> | 
| 199 | struct addressof_non_member_operator { | 
| 200 |     static constexpr bool value = false; | 
| 201 | }; | 
| 202 |  | 
| 203 | template<class T> | 
| 204 | struct addressof_non_member_operator<T, typename | 
| 205 |     addressof_void<decltype(operator&(addressof_declval<T&>()))>::type> { | 
| 206 |     static constexpr bool value = true; | 
| 207 | }; | 
| 208 |  | 
| 209 | template<class T, class E = void> | 
| 210 | struct addressof_expression { | 
| 211 |     static constexpr bool value = false; | 
| 212 | }; | 
| 213 |  | 
| 214 | template<class T> | 
| 215 | struct addressof_expression<T, | 
| 216 |     typename addressof_void<decltype(&addressof_declval<T&>())>::type> { | 
| 217 |     static constexpr bool value = true; | 
| 218 | }; | 
| 219 |  | 
| 220 | template<class T> | 
| 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; | 
| 225 | }; | 
| 226 |  | 
| 227 | template<bool E, class T> | 
| 228 | struct addressof_if { }; | 
| 229 |  | 
| 230 | template<class T> | 
| 231 | struct addressof_if<true, T> { | 
| 232 |     typedef T* type; | 
| 233 | }; | 
| 234 |  | 
| 235 | template<class T> | 
| 236 | BOOST_FORCEINLINE | 
| 237 | typename addressof_if<!addressof_is_constexpr<T>::value, T>::type | 
| 238 | addressof(T& o) BOOST_NOEXCEPT | 
| 239 | { | 
| 240 |     return address_of<T>::get(addressof_ref<T>(o), 0); | 
| 241 | } | 
| 242 |  | 
| 243 | template<class T> | 
| 244 | constexpr BOOST_FORCEINLINE | 
| 245 | typename addressof_if<addressof_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 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 |  |