]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Make all experimental::observer_ptr functions constexpr
authorJonathan Wakely <jwakely@redhat.com>
Mon, 14 Jul 2025 10:11:28 +0000 (11:11 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 15 Jul 2025 09:25:43 +0000 (10:25 +0100)
I've just created LWG 4295 proposing this change, and am implementing it
via this patch.

libstdc++-v3/ChangeLog:

* include/experimental/memory (swap, make_observer_ptr): Add
constexpr.
(operator==, operator!=, operator<, operator>, operator<=)
(operator>=): Likewise.
* testsuite/experimental/memory/observer_ptr/make_observer.cc:
Checks for constant evaluation.
* testsuite/experimental/memory/observer_ptr/relops/relops.cc:
Likewise.
* testsuite/experimental/memory/observer_ptr/swap/swap.cc:
Likewise.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
libstdc++-v3/include/experimental/memory
libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc
libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc
libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc

index 131e5acc03d950627913daf45c901c869fbd9c10..1b01462e1b268899ab7d6477220e4bdaa10ec2c0 100644 (file)
@@ -148,42 +148,42 @@ inline namespace fundamentals_v2
     }; // observer_ptr<>
 
   template<typename _Tp>
-    void
+    constexpr void
     swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
     {
       __p1.swap(__p2);
     }
 
   template<typename _Tp>
-    observer_ptr<_Tp>
+    constexpr observer_ptr<_Tp>
     make_observer(_Tp* __p) noexcept
     {
       return observer_ptr<_Tp>(__p);
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
       return __p1.get() == __p2.get();
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
     return !(__p1 == __p2);
     }
 
   template<typename _Tp>
-    bool
+    constexpr bool
     operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
     {
       return !__p;
     }
 
   template<typename _Tp>
-    bool
+    constexpr bool
     operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
     {
       return !__p;
@@ -197,14 +197,14 @@ inline namespace fundamentals_v2
     }
 
   template<typename _Tp>
-    bool
+    constexpr bool
     operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
     {
       return bool(__p);
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
       return std::less<typename common_type<typename add_pointer<_Tp>::type,
@@ -214,21 +214,21 @@ inline namespace fundamentals_v2
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
       return __p2 < __p1;
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
       return !(__p2 < __p1);
     }
 
   template<typename _Tp, typename _Up>
-    bool
+    constexpr bool
     operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
     {
       return !(__p1 < __p2);
index 048735ff63ae9a82de9768cc86dde34d407f162b..1de9cf0950921d7f25be1d348d20e06ba0597bb4 100644 (file)
 #include <experimental/memory>
 #include <testsuite_hooks.h>
 
-int main()
+constexpr bool test()
 {
   const int i = 42;
   auto o = std::experimental::make_observer(&i);
   static_assert( std::is_same<decltype(o),
-                 std::experimental::observer_ptr<const int>>(), "" );
+                  std::experimental::observer_ptr<const int>>(), "" );
   VERIFY( o && *o == 42 );
   VERIFY( o.get() == &i );
+  return true;
+}
+
+int main()
+{
+  test();
+  static_assert( test(), "LWG 4295 - make_observer should be constexpr" );
 }
index 3e23e0b452be94cf63e0f41a79832e0dde4044f9..d03dd5dcbd80ba2c190eef97bc71845131c58967 100644 (file)
 
 using std::experimental::observer_ptr;
 
-void test01()
+constexpr void test01()
 {
   observer_ptr<int> a, b;
   VERIFY(a == b);
 }
 
-void test02()
+constexpr void test02()
 {
   int x[2]{};
   observer_ptr<int> a{&x[0]};
@@ -40,7 +40,7 @@ void test02()
   VERIFY(b > a);
 }
 
-void test03()
+constexpr void test03()
 {
   int x{};
   observer_ptr<int> a{&x};
@@ -48,9 +48,10 @@ void test03()
   VERIFY(a == b);
 }
 
-void test04()
+int x[2]{};
+
+constexpr void test04()
 {
-  static constexpr int x[2]{};
   constexpr observer_ptr<const int> a{&x[0]};
   constexpr observer_ptr<const int> b{&x[1]};
   VERIFY(a != b);
@@ -60,20 +61,25 @@ void test04()
   VERIFY(b > a);
 }
 
-void test05()
+constexpr void test05()
 {
-  static constexpr int x{};
-  constexpr observer_ptr<const int> a{&x};
-  constexpr observer_ptr<const int> b{&x};
+  constexpr observer_ptr<const int> a{&x[0]};
+  constexpr observer_ptr<const int> b{&x[0]};
   VERIFY(a == b);
 }
 
-
-int main()
+constexpr bool all_tests()
 {
   test01();
   test02();
   test03();
   test04();
   test05();
+  return true;
+}
+
+int main()
+{
+  all_tests();
+  static_assert( all_tests(), "LWG 4295 - relops should be constexpr" );
 }
index 9e76788635126ba659feda2d2d2e7a0bfbaf3368..84b8844af34d6e3aeff6a57947898c5bf2c51ab6 100644 (file)
@@ -25,7 +25,7 @@ using std::experimental::observer_ptr;
 struct B {};
 struct D : B {};
 
-void test01()
+constexpr void test01()
 {
   observer_ptr<int> a, b;
   VERIFY(a == b);
@@ -33,7 +33,7 @@ void test01()
   VERIFY(a == b);
 }
 
-void test02()
+constexpr void test02()
 {
   int x{};
   observer_ptr<int> a;
@@ -45,7 +45,7 @@ void test02()
   VERIFY(!b);
 }
 
-void test03()
+constexpr void test03()
 {
   int x[2]{1,2};
   observer_ptr<int> a{&x[0]};
@@ -57,10 +57,16 @@ void test03()
   VERIFY(*b == 1);
 }
 
-
 int main()
 {
-  test01();
-  test02();
-  test03();
+  auto tests = [] {
+    test01();
+    test02();
+    test03();
+    return true;
+  };
+  tests();
+#if __cpp_lib_constexpr_algorithms >= 201806L // >= C++20
+  static_assert( tests(), "LWG 4295 - swap should be constexpr" );
+#endif
 }