public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1489] libstdc++: Make ranges CPOs final and not addressable
@ 2021-06-15 18:27 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-06-15 18:27 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:8b93548778a487f31f21e0c6afe7e0bde9711fc4

commit r12-1489-g8b93548778a487f31f21e0c6afe7e0bde9711fc4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jun 15 17:54:53 2021 +0100

    libstdc++: Make ranges CPOs final and not addressable
    
    This restricts the API of the CPOs and other function objects so they
    cannot be misused by deriving from them or taking their addresses.
    
    Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/ranges_base.h (ranges::begin, ranges::end)
            (ranges::cbegin, ranges::cend, ranges::rbeing, ranges::rend)
            (ranges::crbegin, ranges::crend, ranges::size, ranges::ssize)
            (ranges::empty, ranges::data, ranges::cdata): Make types final.
            Add deleted operator& overloads.
            (ranges::advance, ranges::distance, ranges::next, ranges::prev):
            Likewise.
            * testsuite/std/ranges/headers/ranges/synopsis.cc: Replace
            ill-formed & expressions with using-declarations. Add checks for
            other function objects.

Diff:
---
 libstdc++-v3/include/bits/ranges_base.h            | 68 ++++++++++++++++------
 .../std/ranges/headers/ranges/synopsis.cc          | 26 ++++++---
 2 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index a63ef8eb7f4..e392c370fcd 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -91,7 +91,7 @@ namespace ranges
     using std::ranges::__detail::__maybe_borrowed_range;
     using std::__detail::__range_iter_t;
 
-    struct _Begin
+    struct _Begin final
     {
     private:
       template<typename _Tp>
@@ -106,6 +106,8 @@ namespace ranges
 	    return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
 	}
 
+      void operator&() const = delete;
+
     public:
       template<__maybe_borrowed_range _Tp>
 	requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
@@ -142,7 +144,7 @@ namespace ranges
 	  { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>;
 	};
 
-    struct _End
+    struct _End final
     {
     private:
       template<typename _Tp>
@@ -157,6 +159,8 @@ namespace ranges
 	    return noexcept(__decay_copy(end(std::declval<_Tp&>())));
 	}
 
+      void operator&() const = delete;
+
     public:
       template<__maybe_borrowed_range _Tp>
 	requires is_bounded_array_v<remove_reference_t<_Tp>>
@@ -189,7 +193,7 @@ namespace ranges
 	  return static_cast<const _Tp&&>(__t);
       }
 
-    struct _CBegin
+    struct _CBegin final
     {
       template<typename _Tp>
 	constexpr auto
@@ -199,9 +203,11 @@ namespace ranges
 	{
 	  return _Begin{}(__cust_access::__as_const<_Tp>(__e));
 	}
+
+      void operator&() const = delete;
     };
 
-    struct _CEnd
+    struct _CEnd final
     {
       template<typename _Tp>
 	constexpr auto
@@ -211,6 +217,8 @@ namespace ranges
 	{
 	  return _End{}(__cust_access::__as_const<_Tp>(__e));
 	}
+
+      void operator&() const = delete;
     };
 
     template<typename _Tp>
@@ -236,7 +244,7 @@ namespace ranges
 	  { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
 	};
 
-    struct _RBegin
+    struct _RBegin final
     {
     private:
       template<typename _Tp>
@@ -260,6 +268,8 @@ namespace ranges
 	    }
 	}
 
+      void operator&() const = delete;
+
     public:
       template<__maybe_borrowed_range _Tp>
 	requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
@@ -294,7 +304,7 @@ namespace ranges
 	    -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
 	};
 
-    struct _REnd
+    struct _REnd final
     {
     private:
       template<typename _Tp>
@@ -318,6 +328,8 @@ namespace ranges
 	    }
 	}
 
+      void operator&() const = delete;
+
     public:
       template<__maybe_borrowed_range _Tp>
 	requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
@@ -334,7 +346,7 @@ namespace ranges
 	}
     };
 
-    struct _CRBegin
+    struct _CRBegin final
     {
       template<typename _Tp>
 	constexpr auto
@@ -344,9 +356,11 @@ namespace ranges
 	{
 	  return _RBegin{}(__cust_access::__as_const<_Tp>(__e));
 	}
+
+      void operator&() const = delete;
     };
 
-    struct _CREnd
+    struct _CREnd final
     {
       template<typename _Tp>
 	constexpr auto
@@ -356,6 +370,8 @@ namespace ranges
 	{
 	  return _REnd{}(__cust_access::__as_const<_Tp>(__e));
 	}
+
+      void operator&() const = delete;
     };
 
     template<typename _Tp>
@@ -386,7 +402,7 @@ namespace ranges
 	  __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
 	};
 
-    struct _Size
+    struct _Size final
     {
     private:
       template<typename _Tp>
@@ -404,6 +420,8 @@ namespace ranges
 			    - _Begin{}(std::declval<_Tp&>()));
 	}
 
