Message ID | YMjxJMSLuAx03qVU@redhat.com |
---|---|
State | New |
Headers | show |
Series | [committed] libstdc++: Use function object for __decay_copy helper | expand |
On Tue, 15 Jun 2021 at 19:28, Jonathan Wakely wrote: > > By changing __cust_access::__decay_copy from a function template to a > function object we avoid ADL. That means it's fine to call it > unqualified (the compiler won't waste time doing ADL in associated > namespaces, and won't try to complete associated types). > > This also makes some other minor simplications to other concepts for the > [range.access] CPOs. > > Signed-off-by: Jonathan Wakely <jwakely@redhat.com> > > libstdc++-v3/ChangeLog: > > * include/bits/iterator_concepts.h (__cust_access::__decay_copy): > Replace with function object. > (__cust_access::__member_begin, ___cust_access::_adl_begin): Use > __decay_copy unqualified. > * include/bits/ranges_base.h (__member_end, __adl_end): > Likewise. Use __range_iter_t for type of ranges::begin. > (__member_rend): Use correct value category for rbegin argument. > (__member_data): Use __decay_copy unqualified. > (__begin_data): Use __range_iter_t for type of ranges::begin. That change makes it impossible to import the header in a module. Fixed by this patch. Tested powerpc64le-linux. Pushed to trunk. commit c25e3bf87975280a603ff18fba387c6707ce4a95 Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Jun 16 12:47:32 2021 libstdc++: Use named struct for __decay_copy In r12-1486-gcb326a6442f09cb36b05ce556fc91e10bfeb0cf6 I changed __decay_copy to be a function object of unnamed class type. This causes problems when importing the library headers: error: conflicting global module declaration 'constexpr const std::ranges::__cust_access::<unnamed struct> std::ranges::__cust_access::__decay_copy' The fix is to use a named struct instead of an anonymous one. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/bits/iterator_concepts.h (__decay_copy): Name type. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index d18ae32bf20..11748e5ed7b 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -930,7 +930,8 @@ namespace ranges { using std::__detail::__class_or_enum; - struct { + struct _Decay_copy final + { template<typename _Tp> constexpr decay_t<_Tp> operator()(_Tp&& __t) const
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 8723f35c5cb..d18ae32bf20 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -930,17 +930,18 @@ namespace ranges { using std::__detail::__class_or_enum; - template<typename _Tp> - constexpr decay_t<_Tp> - __decay_copy(_Tp&& __t) - noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>) - { return std::forward<_Tp>(__t); } + struct { + template<typename _Tp> + constexpr decay_t<_Tp> + operator()(_Tp&& __t) const + noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>) + { return std::forward<_Tp>(__t); } + } inline constexpr __decay_copy{}; template<typename _Tp> concept __member_begin = requires(_Tp& __t) { - { __cust_access::__decay_copy(__t.begin()) } - -> input_or_output_iterator; + { __decay_copy(__t.begin()) } -> input_or_output_iterator; }; // Poison pills so that unqualified lookup doesn't find std::begin. @@ -951,8 +952,7 @@ namespace ranges concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>> && requires(_Tp& __t) { - { __cust_access::__decay_copy(begin(__t)) } - -> input_or_output_iterator; + { __decay_copy(begin(__t)) } -> input_or_output_iterator; }; // Simplified version of std::ranges::begin that only supports lvalues, diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 3bc657ca17e..a63ef8eb7f4 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -89,6 +89,7 @@ namespace ranges namespace __cust_access { using std::ranges::__detail::__maybe_borrowed_range; + using std::__detail::__range_iter_t; struct _Begin { @@ -127,8 +128,7 @@ namespace ranges template<typename _Tp> concept __member_end = requires(_Tp& __t) { - { __decay_copy(__t.end()) } - -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>; + { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>; }; // Poison pills so that unqualified lookup doesn't find std::end. @@ -139,8 +139,7 @@ namespace ranges concept __adl_end = __class_or_enum<remove_reference_t<_Tp>> && requires(_Tp& __t) { - { __decay_copy(end(__t)) } - -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>; + { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>; }; struct _End @@ -281,7 +280,7 @@ namespace ranges concept __member_rend = requires(_Tp& __t) { { __decay_copy(__t.rend()) } - -> sentinel_for<decltype(_RBegin{}(__t))>; + -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>; }; void rend(auto&) = delete; @@ -507,12 +506,11 @@ namespace ranges template<typename _Tp> concept __member_data = requires(_Tp& __t) { - { __cust_access::__decay_copy(__t.data()) } -> __pointer_to_object; + { __decay_copy(__t.data()) } -> __pointer_to_object; }; template<typename _Tp> - concept __begin_data = requires(_Tp& __t) - { { _Begin{}(__t) } -> contiguous_iterator; }; + concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>; struct _Data {