/* Copyright 2017-2021 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_CORE_POINTER_TRAITS_HPP #define BOOST_CORE_POINTER_TRAITS_HPP #include #include #include namespace boost { namespace detail { struct ptr_none { }; template struct ptr_valid { typedef void type; }; template struct ptr_first { typedef ptr_none type; }; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args> struct ptr_first > { typedef U type; }; #else template class T, class U> struct ptr_first > { typedef U type; }; template class T, class U1, class U2> struct ptr_first > { typedef U1 type; }; template class T, class U1, class U2, class U3> struct ptr_first > { typedef U1 type; }; #endif template struct ptr_element { typedef typename ptr_first::type type; }; template struct ptr_element::type> { typedef typename T::element_type type; }; template struct ptr_difference { typedef std::ptrdiff_t type; }; template struct ptr_difference::type> { typedef typename T::difference_type type; }; template struct ptr_transform { }; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args, class V> struct ptr_transform, V> { typedef T type; }; #else template class T, class U, class V> struct ptr_transform, V> { typedef T type; }; template class T, class U1, class U2, class V> struct ptr_transform, V> { typedef T type; }; template class T, class U1, class U2, class U3, class V> struct ptr_transform, V> { typedef T type; }; #endif template struct ptr_rebind : ptr_transform { }; template struct ptr_rebind >::type> { typedef typename T::template rebind type; }; #if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) template class ptr_to_expr { template struct result { char x, y; }; static E& source(); template static auto check(int) -> result; template static char check(long); public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; template struct ptr_to_expr { BOOST_STATIC_CONSTEXPR bool value = true; }; template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr::value; }; #else template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = true; }; #endif template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = false; }; template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = false; }; template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = false; }; template struct ptr_has_to { BOOST_STATIC_CONSTEXPR bool value = false; }; template::value> struct ptr_to { }; template struct ptr_to { static T pointer_to(E& v) { return T::pointer_to(v); } }; template struct ptr_to { static T* pointer_to(T& v) BOOST_NOEXCEPT { return boost::addressof(v); } }; template struct ptr_traits : ptr_to { typedef T pointer; typedef E element_type; typedef typename ptr_difference::type difference_type; template struct rebind_to : ptr_rebind { }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = typename rebind_to::type; #endif }; template struct ptr_traits { }; } /* detail */ template struct pointer_traits : detail::ptr_traits::type> { }; template struct pointer_traits : detail::ptr_to { typedef T* pointer; typedef T element_type; typedef std::ptrdiff_t difference_type; template struct rebind_to { typedef U* type; }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = typename rebind_to::type*; #endif }; template BOOST_CONSTEXPR inline T* to_address(T* v) BOOST_NOEXCEPT { return v; } #if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION) namespace detail { template inline T* ptr_address(T* v, int) BOOST_NOEXCEPT { return v; } template inline auto ptr_address(const T& v, int) BOOST_NOEXCEPT -> decltype(boost::pointer_traits::to_address(v)) { return boost::pointer_traits::to_address(v); } template inline auto ptr_address(const T& v, long) BOOST_NOEXCEPT { return boost::detail::ptr_address(v.operator->(), 0); } } /* detail */ template inline auto to_address(const T& v) BOOST_NOEXCEPT { return boost::detail::ptr_address(v, 0); } #else template inline typename pointer_traits::element_type* to_address(const T& v) BOOST_NOEXCEPT { return boost::to_address(v.operator->()); } #endif } /* boost */ #endif