+      void operator&() const = delete;
+
     public:
       template<typename _Tp>
 	requires is_bounded_array_v<remove_reference_t<_Tp>>
@@ -422,7 +440,7 @@ namespace ranges
 	}
     };
 
-    struct _SSize
+    struct _SSize final
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E)
@@ -451,6 +469,8 @@ namespace ranges
 	  else // Must be one of __max_diff_type or __max_size_type.
 	    return __detail::__max_diff_type(__size);
 	}
+
+      void operator&() const = delete;
     };
 
     template<typename _Tp>
@@ -467,7 +487,7 @@ namespace ranges
 	  bool(_Begin{}(__t) == _End{}(__t));
 	};
 
-    struct _Empty
+    struct _Empty final
     {
     private:
       template<typename _Tp>
@@ -483,6 +503,8 @@ namespace ranges
 		== _End{}(std::declval<_Tp&>())));
 	}
 
+      void operator&() const = delete;
+
     public:
       template<typename _Tp>
 	requires __member_empty<_Tp> || __size0_empty<_Tp>
@@ -512,7 +534,7 @@ namespace ranges
     template<typename _Tp>
       concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;
 
-    struct _Data
+    struct _Data final
     {
     private:
       template<typename _Tp>
@@ -525,6 +547,8 @@ namespace ranges
 	    return noexcept(_Begin{}(std::declval<_Tp&>()));
 	}
 
+      void operator&() const = delete;
+
     public:
       template<__maybe_borrowed_range _Tp>
 	requires __member_data<_Tp> || __begin_data<_Tp>
@@ -538,7 +562,7 @@ namespace ranges
 	}
     };
 
-    struct _CData
+    struct _CData final
     {
       template<typename _Tp>
 	constexpr auto
@@ -548,6 +572,8 @@ namespace ranges
 	{
 	  return _Data{}(__cust_access::__as_const<_Tp>(__e));
 	}
+
+      void operator&() const = delete;
     };
 
   } // namespace __cust_access
@@ -669,7 +695,7 @@ namespace ranges
 
   // [range.iter.ops] range iterator operations
 
-  struct __advance_fn
+  struct __advance_fn final
   {
     template<input_or_output_iterator _It>
       constexpr void
@@ -774,11 +800,13 @@ namespace ranges
 	    return __n;
 	  }
       }
+
+    void operator&() const = delete;
   };
 
   inline constexpr __advance_fn advance{};
 
-  struct __distance_fn
+  struct __distance_fn final
   {
     template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
       constexpr iter_difference_t<_It>
@@ -807,11 +835,13 @@ namespace ranges
 	else
 	  return (*this)(ranges::begin(__r), ranges::end(__r));
       }
+
+    void operator&() const = delete;
   };
 
   inline constexpr __distance_fn distance{};
 
-  struct __next_fn
+  struct __next_fn final
   {
     template<input_or_output_iterator _It>
       constexpr _It
@@ -844,11 +874,13 @@ namespace ranges
 	ranges::advance(__x, __n, __bound);
 	return __x;
       }
+
+    void operator&() const = delete;
   };
 
   inline constexpr __next_fn next{};
 
-  struct __prev_fn
+  struct __prev_fn final
   {
     template<bidirectional_iterator _It>
       constexpr _It
@@ -873,6 +905,8 @@ namespace ranges
 	ranges::advance(__x, -__n, __bound);
 	return __x;
       }
+
+    void operator&() const = delete;
   };
 
   inline constexpr __prev_fn prev{};
diff --git a/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc
index 115b157fd6c..ea26b505678 100644
--- a/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc
+++ b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc
@@ -33,12 +33,22 @@ namespace __gnu_test
 {
   constexpr const bool* disable_sized_range
     = &std::ranges::disable_sized_range<void>;
-  constexpr auto* begin = &std::ranges::begin;
-  constexpr auto* end = &std::ranges::end;
-  constexpr auto* cbegin = &std::ranges::cbegin;
-  constexpr auto* cend = &std::ranges::cend;
-  constexpr auto* rbegin = &std::ranges::rbegin;
-  constexpr auto* rend = &std::ranges::rend;
-  constexpr auto* crbegin = &std::ranges::crbegin;
-  constexpr auto* crend = &std::ranges::crend;
+  using std::ranges::begin;
+  using std::ranges::end;
+  using std::ranges::cbegin;
+  using std::ranges::cend;
+  using std::ranges::rbegin;
+  using std::ranges::rend;
+  using std::ranges::crbegin;
+  using std::ranges::crend;
+  using std::ranges::size;
+  using std::ranges::ssize;
+  using std::ranges::empty;
+  using std::ranges::data;
+  using std::ranges::cdata;
+
+  using std::ranges::advance;
+  using std::ranges::distance;
+  using std::ranges::next;
+  using std::ranges::prev;
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-15 18:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-15 18:27 [gcc r12-1489] libstdc++: Make ranges CPOs final and not addressable Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).