GCC 16.1's explicit specialization of std::allocator_traits on
std::pmr::polymorphic_allocator<T> lacks the required
definition of allocate_at_least. This patch provides it, and
tests for its presence in C++23 and up.
libstdc++-v3/Changelog:
PR libstdc++/125890
* include/bits/memory_resource.h (allocate_at_least): Add to
allocator_traits<pmr::polymorphic_allocator> specialization.
* testsuite/20_util/polymorphic_allocator/at_least.cc: New test.
---
libstdc++-v3/include/bits/memory_resource.h | 17 +++++++++++++
.../20_util/polymorphic_allocator/at_least.cc | 25 +++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644
libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
diff --git a/libstdc++-v3/include/bits/memory_resource.h
b/libstdc++-v3/include/bits/memory_resource.h
index e5c6697b07e..a9db58b76a3 100644
--- a/libstdc++-v3/include/bits/memory_resource.h
+++ b/libstdc++-v3/include/bits/memory_resource.h
@@ -48,6 +48,7 @@
# include <bits/utility.h> // index_sequence
# include <tuple> // tuple, forward_as_tuple
#endif
+#include <bits/memoryfwd.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -468,6 +469,22 @@ namespace pmr
allocate(allocator_type& __a, size_type __n, const_void_pointer)
{ return __a.allocate(__n); }
+#ifdef __glibcxx_allocate_at_least
+ /**
+ * @brief Allocate memory.
+ * @param __a An allocator.
+ * @param __n The number of objects to allocate space for.
+ * @return Memory of suitable size and alignment for `n` objects
+ * of type `value_type`.
+ *
+ * Just returns `{ a.allocate(n), n }`: `polymorphic_allocator`
+ * cannot be extended without breaking ABI.
+ */
+ [[nodiscard]] static std::allocation_result<pointer, size_type>
+ allocate_at_least(allocator_type& __a, size_type __n)
+ { return { __a.allocate(__n), __n }; }
+#endif
+
/**
* @brief Deallocate memory.
* @param __a An allocator.
diff --git a/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
new file mode 100644
index 00000000000..2910807d030
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
@@ -0,0 +1,25 @@
+// { dg-do run { target c++23 } }
+
+#include <memory_resource>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void
+alloc_at_least()
+{
+ struct A { char a; };
+ using alloc_A = std::pmr::polymorphic_allocator<A>;
+ using traits_A = std::allocator_traits<alloc_A>;
+ alloc_A alloc_a;
+ // This just forwards to alloc_a::allocate:
+ std::allocation_result result = traits_A::allocate_at_least(alloc_a, 1);
+ VERIFY(result.count == 1);
+ VERIFY(result.ptr != nullptr);
+ auto [pointer, count] = result;
+ traits_A::deallocate(alloc_a, pointer, count);
+}
+
+int main()
+{
+ alloc_at_least();
+}
--
2.54.0