/* Copyright 2017-2018 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 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS) #include #else #include #endif namespace boost { #if !defined(BOOST_NO_CXX11_POINTER_TRAITS) template struct pointer_traits : std::pointer_traits { template struct rebind_to { typedef typename std::pointer_traits::template rebind type; }; }; template struct pointer_traits : std::pointer_traits { template struct rebind_to { typedef U* type; }; }; #else namespace detail { template struct ptr_void { typedef void type; }; template struct ptr_first; #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 { typedef typename ptr_transform::type type; }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template struct ptr_rebind >::type> { typedef typename T::template rebind type; }; #endif template struct ptr_value { typedef T type; }; template<> struct ptr_value { typedef struct { } type; }; } /* detail */ template struct pointer_traits { typedef T pointer; typedef typename detail::ptr_element::type element_type; typedef typename detail::ptr_difference::type difference_type; template struct rebind_to { typedef typename detail::ptr_rebind::type type; }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = typename detail::ptr_rebind::type; #endif static pointer pointer_to(typename detail::ptr_value::type& v) { return pointer::pointer_to(v); } }; template struct pointer_traits { 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 = U*; #endif static T* pointer_to(typename detail::ptr_value::type& v) BOOST_NOEXCEPT { return boost::addressof(v); } }; #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