/* Copyright (C) 2002 Brad King (brad.king@kitware.com) Douglas Gregor (gregod@cs.rpi.edu) Copyright (C) 2002, 2008, 2013 Peter Dimov Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_CORE_ADDRESSOF_HPP #define BOOST_CORE_ADDRESSOF_HPP #include #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 class addressof_ref { public: BOOST_FORCEINLINE addressof_ref(T& o) BOOST_NOEXCEPT : o_(o) { } BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT { return o_; } private: T& o_; }; template struct address_of { static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT { return reinterpret_cast(& const_cast(reinterpret_cast(o))); } static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT { return p; } }; #if !defined(BOOST_NO_CXX11_NULLPTR) #if !defined(BOOST_NO_CXX11_DECLTYPE) && \ (defined(__INTEL_COMPILER) || \ (defined(__clang__) && !defined(_LIBCPP_VERSION))) typedef decltype(nullptr) null_type; #else typedef std::nullptr_t null_type; #endif template<> struct address_of { typedef null_type type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> struct address_of { typedef const null_type type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> struct address_of { typedef volatile null_type type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; template<> struct address_of { typedef const volatile null_type type; static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { return &o; } }; #endif #if defined(BOOST_CORE_NO_CONSTEXPR_ADDRESSOF) template BOOST_FORCEINLINE T* addressof(T& o) BOOST_NOEXCEPT { #if (defined(__BORLANDC__) && \ BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))) || \ (defined(__SUNPRO_CC) && \ BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)) return address_of::get(o, 0); #else return address_of::get(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 { typedef T* type; }; } /* detail */ } /* core */ template BOOST_FORCEINLINE typename core::detail::add_pointer::type addressof(T (&o)[N]) BOOST_NOEXCEPT { return &o; } #endif #if defined(__BORLANDC__) && \ BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template BOOST_FORCEINLINE T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N] { return reinterpret_cast(&o); } template BOOST_FORCEINLINE const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N] { return reinterpret_cast(&o); } #endif #endif } /* boost */ #endif