/* Copyright 2017 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 { template struct pointer_traits; namespace detail { template inline typename boost::pointer_traits::element_type* ptr_traits_address(const U& v) BOOST_NOEXCEPT { return boost::pointer_traits::to_address(v); } } /* detail */ #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; }; static typename std::pointer_traits::element_type* to_address(const T& v) BOOST_NOEXCEPT { return detail::ptr_traits_address(v.operator->()); } }; template struct pointer_traits : std::pointer_traits { template struct rebind_to { typedef U* type; }; static T* to_address(T* v) BOOST_NOEXCEPT { return v; } }; #else namespace detail { struct ptr_traits_none { char first, second; }; template struct ptr_traits_has_element { private: template static ptr_traits_none call(...); template static char call(typename U::element_type* = 0); public: static const bool value = sizeof(call(0)) == 1; }; template struct ptr_traits_first; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args> struct ptr_traits_first > { typedef U type; }; #else template class T, class U> struct ptr_traits_first > { typedef U type; }; template class T, class U1, class U2> struct ptr_traits_first > { typedef U1 type; }; template class T, class U1, class U2, class U3> struct ptr_traits_first > { typedef U1 type; }; #endif template::value> struct ptr_traits_element { typedef typename T::element_type type; }; template struct ptr_traits_element { typedef typename ptr_traits_first::type type; }; template struct ptr_traits_has_difference { private: template static ptr_traits_none call(...); template static char call(typename U::difference_type* = 0); public: static const bool value = sizeof(call(0)) == 1; }; template::value> struct ptr_traits_difference { typedef typename T::difference_type type; }; template struct ptr_traits_difference { typedef std::ptrdiff_t type; }; template struct ptr_traits_has_rebind { private: template static ptr_traits_none call(...); template static char call(typename U::template rebind* = 0); public: static const bool value = sizeof(call(0)) == 1; }; template struct ptr_traits_rebind_to; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template class T, class U, class... Args, class V> struct ptr_traits_rebind_to, V> { typedef T type; }; #else template class T, class U, class V> struct ptr_traits_rebind_to, V> { typedef T type; }; template class T, class U1, class U2, class V> struct ptr_traits_rebind_to, V> { typedef T type; }; template class T, class U1, class U2, class U3, class V> struct ptr_traits_rebind_to, V> { typedef T type; }; #endif #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template::value> struct ptr_traits_rebind { typedef typename T::template rebind type; }; template struct ptr_traits_rebind { typedef typename ptr_traits_rebind_to::type type; }; #else template struct ptr_traits_rebind { typedef typename ptr_traits_rebind_to::type type; }; #endif template struct ptr_traits_value { typedef T type; }; template<> struct ptr_traits_value { typedef struct { } type; }; } /* detail */ template struct pointer_traits { typedef T pointer; typedef typename detail::ptr_traits_element::type element_type; typedef typename detail::ptr_traits_difference::type difference_type; template struct rebind_to { typedef typename detail::ptr_traits_rebind::type type; }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = typename detail::ptr_traits_rebind::type; #endif static pointer pointer_to(typename detail::ptr_traits_value::type& v) { return pointer::pointer_to(v); } static element_type* to_address(const pointer& v) BOOST_NOEXCEPT { return detail::ptr_traits_address(v.operator->()); } }; 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_traits_value::type& v) BOOST_NOEXCEPT { return addressof(v); } static T* to_address(T* v) BOOST_NOEXCEPT { return v; } }; #endif template inline typename pointer_traits::element_type* to_address(const T& v) BOOST_NOEXCEPT { return pointer_traits::to_address(v); } template inline T* to_address(T* v) BOOST_NOEXCEPT { return v; } } /* boost */ #endif