[gcc r11-8760] libstdc++: Use function object for __decay_copy helper

Jonathan Wakely redi@gcc.gnu.org
Fri Jul 16 13:15:05 GMT 2021


https://gcc.gnu.org/g:419201f566bbc1359de669ba693d7628c247e7c8

commit r11-8760-g419201f566bbc1359de669ba693d7628c247e7c8
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jun 15 14:39:02 2021 +0100

    libstdc++: Use function object for __decay_copy helper
    
    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.
    
    (cherry picked from commit cb326a6442f09cb36b05ce556fc91e10bfeb0cf6)

Diff:
---
 libstdc++-v3/include/bits/iterator_concepts.h | 19 ++++++++++---------
 libstdc++-v3/include/bits/ranges_base.h       | 14 ++++++--------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index f4e94a6263b..ccc0a19dafd 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -930,17 +930,19 @@ 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 _Decay_copy final
+    {
+      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 +953,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
     {


More information about the Libstdc++-cvs mailing list