diff options
Diffstat (limited to 'libcxx/include/__memory/pointer_traits.h')
| -rw-r--r-- | libcxx/include/__memory/pointer_traits.h | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h index 2549e4be7df1..c4f20def4540 100644 --- a/libcxx/include/__memory/pointer_traits.h +++ b/libcxx/include/__memory/pointer_traits.h @@ -12,7 +12,15 @@ #include <__config> #include <__memory/addressof.h> -#include <type_traits> +#include <__type_traits/conditional.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/decay.h> +#include <__type_traits/is_class.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_void.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> +#include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -24,8 +32,7 @@ template <class _Tp, class = void> struct __has_element_type : false_type {}; template <class _Tp> -struct __has_element_type<_Tp, - typename __void_t<typename _Tp::element_type>::type> : true_type {}; +struct __has_element_type<_Tp, __void_t<typename _Tp::element_type> > : true_type {}; template <class _Ptr, bool = __has_element_type<_Ptr>::value> struct __pointer_traits_element_type; @@ -52,8 +59,7 @@ template <class _Tp, class = void> struct __has_difference_type : false_type {}; template <class _Tp> -struct __has_difference_type<_Tp, - typename __void_t<typename _Tp::difference_type>::type> : true_type {}; +struct __has_difference_type<_Tp, __void_t<typename _Tp::difference_type> > : true_type {}; template <class _Ptr, bool = __has_difference_type<_Ptr>::value> struct __pointer_traits_difference_type @@ -122,9 +128,8 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits private: struct __nat {}; public: - _LIBCPP_INLINE_VISIBILITY - static pointer pointer_to(typename conditional<is_void<element_type>::value, - __nat, element_type>::type& __r) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + static pointer pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) {return pointer::pointer_to(__r);} }; @@ -144,20 +149,18 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*> private: struct __nat {}; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - static pointer pointer_to(typename conditional<is_void<element_type>::value, - __nat, element_type>::type& __r) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + static pointer pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) _NOEXCEPT {return _VSTD::addressof(__r);} }; -template <class _From, class _To> -struct __rebind_pointer { #ifndef _LIBCPP_CXX03_LANG - typedef typename pointer_traits<_From>::template rebind<_To> type; +template <class _From, class _To> +using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>; #else - typedef typename pointer_traits<_From>::template rebind<_To>::other type; +template <class _From, class _To> +using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>::other; #endif -}; // to_address @@ -171,12 +174,33 @@ _Tp* __to_address(_Tp* __p) _NOEXCEPT { return __p; } +template <class _Pointer, class = void> +struct _HasToAddress : false_type {}; + +template <class _Pointer> +struct _HasToAddress<_Pointer, + decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>())) +> : true_type {}; + +template <class _Pointer, class = void> +struct _HasArrow : false_type {}; + +template <class _Pointer> +struct _HasArrow<_Pointer, + decltype((void)std::declval<const _Pointer&>().operator->()) +> : true_type {}; + +template <class _Pointer> +struct _IsFancyPointer { + static const bool value = _HasArrow<_Pointer>::value || _HasToAddress<_Pointer>::value; +}; + // enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers template <class _Pointer, class = __enable_if_t< - !is_pointer<_Pointer>::value && !is_array<_Pointer>::value && !is_function<_Pointer>::value + _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type +typename decay<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>::type __to_address(const _Pointer& __p) _NOEXCEPT { return __to_address_helper<_Pointer>::__call(__p); } @@ -184,16 +208,16 @@ __to_address(const _Pointer& __p) _NOEXCEPT { template <class _Pointer, class> struct __to_address_helper { _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - static decltype(_VSTD::__to_address(declval<const _Pointer&>().operator->())) + static decltype(_VSTD::__to_address(std::declval<const _Pointer&>().operator->())) __call(const _Pointer& __p) _NOEXCEPT { return _VSTD::__to_address(__p.operator->()); } }; template <class _Pointer> -struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))> { +struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))> { _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - static decltype(pointer_traits<_Pointer>::to_address(declval<const _Pointer&>())) + static decltype(pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>())) __call(const _Pointer& __p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); } @@ -208,7 +232,7 @@ auto to_address(_Tp *__p) noexcept { template <class _Pointer> inline _LIBCPP_INLINE_VISIBILITY constexpr -auto to_address(const _Pointer& __p) noexcept { +auto to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)) { return _VSTD::__to_address(__p); } #endif |
