diff --git a/include/boost/core/addressof.hpp b/include/boost/core/addressof.hpp index a308da4..7dda247 100644 --- a/include/boost/core/addressof.hpp +++ b/include/boost/core/addressof.hpp @@ -15,20 +15,33 @@ http://www.boost.org/LICENSE_1_0.txt) #define BOOST_CORE_ADDRESSOF_HPP #include + +#if BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif BOOST_GCC >= 70000 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF) +namespace boost { + +template +BOOST_CONSTEXPR inline T* +addressof(T& o) BOOST_NOEXCEPT +{ + return __builtin_addressof(o); +} + +} /* boost */ +#else #include #include -#if defined(BOOST_NO_SFINAE_EXPR) || \ - defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ - defined(BOOST_NO_CXX11_CONSTEXPR) || \ - defined(BOOST_NO_CXX11_DECLTYPE) || \ - (defined(BOOST_MSVC) && \ - BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))) -#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF -#endif - namespace boost { -namespace core { namespace detail { template @@ -46,8 +59,8 @@ private: template struct address_of { static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT { - return reinterpret_cast(& - const_cast(reinterpret_cast(o))); + return reinterpret_cast(&const_cast< + char&>(reinterpret_cast(o))); } static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT { return p; @@ -58,45 +71,54 @@ struct address_of { #if !defined(BOOST_NO_CXX11_DECLTYPE) && \ (defined(__INTEL_COMPILER) || \ (defined(__clang__) && !defined(_LIBCPP_VERSION))) -typedef decltype(nullptr) null_type; +typedef decltype(nullptr) addressof_null_t; #else -typedef std::nullptr_t null_type; +typedef std::nullptr_t addressof_null_t; #endif template<> -struct address_of { - typedef null_type type; +struct address_of { + typedef addressof_null_t type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> -struct address_of { - typedef const null_type type; +struct address_of { + typedef const addressof_null_t type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> -struct address_of { - typedef volatile null_type type; +struct address_of { + typedef volatile addressof_null_t type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> -struct address_of { - typedef const volatile null_type type; +struct address_of { + typedef const volatile addressof_null_t type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; #endif -#if defined(BOOST_CORE_NO_CONSTEXPR_ADDRESSOF) +} /* detail */ + +#if defined(BOOST_NO_SFINAE_EXPR) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_DECLTYPE) || \ + (defined(BOOST_MSVC) && \ + BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))) +#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF + template BOOST_FORCEINLINE T* addressof(T& o) BOOST_NOEXCEPT @@ -105,122 +127,25 @@ addressof(T& o) BOOST_NOEXCEPT BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))) || \ (defined(__SUNPRO_CC) && \ BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)) - return address_of::get(o, 0); + return detail::address_of::get(o, 0); #else - return address_of::get(addressof_ref(o), 0); + return detail::address_of::get(detail::addressof_ref(o), 0); #endif } -#else -template -struct add_rvalue_reference { - typedef T&& type; -}; -template -typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; - -template -struct make_void { - typedef void type; -}; - -template -struct has_member_address_operator { - static constexpr bool value = false; -}; - -template -struct has_member_address_operator().operator&())>::type> { - static constexpr bool value = true; -}; - -#if defined(BOOST_INTEL) && BOOST_WORKAROUND(BOOST_INTEL, < 1600) -struct addressable { }; - -addressable* operator&(addressable&) BOOST_NOEXCEPT; -#endif - -template -struct has_non_member_address_operator { - static constexpr bool value = false; -}; - -template -struct has_non_member_address_operator()))>::type> { - static constexpr bool value = true; -}; - -template -struct is_addressable { - static constexpr bool value = false; -}; - -template -struct is_addressable())>::type> { - static constexpr bool value = true; -}; - -template -struct has_constexpr_address { - static constexpr bool value = is_addressable::value && - !has_member_address_operator::value && - !has_non_member_address_operator::value; -}; - -template -struct address_if { }; - -template -struct address_if { - typedef T* type; -}; - -template -BOOST_FORCEINLINE -typename address_if::value, T>::type -addressof(T& o) BOOST_NOEXCEPT -{ - return address_of::get(addressof_ref(o), 0); -} - -template -constexpr BOOST_FORCEINLINE -typename address_if::value, T>::type -addressof(T& o) BOOST_NOEXCEPT -{ - return &o; -} -#endif - -} /* detail */ -} /* core */ - -template -BOOST_CONSTEXPR BOOST_FORCEINLINE T* -addressof(T& o) BOOST_NOEXCEPT -{ - return core::detail::addressof(o); -} - -#if defined(BOOST_CORE_NO_CONSTEXPR_ADDRESSOF) #if defined(__SUNPRO_CC) && \ BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) -namespace core { namespace detail { template -struct add_pointer { +struct addressof_result { typedef T* type; }; } /* detail */ -} /* core */ template -BOOST_FORCEINLINE typename core::detail::add_pointer::type +BOOST_FORCEINLINE typename detail::addressof_result::type addressof(T (&o)[N]) BOOST_NOEXCEPT { return &o; @@ -243,8 +168,108 @@ const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N] return reinterpret_cast(&o); } #endif +#else +namespace detail { + +template +struct addressof_rvalue { + typedef T&& type; +}; + +template +typename addressof_rvalue::type +addressof_declval() BOOST_NOEXCEPT; + +template +struct addressof_make_void { + typedef void type; +}; + +template +struct addressof_member_operator { + static constexpr bool value = false; +}; + +template +struct addressof_member_operator().operator&())>::type> { + static constexpr bool value = true; +}; + +#if defined(BOOST_INTEL) && BOOST_WORKAROUND(BOOST_INTEL, < 1600) +struct addressof_addressable { }; + +addressof_addressable* +operator&(addressof_addressable&) BOOST_NOEXCEPT; +#endif + +template +struct addressof_non_member_operator { + static constexpr bool value = false; +}; + +template +struct addressof_non_member_operator()))>::type> { + static constexpr bool value = true; +}; + +template +struct addressof_expression { + static constexpr bool value = false; +}; + +template +struct addressof_expression())>::type> { + static constexpr bool value = true; +}; + +template +struct addressof_is_constexpr { + static constexpr bool value = addressof_expression::value && + !addressof_member_operator::value && + !addressof_non_member_operator::value; +}; + +template +struct addressof_if { }; + +template +struct addressof_if { + typedef T* type; +}; + +template +BOOST_FORCEINLINE +typename addressof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return address_of::get(addressof_ref(o), 0); +} + +template +constexpr BOOST_FORCEINLINE +typename addressof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return &o; +} + +} /* detail */ + +template +constexpr BOOST_FORCEINLINE T* +addressof(T& o) BOOST_NOEXCEPT +{ + return detail::addressof(o); +} #endif } /* boost */ +#endif #endif