From 4f44c5556fc384b57ea0c8c6908701bb5f1c4ed4 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 1 Jul 2015 13:24:03 +0100 Subject: [PATCH] ptr_traits.h (__ptrtr_elt_type, [...]): Remove * include/bits/ptr_traits.h (__ptrtr_elt_type, __ptrtr_diff_type, __ptrtr_rebind, __ptrtr_not_void): Remove (__get_first_arg, __replace_first_arg, __make_not_void): Define new transformations. (__detected_or_): New detection trait. (pointer_traits): Use new traits. * testsuite/20_util/pointer_traits/pointer_to.cc: Add rebind member. * testsuite/20_util/pointer_traits/requirements/ explicit_instantiation.cc: Use valid arguments to pointer_traits. From-SVN: r225243 --- libstdc++-v3/ChangeLog | 10 ++ libstdc++-v3/include/bits/ptr_traits.h | 144 +++++++++------------ .../testsuite/20_util/pointer_traits/pointer_to.cc | 2 + .../requirements/explicit_instantiation.cc | 19 ++- 4 files changed, 89 insertions(+), 86 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e349937..f7ea928 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2015-07-01 Jonathan Wakely + * include/bits/ptr_traits.h (__ptrtr_elt_type, __ptrtr_diff_type, + __ptrtr_rebind, __ptrtr_not_void): Remove + (__get_first_arg, __replace_first_arg, __make_not_void): Define new + transformations. + (__detected_or_): New detection trait. + (pointer_traits): Use new traits. + * testsuite/20_util/pointer_traits/pointer_to.cc: Add rebind member. + * testsuite/20_util/pointer_traits/requirements/ + explicit_instantiation.cc: Use valid arguments to pointer_traits. + * doc/xml/manual/status_cxx2017.xml: Update status table. * include/experimental/type_traits (void_t, is_detected, is_detected_v, detected_t, detected_or, detected_or_t, diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index 9fd6bf8..84cc4da 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -32,114 +32,86 @@ #if __cplusplus >= 201103L -#include // For _GLIBCXX_HAS_NESTED_TYPE +#include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION -_GLIBCXX_HAS_NESTED_TYPE(element_type) -_GLIBCXX_HAS_NESTED_TYPE(difference_type) - - template::value> - struct __ptrtr_elt_type; + class __undefined; + // Given Template return T, otherwise invalid. template - struct __ptrtr_elt_type<_Tp, true> - { - typedef typename _Tp::element_type __type; - }; - - template class _SomePtr, typename _Tp, - typename... _Args> - struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false> - { - typedef _Tp __type; - }; + struct __get_first_arg + { using type = __undefined; }; - template::value> - struct __ptrtr_diff_type - { - typedef typename _Tp::difference_type __type; - }; + template class _Template, typename _Tp, + typename... _Types> + struct __get_first_arg<_Template<_Tp, _Types...>> + { using type = _Tp; }; template - struct __ptrtr_diff_type<_Tp, false> - { - typedef ptrdiff_t __type; - }; - - template - class __ptrtr_rebind_helper - { - template - static constexpr true_type - _S_chk(typename _Ptr2::template rebind<_Up2>*); - - template - static constexpr false_type - _S_chk(...); - - public: - using __type = decltype(_S_chk<_Ptr, _Up>(nullptr)); - }; - - template::__type::value> - struct __ptrtr_rebind; + using __get_first_arg_t = typename __get_first_arg<_Tp>::type; + // Given Template and U return Template, otherwise invalid. template - struct __ptrtr_rebind<_Tp, _Up, true> - { - typedef typename _Tp::template rebind<_Up> __type; - }; + struct __replace_first_arg + { using type = __undefined; }; - template class _SomePtr, typename _Up, - typename _Tp, typename... _Args> - struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false> - { - typedef _SomePtr<_Up, _Args...> __type; - }; + template class _Template, typename _Up, + typename _Tp, typename... _Types> + struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> + { using type = _Template<_Up, _Types...>; }; - template::type> - struct __ptrtr_not_void - { - typedef _Tp __type; - }; + template + using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type; template - struct __ptrtr_not_void<_Tp, void> - { - struct __type { }; - }; - - template - class __ptrtr_pointer_to - { - typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type; - typedef typename __ptrtr_not_void<__orig_type>::__type __element_type; - - public: - static _Ptr pointer_to(__element_type& __e) - { return _Ptr::pointer_to(__e); } - }; + using __make_not_void + = typename conditional::value, __undefined, _Tp>::type; /** * @brief Uniform interface to all pointer-like types * @ingroup pointer_abstractions */ template - struct pointer_traits : __ptrtr_pointer_to<_Ptr> + struct pointer_traits { - /// The pointer type - typedef _Ptr pointer; - /// The type pointed to - typedef typename __ptrtr_elt_type<_Ptr>::__type element_type; - /// Type used to represent the difference between two pointers - typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type; + private: + template + using __element_type = typename _Tp::element_type; + + template + using __difference_type = typename _Tp::difference_type; + + template + using __rebind = typename _Tp::template rebind<_Up>; + + public: + /// The pointer type. + using pointer = _Ptr; + + /// The type pointed to. + using element_type + = __detected_or_t_<__get_first_arg_t, __element_type, _Ptr>; + /// The type used to represent the difference between two pointers. + using difference_type + = __detected_or_t; + + /// A pointer to a different type. template - using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type; + using rebind + = __detected_or_t_<__replace_first_arg_t, __rebind, _Ptr, _Up>; + + static _Ptr + pointer_to(__make_not_void& __e) + { return _Ptr::pointer_to(__e); } + + static_assert(!is_same::value, + "pointer type defines element_type or is like SomePointer"); + static_assert(!is_same, __undefined>::value, + "pointer type defines rebind or is like SomePointer"); }; /** @@ -165,10 +137,14 @@ _GLIBCXX_HAS_NESTED_TYPE(difference_type) * @return @c addressof(__r) */ static pointer - pointer_to(typename __ptrtr_not_void::__type& __r) noexcept + pointer_to(__make_not_void& __r) noexcept { return std::addressof(__r); } }; + /// Convenience alias for rebinding pointers. + template + using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>; + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/pointer_to.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/pointer_to.cc index 843adbd..6782f79 100644 --- a/libstdc++-v3/testsuite/20_util/pointer_traits/pointer_to.cc +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/pointer_to.cc @@ -26,6 +26,8 @@ struct Ptr typedef bool element_type; bool* value; + template using rebind = Ptr; + static Ptr pointer_to(bool& b) { return Ptr{&b}; } }; diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc index f47bed0..d9c808f 100644 --- a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc @@ -22,10 +22,25 @@ #include +template +struct P1 +{ + using element_type = T; + using difference_type = long; + template using rebind = P1; + static P1 pointer_to(T&) { return {}; } +}; + +template +struct P2 +{ + static P2 pointer_to(T&) { return {}; } +}; + namespace std { typedef short test_type; template struct pointer_traits; - template struct pointer_traits>; - template struct pointer_traits>; + template struct pointer_traits>; + template struct pointer_traits>; } -- 2.7.4