1
0
forked from boostorg/core
Files
boost_core/include/boost/core/addressof.hpp

275 lines
6.0 KiB
C++
Raw Normal View History

2017-01-30 17:34:49 -05:00
/*
Copyright (C) 2002 Brad King (brad.king@kitware.com)
Douglas Gregor (gregod@cs.rpi.edu)
2017-01-30 17:34:49 -05:00
Copyright (C) 2002, 2008, 2013 Peter Dimov
2017-01-30 17:34:49 -05:00
Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
2017-02-02 13:42:42 -05:00
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
2017-01-30 17:34:49 -05:00
http://www.boost.org/LICENSE_1_0.txt)
*/
2017-01-30 17:34:49 -05:00
#ifndef BOOST_CORE_ADDRESSOF_HPP
#define BOOST_CORE_ADDRESSOF_HPP
2017-01-30 17:34:49 -05:00
#include <boost/config.hpp>
#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
2017-01-31 19:29:53 -05:00
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
2017-01-31 19:29:53 -05:00
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
#elif defined(__has_builtin)
#if __has_builtin(__builtin_addressof)
#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
#endif
2017-01-30 17:34:49 -05:00
#endif
2017-01-31 19:29:53 -05:00
#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF)
#if defined(BOOST_NO_CXX11_CONSTEXPR)
#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
#endif
2017-01-31 19:29:53 -05:00
namespace boost {
template<class T>
BOOST_CONSTEXPR inline T*
addressof(T& o) BOOST_NOEXCEPT
{
return __builtin_addressof(o);
}
} /* boost */
#else
2017-06-13 23:24:38 -04:00
#include <boost/config/workaround.hpp>
2017-01-31 19:29:53 -05:00
#include <cstddef>
2017-01-30 17:34:49 -05:00
namespace boost {
namespace detail {
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
class addrof_ref {
2017-01-30 17:34:49 -05:00
public:
2018-01-27 12:44:50 -05:00
BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT
2017-01-30 17:34:49 -05:00
: o_(o) { }
BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
return o_;
}
private:
2018-01-27 12:44:50 -05:00
addrof_ref& operator=(const addrof_ref&);
2017-01-30 17:34:49 -05:00
T& o_;
};
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof {
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT {
return reinterpret_cast<T*>(&
const_cast<char&>(reinterpret_cast<const volatile char&>(o)));
}
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT {
return p;
}
};
2017-01-30 17:34:49 -05:00
#if !defined(BOOST_NO_CXX11_NULLPTR)
#if !defined(BOOST_NO_CXX11_DECLTYPE) && \
(defined(__INTEL_COMPILER) || \
(defined(__clang__) && !defined(_LIBCPP_VERSION)))
2018-01-27 12:44:50 -05:00
typedef decltype(nullptr) addrof_null_t;
#else
2018-01-27 12:44:50 -05:00
typedef std::nullptr_t addrof_null_t;
#endif
2017-01-30 17:34:49 -05:00
template<>
2018-01-27 12:44:50 -05:00
struct addrof<addrof_null_t> {
typedef addrof_null_t type;
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
return &o;
}
};
2017-01-30 17:34:49 -05:00
template<>
2018-01-27 12:44:50 -05:00
struct addrof<const addrof_null_t> {
typedef const addrof_null_t type;
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
return &o;
}
};
2017-01-30 17:34:49 -05:00
template<>
2018-01-27 12:44:50 -05:00
struct addrof<volatile addrof_null_t> {
typedef volatile addrof_null_t type;
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
return &o;
}
};
2017-01-30 17:34:49 -05:00
template<>
2018-01-27 12:44:50 -05:00
struct addrof<const volatile addrof_null_t> {
typedef const volatile addrof_null_t type;
2017-01-30 17:34:49 -05:00
static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
return &o;
}
};
2017-01-30 17:34:49 -05:00
#endif
2017-01-31 19:29:53 -05:00
} /* detail */
#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \
2017-01-31 19:29:53 -05:00
defined(BOOST_NO_CXX11_CONSTEXPR) || \
defined(BOOST_NO_CXX11_DECLTYPE)
2017-01-31 19:29:53 -05:00
#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
2017-01-30 17:34:49 -05:00
template<class T>
BOOST_FORCEINLINE T*
addressof(T& o) BOOST_NOEXCEPT
{
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \
2017-02-02 13:42:42 -05:00
BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
2018-01-27 12:44:50 -05:00
return boost::detail::addrof<T>::get(o, 0);
2017-01-30 17:34:49 -05:00
#else
2018-01-27 12:44:50 -05:00
return boost::detail::addrof<T>::get(boost::detail::addrof_ref<T>(o), 0);
2017-01-30 17:34:49 -05:00
#endif
}
2017-01-31 19:29:53 -05:00
2017-02-02 13:42:42 -05:00
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
2017-01-31 19:29:53 -05:00
namespace detail {
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_result {
2017-01-31 19:29:53 -05:00
typedef T* type;
};
} /* detail */
template<class T, std::size_t N>
2018-01-27 12:44:50 -05:00
BOOST_FORCEINLINE typename boost::detail::addrof_result<T[N]>::type
2017-01-31 19:29:53 -05:00
addressof(T (&o)[N]) BOOST_NOEXCEPT
{
return &o;
}
#endif
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
2017-01-31 19:29:53 -05:00
template<class T, std::size_t N>
BOOST_FORCEINLINE
T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
{
return reinterpret_cast<T(*)[N]>(&o);
}
template<class T, std::size_t N>
BOOST_FORCEINLINE
const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
{
return reinterpret_cast<const T(*)[N]>(&o);
}
#endif
2017-01-30 17:34:49 -05:00
#else
2017-01-31 19:29:53 -05:00
namespace detail {
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
T addrof_declval() BOOST_NOEXCEPT;
2017-01-30 17:34:49 -05:00
template<class>
2018-01-27 12:44:50 -05:00
struct addrof_void {
typedef void type;
};
2017-01-30 17:34:49 -05:00
template<class T, class E = void>
2018-01-27 12:44:50 -05:00
struct addrof_member_operator {
2017-01-30 17:34:49 -05:00
static constexpr bool value = false;
};
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_member_operator<T, typename
addrof_void<decltype(addrof_declval<T&>().operator&())>::type> {
2017-01-30 17:34:49 -05:00
static constexpr bool value = true;
};
#if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
2018-01-27 12:44:50 -05:00
struct addrof_addressable { };
2017-01-30 17:34:49 -05:00
2018-01-27 12:44:50 -05:00
addrof_addressable*
operator&(addrof_addressable&) BOOST_NOEXCEPT;
#endif
2017-01-30 17:34:49 -05:00
template<class T, class E = void>
2018-01-27 12:44:50 -05:00
struct addrof_non_member_operator {
2017-01-30 17:34:49 -05:00
static constexpr bool value = false;
};
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_non_member_operator<T, typename
addrof_void<decltype(operator&(addrof_declval<T&>()))>::type> {
2017-01-30 17:34:49 -05:00
static constexpr bool value = true;
};
template<class T, class E = void>
2018-01-27 12:44:50 -05:00
struct addrof_expression {
2017-01-30 17:34:49 -05:00
static constexpr bool value = false;
};
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_expression<T,
typename addrof_void<decltype(&addrof_declval<T&>())>::type> {
2017-01-30 17:34:49 -05:00
static constexpr bool value = true;
};
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_is_constexpr {
static constexpr bool value = addrof_expression<T>::value &&
!addrof_member_operator<T>::value &&
!addrof_non_member_operator<T>::value;
2017-01-30 17:34:49 -05:00
};
2017-01-30 17:34:49 -05:00
template<bool E, class T>
2018-01-27 12:44:50 -05:00
struct addrof_if { };
2017-01-30 17:34:49 -05:00
template<class T>
2018-01-27 12:44:50 -05:00
struct addrof_if<true, T> {
2017-01-30 17:34:49 -05:00
typedef T* type;
};
2017-01-30 17:34:49 -05:00
template<class T>
BOOST_FORCEINLINE
2018-01-27 12:44:50 -05:00
typename addrof_if<!addrof_is_constexpr<T>::value, T>::type
2017-01-30 17:34:49 -05:00
addressof(T& o) BOOST_NOEXCEPT
{
2018-01-27 12:44:50 -05:00
return addrof<T>::get(addrof_ref<T>(o), 0);
2017-01-30 17:34:49 -05:00
}
2017-01-30 17:34:49 -05:00
template<class T>
constexpr BOOST_FORCEINLINE
2018-01-27 12:44:50 -05:00
typename addrof_if<addrof_is_constexpr<T>::value, T>::type
2017-01-30 17:34:49 -05:00
addressof(T& o) BOOST_NOEXCEPT
{
2017-01-30 17:34:49 -05:00
return &o;
}
} /* detail */
2017-01-30 17:34:49 -05:00
template<class T>
2017-01-31 19:29:53 -05:00
constexpr BOOST_FORCEINLINE T*
2017-01-30 17:34:49 -05:00
addressof(T& o) BOOST_NOEXCEPT
{
2018-01-27 12:44:50 -05:00
return boost::detail::addressof(o);
}
2017-01-30 17:34:49 -05:00
#endif
2017-01-30 17:34:49 -05:00
} /* boost */
2017-01-31 19:29:53 -05:00
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
namespace boost {
template<class T>
const T* addressof(const T&&) = delete;
} /* boost */
#endif
2017-01-30 17:34:49 -05:00
#endif