summaryrefslogtreecommitdiff
path: root/boost/core/addressof.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/core/addressof.hpp')
-rw-r--r--boost/core/addressof.hpp301
1 files changed, 202 insertions, 99 deletions
diff --git a/boost/core/addressof.hpp b/boost/core/addressof.hpp
index 889b5825e1..0a2b46be77 100644
--- a/boost/core/addressof.hpp
+++ b/boost/core/addressof.hpp
@@ -1,162 +1,265 @@
-// Copyright (C) 2002 Brad King (brad.king@kitware.com)
-// Douglas Gregor (gregod@cs.rpi.edu)
-//
-// Copyright (C) 2002, 2008, 2013 Peter Dimov
-//
-// 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)
+/*
+Copyright (C) 2002 Brad King (brad.king@kitware.com)
+ Douglas Gregor (gregod@cs.rpi.edu)
-// For more information, see http://www.boost.org
+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 <boost/config.hpp>
-# include <boost/detail/workaround.hpp>
-# include <cstddef>
+#include <boost/config.hpp>
-namespace boost
-{
+#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
+#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
+#elif defined(BOOST_GCC) && 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
-namespace detail
-{
+#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF)
+#if defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
+#endif
+
+namespace boost {
-template<class T> struct addr_impl_ref
+template<class T>
+BOOST_CONSTEXPR inline T*
+addressof(T& o) BOOST_NOEXCEPT
{
- T & v_;
+ return __builtin_addressof(o);
+}
- BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
- BOOST_FORCEINLINE operator T& () const { return v_; }
+} /* boost */
+#else
+#include <boost/detail/workaround.hpp>
+#include <cstddef>
+namespace boost {
+namespace detail {
+
+template<class T>
+class addressof_ref {
+public:
+ BOOST_FORCEINLINE addressof_ref(T& o) BOOST_NOEXCEPT
+ : o_(o) { }
+ BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
+ return o_;
+ }
private:
- addr_impl_ref & operator=(const addr_impl_ref &);
+ addressof_ref& operator=(const addressof_ref&);
+ T& o_;
};
-template<class T> struct addressof_impl
-{
- static BOOST_FORCEINLINE T * f( T & v, long )
- {
- return reinterpret_cast<T*>(
- &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+template<class T>
+struct address_of {
+ static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT {
+ return reinterpret_cast<T*>(&
+ const_cast<char&>(reinterpret_cast<const volatile char&>(o)));
}
-
- static BOOST_FORCEINLINE T * f( T * v, int )
- {
- return v;
+ 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( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
-
- typedef decltype(nullptr) addr_nullptr_t;
-
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && \
+ (defined(__INTEL_COMPILER) || \
+ (defined(__clang__) && !defined(_LIBCPP_VERSION)))
+typedef decltype(nullptr) addressof_null_t;
#else
-
- typedef std::nullptr_t addr_nullptr_t;
-
+typedef std::nullptr_t addressof_null_t;
#endif
-template<> struct addressof_impl< addr_nullptr_t >
-{
- typedef addr_nullptr_t T;
-
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<addressof_null_t> {
+ typedef addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
-template<> struct addressof_impl< addr_nullptr_t const >
-{
- typedef addr_nullptr_t const T;
-
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<const addressof_null_t> {
+ typedef const addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
-template<> struct addressof_impl< addr_nullptr_t volatile >
-{
- typedef addr_nullptr_t volatile T;
+template<>
+struct address_of<volatile addressof_null_t> {
+ typedef volatile addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
+ }
+};
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<const volatile addressof_null_t> {
+ typedef const volatile addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
+#endif
+
+} /* detail */
-template<> struct addressof_impl< addr_nullptr_t const volatile >
+#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \
+ defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
+ defined(BOOST_NO_CXX11_CONSTEXPR) || \
+ defined(BOOST_NO_CXX11_DECLTYPE)
+#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
+
+template<class T>
+BOOST_FORCEINLINE T*
+addressof(T& o) BOOST_NOEXCEPT
{
- typedef addr_nullptr_t const volatile T;
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) || \
+ BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
+ return detail::address_of<T>::get(o, 0);
+#else
+ return detail::address_of<T>::get(detail::addressof_ref<T>(o), 0);
+#endif
+}
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
- }
+#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+namespace detail {
+
+template<class T>
+struct addressof_result {
+ typedef T* type;
};
+} /* detail */
+
+template<class T, std::size_t N>
+BOOST_FORCEINLINE typename detail::addressof_result<T[N]>::type
+addressof(T (&o)[N]) BOOST_NOEXCEPT
+{
+ return &o;
+}
#endif
-} // namespace detail
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+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>
+template<class T, std::size_t N>
BOOST_FORCEINLINE
-T * addressof( T & v )
+const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
{
-#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120))
+ return reinterpret_cast<const T(*)[N]>(&o);
+}
+#endif
+#else
+namespace detail {
- return boost::detail::addressof_impl<T>::f( v, 0 );
+template<class T>
+T&& addressof_declval() BOOST_NOEXCEPT;
-#else
+template<class>
+struct addressof_void {
+ typedef void type;
+};
- return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );
+template<class T, class E = void>
+struct addressof_member_operator {
+ static constexpr bool value = false;
+};
+
+template<class T>
+struct addressof_member_operator<T, typename
+ addressof_void<decltype(addressof_declval<T&>().operator&())>::type> {
+ static constexpr bool value = true;
+};
+
+#if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
+struct addressof_addressable { };
+addressof_addressable*
+operator&(addressof_addressable&) BOOST_NOEXCEPT;
#endif
-}
-#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) )
+template<class T, class E = void>
+struct addressof_non_member_operator {
+ static constexpr bool value = false;
+};
-namespace detail
-{
+template<class T>
+struct addressof_non_member_operator<T, typename
+ addressof_void<decltype(operator&(addressof_declval<T&>()))>::type> {
+ static constexpr bool value = true;
+};
-template<class T> struct addressof_addp
-{
- typedef T * type;
+template<class T, class E = void>
+struct addressof_expression {
+ static constexpr bool value = false;
+};
+
+template<class T>
+struct addressof_expression<T,
+ typename addressof_void<decltype(&addressof_declval<T&>())>::type> {
+ static constexpr bool value = true;
+};
+
+template<class T>
+struct addressof_is_constexpr {
+ static constexpr bool value = addressof_expression<T>::value &&
+ !addressof_member_operator<T>::value &&
+ !addressof_non_member_operator<T>::value;
};
-} // namespace detail
+template<bool E, class T>
+struct addressof_if { };
+
+template<class T>
+struct addressof_if<true, T> {
+ typedef T* type;
+};
-template< class T, std::size_t N >
+template<class T>
BOOST_FORCEINLINE
-typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] )
+typename addressof_if<!addressof_is_constexpr<T>::value, T>::type
+addressof(T& o) BOOST_NOEXCEPT
{
- return &t;
+ return address_of<T>::get(addressof_ref<T>(o), 0);
}
-#endif
-
-// Borland doesn't like casting an array reference to a char reference
-// but these overloads work around the problem.
-#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-template<typename T,std::size_t N>
-BOOST_FORCEINLINE
-T (*addressof(T (&t)[N]))[N]
+template<class T>
+constexpr BOOST_FORCEINLINE
+typename addressof_if<addressof_is_constexpr<T>::value, T>::type
+addressof(T& o) BOOST_NOEXCEPT
{
- return reinterpret_cast<T(*)[N]>(&t);
+ return &o;
}
-template<typename T,std::size_t N>
-BOOST_FORCEINLINE
-const T (*addressof(const T (&t)[N]))[N]
+} /* detail */
+
+template<class T>
+constexpr BOOST_FORCEINLINE T*
+addressof(T& o) BOOST_NOEXCEPT
{
- return reinterpret_cast<const T(*)[N]>(&t);
+ return detail::addressof(o);
}
#endif
-} // namespace boost
+} /* boost */
+#endif
-#endif // BOOST_CORE_ADDRESSOF_HPP
+#endif