]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Make __gnu_test::default_init_allocator usable in constexpr
authorJonathan Wakely <jwakely@redhat.com>
Thu, 1 May 2025 21:41:40 +0000 (22:41 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 2 May 2025 10:53:22 +0000 (11:53 +0100)
If we make this test allocator usable in constant expressions then we'll
get an error if the 'state' data member isn't initialized. This makes it
a more reliable check that allocators are correctly value-initialized
when they're required to be.

libstdc++-v3/ChangeLog:

* testsuite/23_containers/vector/allocator/default_init.cc:
Add a check using constant evaluation.
* testsuite/23_containers/vector/bool/allocator/default_init.cc:
Likewise.
* testsuite/util/testsuite_allocator.h (default_init_allocator):
Make all member functions and equality ops constexpr.

libstdc++-v3/testsuite/23_containers/vector/allocator/default_init.cc
libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc
libstdc++-v3/testsuite/util/testsuite_allocator.h

index 195cd2dca544fe766472bade717f4e3a75e560fa..486c44c9699dfaae196709d28fd8d68b88be860c 100644 (file)
@@ -59,6 +59,17 @@ void test02()
   tmp->~test_type();
 }
 
+#ifdef __cpp_lib_constexpr_vector
+constexpr bool
+test03()
+{
+  using alloc_type = default_init_allocator<T>;
+  std::vector<T, alloc_type> v;
+  return v.get_allocator().state == 0;
+}
+static_assert( test03() );
+#endif
+
 int main()
 {
   test01();
index 3914b7fe6c3ac37c18d59691d223af89527b5c4b..c95cb6ba99f316fe64db2f85fc36b160962ede0d 100644 (file)
@@ -59,6 +59,17 @@ void test02()
   tmp->~test_type();
 }
 
+#ifdef __cpp_lib_constexpr_vector
+constexpr bool
+test03()
+{
+  using alloc_type = default_init_allocator<T>;
+  std::vector<T, alloc_type> v;
+  return v.get_allocator().state == 0;
+}
+static_assert( test03() );
+#endif
+
 int main()
 {
   test01();
index be596bf00fb41fec5278453c768de09ee1f366a8..e5ffad2ba5875de9bed447903c62083bcb5c9089 100644 (file)
@@ -541,15 +541,16 @@ namespace __gnu_test
       default_init_allocator() = default;
 
       template<typename U>
+       constexpr
         default_init_allocator(const default_init_allocator<U>& a)
          : state(a.state)
         { }
 
-      T*
+      constexpr T*
       allocate(std::size_t n)
       { return std::allocator<T>().allocate(n); }
 
-      void
+      constexpr void
       deallocate(T* p, std::size_t n)
       { std::allocator<T>().deallocate(p, n); }
 
@@ -557,15 +558,17 @@ namespace __gnu_test
     };
 
   template<typename T, typename U>
-    bool operator==(const default_init_allocator<T>& t,
-                   const default_init_allocator<U>& u)
+    constexpr bool
+    operator==(const default_init_allocator<T>& t,
+              const default_init_allocator<U>& u)
     { return t.state == u.state; }
 
   template<typename T, typename U>
-    bool operator!=(const default_init_allocator<T>& t,
-                   const default_init_allocator<U>& u)
+    constexpr bool
+    operator!=(const default_init_allocator<T>& t,
+              const default_init_allocator<U>& u)
     { return !(t == u); }
-#endif
+#endif // C++11
 
   template<typename Tp>
     struct ExplicitConsAlloc : std::allocator<Tp>