From: Jonathan Wakely Date: Thu, 4 Jun 2020 22:20:49 +0000 (+0100) Subject: libstdc++: Remove workarounds for constrained nested class templates X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f2242ec0d3f1bb13c78ef3c21e0354d84fe57222;p=gcc.git libstdc++: Remove workarounds for constrained nested class templates With PR c++/92078 and PR c++/92103 both fixed, nested class templates can now be constrained. That means a number of namespace-scope helpers can be moved to the class scope, so they're only visible where they're needed. * include/bits/iterator_concepts.h (__detail::__ptr, __detail::__ref) (__detail::__cat, __detail::__diff): Move to class scope in the relevant __iterator_traits specializations. (__iterator_traits<>): Use nested class templates instead of ones from namespace __detail. * include/bits/stl_iterator.h (__detail::__common_iter_ptr): Move to class scope in iterator_traits>. (iterator_traits>): Use nested class template instead of __detail::__common_iter_ptr. --- diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 31b58408fe9..e56abe2be6c 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -320,84 +320,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>; - - // FIXME: These have to be at namespace-scope because of PR 92103. - template - struct __ptr - { using type = void; }; - - template requires requires { typename _Iter::pointer; } - struct __ptr<_Iter, true> - { using type = typename _Iter::pointer; }; - - template requires requires { typename _Iter::pointer; } - struct __ptr<_Iter, false> - { using type = typename _Iter::pointer; }; - - template - requires (!requires { typename _Iter::pointer; } - && requires(_Iter& __it) { __it.operator->(); }) - struct __ptr<_Iter, true> - { using type = decltype(std::declval<_Iter&>().operator->()); }; - - template - struct __ref - { using type = iter_reference_t<_Iter>; }; - - template requires requires { typename _Iter::reference; } - struct __ref<_Iter> - { using type = typename _Iter::reference; }; - - template - struct __cat - { using type = input_iterator_tag; }; - - template - requires requires { typename _Iter::iterator_category; } - struct __cat<_Iter> - { using type = typename _Iter::iterator_category; }; - - template - requires (!requires { typename _Iter::iterator_category; } - && __detail::__cpp17_randacc_iterator<_Iter>) - struct __cat<_Iter> - { using type = random_access_iterator_tag; }; - - template - requires (!requires { typename _Iter::iterator_category; } - && __detail::__cpp17_bidi_iterator<_Iter>) - struct __cat<_Iter> - { using type = bidirectional_iterator_tag; }; - - template - requires (!requires { typename _Iter::iterator_category; } - && __detail::__cpp17_fwd_iterator<_Iter>) - struct __cat<_Iter> - { using type = forward_iterator_tag; }; - - template - struct __diff - { using type = void; }; - - template - requires requires { - typename incrementable_traits<_Iter>::difference_type; - } - struct __diff<_Iter> - { - using type = typename incrementable_traits<_Iter>::difference_type; - }; - } // namespace __detail template requires __detail::__iter_with_nested_types<_Iterator> struct __iterator_traits<_Iterator, void> { + private: + template + struct __ptr + { using type = void; }; + + template requires requires { typename _Iter::pointer; } + struct __ptr<_Iter> + { using type = typename _Iter::pointer; }; + + public: using iterator_category = typename _Iterator::iterator_category; using value_type = typename _Iterator::value_type; using difference_type = typename _Iterator::difference_type; - using pointer = typename __detail::__ptr<_Iterator>::type; + using pointer = typename __ptr<_Iterator>::type; using reference = typename _Iterator::reference; }; @@ -406,13 +348,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __detail::__cpp17_input_iterator<_Iterator> struct __iterator_traits<_Iterator, void> { - using iterator_category = typename __detail::__cat<_Iterator>::type; + private: + template + struct __cat + { using type = input_iterator_tag; }; + + template + requires requires { typename _Iter::iterator_category; } + struct __cat<_Iter> + { using type = typename _Iter::iterator_category; }; + + template + requires (!requires { typename _Iter::iterator_category; } + && __detail::__cpp17_randacc_iterator<_Iter>) + struct __cat<_Iter> + { using type = random_access_iterator_tag; }; + + template + requires (!requires { typename _Iter::iterator_category; } + && __detail::__cpp17_bidi_iterator<_Iter>) + struct __cat<_Iter> + { using type = bidirectional_iterator_tag; }; + + template + requires (!requires { typename _Iter::iterator_category; } + && __detail::__cpp17_fwd_iterator<_Iter>) + struct __cat<_Iter> + { using type = forward_iterator_tag; }; + + template + struct __ptr + { using type = void; }; + + template requires requires { typename _Iter::pointer; } + struct __ptr<_Iter> + { using type = typename _Iter::pointer; }; + + template + requires (!requires { typename _Iter::pointer; } + && requires(_Iter& __it) { __it.operator->(); }) + struct __ptr<_Iter> + { using type = decltype(std::declval<_Iter&>().operator->()); }; + + template + struct __ref + { using type = iter_reference_t<_Iter>; }; + + template requires requires { typename _Iter::reference; } + struct __ref<_Iter> + { using type = typename _Iter::reference; }; + + public: + using iterator_category = typename __cat<_Iterator>::type; using value_type = typename indirectly_readable_traits<_Iterator>::value_type; using difference_type = typename incrementable_traits<_Iterator>::difference_type; - using pointer = typename __detail::__ptr<_Iterator, true>::type; - using reference = typename __detail::__ref<_Iterator>::type; + using pointer = typename __ptr<_Iterator>::type; + using reference = typename __ref<_Iterator>::type; }; template @@ -420,9 +413,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __detail::__cpp17_iterator<_Iterator> struct __iterator_traits<_Iterator, void> { + private: + template + struct __diff + { using type = void; }; + + template + requires requires + { typename incrementable_traits<_Iter>::difference_type; } + struct __diff<_Iter> + { + using type = typename incrementable_traits<_Iter>::difference_type; + }; + + public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = typename __detail::__diff<_Iterator>::type; + using difference_type = typename __diff<_Iterator>::type; using pointer = void; using reference = void; }; diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index b0f45499aec..72907813bf5 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1903,29 +1903,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using difference_type = iter_difference_t<_It>; }; - namespace __detail - { - // FIXME: This has to be at namespace-scope because of PR 92103. - template - struct __common_iter_ptr - { - using type = void; - }; - - template - requires __detail::__common_iter_has_arrow<_It> - struct __common_iter_ptr<_It, _Sent> - { - using common_iterator = std::common_iterator<_It, _Sent>; - - using type - = decltype(std::declval().operator->()); - }; - } // namespace __detail - template struct iterator_traits> { + private: + template + struct __ptr + { + using type = void; + }; + + template + requires __detail::__common_iter_has_arrow<_Iter> + struct __ptr<_Iter> + { + using _CIter = common_iterator<_Iter, _Sent>; + using type = decltype(std::declval().operator->()); + }; + + public: using iterator_concept = conditional_t, forward_iterator_tag, input_iterator_tag>; using iterator_category = __detail::__clamp_iter_cat< @@ -1933,7 +1929,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION forward_iterator_tag, input_iterator_tag>; using value_type = iter_value_t<_It>; using difference_type = iter_difference_t<_It>; - using pointer = typename __detail::__common_iter_ptr<_It, _Sent>::type; + using pointer = typename __ptr<_It>::type; using reference = iter_reference_t<_It>; };