aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2022-05-19 23:38:23 +0100
committerJonathan Wakely <jwakely@redhat.com>2022-05-19 23:38:23 +0100
commit8ccdc7ce33f5e7ca509e5b9f835ed4719db21ffd (patch)
tree35b201acf391285912ba2ad28de5baff3c197b13
parentd863ba23fb16122bb0547b0c678173be0d98f43c (diff)
libstdc++: Ensure pmr aliases work without <memory_resource>
Currently the alias templates for std::pmr::vector, std::pmr::string etc. are defined using a forward declaration for polymorphic_allocator. This means you can't actually use the alias templates unless you also include <memory_resource>. The rationale for that is that it's a fairly large header, and most users don't need it. This isn't uncontroversial though, and LWG 3681 questions whether it's even conforming. This change adds a new <bits/memory_resource.h> header with the minimum needed to use polymorphic_allocator and the std::pmr container aliases. Including <memory_resource> is still necessary to use the program-wide resource objects, or the pool resources or monotonic buffer resource. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/memory_resource.h: New file. * include/std/deque: Include <bits/memory_resource.h>. * include/std/forward_list: Likewise. * include/std/list: Likewise. * include/std/map: Likewise. * include/std/memory_resource (pmr::memory_resource): Move to new <bits/memory_resource.h> header. (pmr::polymorphic_allocator): Likewise. * include/std/regex: Likewise. * include/std/set: Likewise. * include/std/stacktrace: Likewise. * include/std/string: Likewise. * include/std/unordered_map: Likewise. * include/std/unordered_set: Likewise. * include/std/vector: Likewise. * testsuite/21_strings/basic_string/types/pmr_typedefs.cc: Remove <memory_resource> header and check construction. * testsuite/23_containers/deque/types/pmr_typedefs.cc: Likewise. * testsuite/23_containers/forward_list/pmr_typedefs.cc: Likewise. * testsuite/23_containers/list/pmr_typedefs.cc: Likewise. * testsuite/23_containers/map/pmr_typedefs.cc: Likewise. * testsuite/23_containers/multimap/pmr_typedefs.cc: Likewise. * testsuite/23_containers/multiset/pmr_typedefs.cc: Likewise. * testsuite/23_containers/set/pmr_typedefs.cc: Likewise. * testsuite/23_containers/unordered_map/pmr_typedefs.cc: Likewise. * testsuite/23_containers/unordered_multimap/pmr_typedefs.cc: Likewise. * testsuite/23_containers/unordered_multiset/pmr_typedefs.cc: Likewise. * testsuite/23_containers/unordered_set/pmr_typedefs.cc: Likewise. * testsuite/23_containers/vector/pmr_typedefs.cc: Likewise. * testsuite/28_regex/match_results/pmr_typedefs.cc: Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/variadic-tuple.C: Qualify function to avoid ADL finding std::make_tuple.
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C2
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/memory_resource.h507
-rw-r--r--libstdc++-v3/include/std/deque2
-rw-r--r--libstdc++-v3/include/std/forward_list2
-rw-r--r--libstdc++-v3/include/std/list2
-rw-r--r--libstdc++-v3/include/std/map2
-rw-r--r--libstdc++-v3/include/std/memory_resource464
-rw-r--r--libstdc++-v3/include/std/regex2
-rw-r--r--libstdc++-v3/include/std/set2
-rw-r--r--libstdc++-v3/include/std/stacktrace2
-rw-r--r--libstdc++-v3/include/std/string2
-rw-r--r--libstdc++-v3/include/std/unordered_map2
-rw-r--r--libstdc++-v3/include/std/unordered_set2
-rw-r--r--libstdc++-v3/include/std/vector2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc3
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc3
30 files changed, 551 insertions, 488 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
index b1c6b3d7814..e2699d94ebf 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
@@ -272,7 +272,7 @@ int main()
// t3a = t3b; DPG: triggers an error, as it should.
tuple<int, float, std::string> t3c =
- make_tuple(17, 2.718281828, std::string("Fun"));
+ ::make_tuple(17, 2.718281828, std::string("Fun"));
int seventeen = 17;
double pi = 3.14159;
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 77eea7d61e8..b46def7ff9f 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -157,6 +157,7 @@ bits_headers = \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
${bits_srcdir}/max_size_type.h \
+ ${bits_srcdir}/memory_resource.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/mofunc_impl.h \
${bits_srcdir}/move.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 01bf3e0eb32..f844008a7c5 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -515,6 +515,7 @@ bits_headers = \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
${bits_srcdir}/max_size_type.h \
+ ${bits_srcdir}/memory_resource.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/mofunc_impl.h \
${bits_srcdir}/move.h \
diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h
new file mode 100644
index 00000000000..d8c7e168235
--- /dev/null
+++ b/libstdc++-v3/include/bits/memory_resource.h
@@ -0,0 +1,507 @@
+// <memory_resource> -*- C++ -*-
+
+// Copyright (C) 2018-2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/memory_resource.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{memory_resource}
+ */
+
+#ifndef _GLIBCXX_MEMORY_RESOURCE_H
+#define _GLIBCXX_MEMORY_RESOURCE_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201703L
+
+#include <new> // operator new(size_t, void*)
+#include <cstddef> // size_t, max_align_t, byte
+#include <bits/functexcept.h> // __throw_bad_array_new_length
+#include <bits/uses_allocator.h> // allocator_arg_t, __use_alloc
+#include <bits/uses_allocator_args.h> // uninitialized_construct_using_alloc
+#include <ext/numeric_traits.h> // __int_traits
+#include <debug/assertions.h>
+
+#if ! __cpp_lib_make_obj_using_allocator
+# include <bits/utility.h> // index_sequence
+# include <tuple> // tuple, forward_as_tuple
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace pmr
+{
+ /// Class memory_resource
+ class memory_resource
+ {
+ static constexpr size_t _S_max_align = alignof(max_align_t);
+
+ public:
+ memory_resource() = default;
+ memory_resource(const memory_resource&) = default;
+ virtual ~memory_resource(); // key function
+
+ memory_resource& operator=(const memory_resource&) = default;
+
+ [[nodiscard]]
+ void*
+ allocate(size_t __bytes, size_t __alignment = _S_max_align)
+ __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
+ { return ::operator new(__bytes, do_allocate(__bytes, __alignment)); }
+
+ void
+ deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
+ __attribute__((__nonnull__))
+ { return do_deallocate(__p, __bytes, __alignment); }
+
+ [[nodiscard]]
+ bool
+ is_equal(const memory_resource& __other) const noexcept
+ { return do_is_equal(__other); }
+
+ private:
+ virtual void*
+ do_allocate(size_t __bytes, size_t __alignment) = 0;
+
+ virtual void
+ do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;
+
+ virtual bool
+ do_is_equal(const memory_resource& __other) const noexcept = 0;
+ };
+
+ [[nodiscard]]
+ inline bool
+ operator==(const memory_resource& __a, const memory_resource& __b) noexcept
+ { return &__a == &__b || __a.is_equal(__b); }
+
+#if __cpp_impl_three_way_comparison < 201907L
+ [[nodiscard]]
+ inline bool
+ operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
+ { return !(__a == __b); }
+#endif
+
+ // C++17 23.12.3 Class template polymorphic_allocator
+ template<typename _Tp>
+ class polymorphic_allocator
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2975. Missing case for pair construction in polymorphic allocators
+ template<typename _Up>
+ struct __not_pair { using type = void; };
+
+ template<typename _Up1, typename _Up2>
+ struct __not_pair<pair<_Up1, _Up2>> { };
+
+ public:
+ using value_type = _Tp;
+
+ polymorphic_allocator() noexcept
+ {
+ extern memory_resource* get_default_resource() noexcept
+ __attribute__((__returns_nonnull__));
+ _M_resource = get_default_resource();
+ }
+
+ polymorphic_allocator(memory_resource* __r) noexcept
+ __attribute__((__nonnull__))
+ : _M_resource(__r)
+ { _GLIBCXX_DEBUG_ASSERT(__r); }
+
+ polymorphic_allocator(const polymorphic_allocator& __other) = default;
+
+ template<typename _Up>
+ polymorphic_allocator(const polymorphic_allocator<_Up>& __x) noexcept
+ : _M_resource(__x.resource())
+ { }
+
+ polymorphic_allocator&
+ operator=(const polymorphic_allocator&) = delete;
+
+ [[nodiscard]]
+ _Tp*
+ allocate(size_t __n)
+ __attribute__((__returns_nonnull__))
+ {
+ if ((__gnu_cxx::__int_traits<size_t>::__max / sizeof(_Tp)) < __n)
+ std::__throw_bad_array_new_length();
+ return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
+ alignof(_Tp)));
+ }
+
+ void
+ deallocate(_Tp* __p, size_t __n) noexcept
+ __attribute__((__nonnull__))
+ { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
+
+#if __cplusplus > 201703L
+ [[nodiscard]] void*
+ allocate_bytes(size_t __nbytes,
+ size_t __alignment = alignof(max_align_t))
+ { return _M_resource->allocate(__nbytes, __alignment); }
+
+ void
+ deallocate_bytes(void* __p, size_t __nbytes,
+ size_t __alignment = alignof(max_align_t))
+ { _M_resource->deallocate(__p, __nbytes, __alignment); }
+
+ template<typename _Up>
+ [[nodiscard]] _Up*
+ allocate_object(size_t __n = 1)
+ {
+ if ((__gnu_cxx::__int_traits<size_t>::__max / sizeof(_Up)) < __n)
+ std::__throw_bad_array_new_length();
+ return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up),
+ alignof(_Up)));
+ }
+
+ template<typename _Up>
+ void
+ deallocate_object(_Up* __p, size_t __n = 1)
+ { deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); }
+
+ template<typename _Up, typename... _CtorArgs>
+ [[nodiscard]] _Up*
+ new_object(_CtorArgs&&... __ctor_args)
+ {
+ _Up* __p = allocate_object<_Up>();
+ __try
+ {
+ construct(__p, std::forward<_CtorArgs>(__ctor_args)...);
+ }
+ __catch (...)
+ {
+ deallocate_object(__p);
+ __throw_exception_again;
+ }
+ return __p;
+ }
+
+ template<typename _Up>
+ void
+ delete_object(_Up* __p)
+ {
+ __p->~_Up();
+ deallocate_object(__p);
+ }
+#endif // C++2a
+
+#if ! __cpp_lib_make_obj_using_allocator
+ template<typename _Tp1, typename... _Args>
+ __attribute__((__nonnull__))
+ typename __not_pair<_Tp1>::type
+ construct(_Tp1* __p, _Args&&... __args)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2969. polymorphic_allocator::construct() shouldn't pass resource()
+ using __use_tag
+ = std::__uses_alloc_t<_Tp1, polymorphic_allocator, _Args...>;
+ if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)
+ ::new(__p) _Tp1(std::forward<_Args>(__args)...);
+ else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)
+ ::new(__p) _Tp1(allocator_arg, *this,
+ std::forward<_Args>(__args)...);
+ else
+ ::new(__p) _Tp1(std::forward<_Args>(__args)..., *this);
+ }
+
+ template<typename _Tp1, typename _Tp2,
+ typename... _Args1, typename... _Args2>
+ __attribute__((__nonnull__))
+ void
+ construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
+ tuple<_Args1...> __x, tuple<_Args2...> __y)
+ {
+ auto __x_tag =
+ __use_alloc<_Tp1, polymorphic_allocator, _Args1...>(*this);
+ auto __y_tag =
+ __use_alloc<_Tp2, polymorphic_allocator, _Args2...>(*this);
+ index_sequence_for<_Args1...> __x_i;
+ index_sequence_for<_Args2...> __y_i;
+
+ ::new(__p) pair<_Tp1, _Tp2>(piecewise_construct,
+ _S_construct_p(__x_tag, __x_i, __x),
+ _S_construct_p(__y_tag, __y_i, __y));
+ }
+
+ template<typename _Tp1, typename _Tp2>
+ __attribute__((__nonnull__))
+ void
+ construct(pair<_Tp1, _Tp2>* __p)
+ { this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
+
+ template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+ __attribute__((__nonnull__))
+ void
+ construct(pair<_Tp1, _Tp2>* __p, _Up&& __x, _Vp&& __y)
+ {
+ this->construct(__p, piecewise_construct,
+ std::forward_as_tuple(std::forward<_Up>(__x)),
+ std::forward_as_tuple(std::forward<_Vp>(__y)));
+ }
+
+ template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+ __attribute__((__nonnull__))
+ void
+ construct(pair<_Tp1, _Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
+ {
+ this->construct(__p, piecewise_construct,
+ std::forward_as_tuple(__pr.first),
+ std::forward_as_tuple(__pr.second));
+ }
+
+ template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+ __attribute__((__nonnull__))
+ void
+ construct(pair<_Tp1, _Tp2>* __p, pair<_Up, _Vp>&& __pr)
+ {
+ this->construct(__p, piecewise_construct,
+ std::forward_as_tuple(std::forward<_Up>(__pr.first)),
+ std::forward_as_tuple(std::forward<_Vp>(__pr.second)));
+ }
+#else // make_obj_using_allocator
+ template<typename _Tp1, typename... _Args>
+ __attribute__((__nonnull__))
+ void
+ construct(_Tp1* __p, _Args&&... __args)
+ {
+ std::uninitialized_construct_using_allocator(__p, *this,
+ std::forward<_Args>(__args)...);
+ }
+#endif
+
+ template<typename _Up>
+ _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::destroy")
+ __attribute__((__nonnull__))
+ void
+ destroy(_Up* __p)
+ { __p->~_Up(); }
+
+ polymorphic_allocator
+ select_on_container_copy_construction() const noexcept
+ { return polymorphic_allocator(); }
+
+ memory_resource*
+ resource() const noexcept
+ __attribute__((__returns_nonnull__))
+ { return _M_resource; }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3683. operator== for polymorphic_allocator cannot deduce template arg
+ [[nodiscard]]
+ friend bool
+ operator==(const polymorphic_allocator& __a,
+ const polymorphic_allocator& __b) noexcept
+ { return *__a.resource() == *__b.resource(); }
+
+#if __cpp_impl_three_way_comparison < 201907L
+ [[nodiscard]]
+ friend bool
+ operator!=(const polymorphic_allocator& __a,
+ const polymorphic_allocator& __b) noexcept
+ { return !(__a == __b); }
+#endif
+
+ private:
+#if ! __cpp_lib_make_obj_using_allocator
+ using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
+ using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
+
+ template<typename _Ind, typename... _Args>
+ static tuple<_Args&&...>
+ _S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
+ { return std::move(__t); }
+
+ template<size_t... _Ind, typename... _Args>
+ static tuple<allocator_arg_t, polymorphic_allocator, _Args&&...>
+ _S_construct_p(__uses_alloc1_ __ua, index_sequence<_Ind...>,
+ tuple<_Args...>& __t)
+ {
+ return {
+ allocator_arg, *__ua._M_a, std::get<_Ind>(std::move(__t))...
+ };
+ }
+
+ template<size_t... _Ind, typename... _Args>
+ static tuple<_Args&&..., polymorphic_allocator>
+ _S_construct_p(__uses_alloc2_ __ua, index_sequence<_Ind...>,
+ tuple<_Args...>& __t)
+ { return { std::get<_Ind>(std::move(__t))..., *__ua._M_a }; }
+#endif
+
+ memory_resource* _M_resource;
+ };
+
+ template<typename _Tp1, typename _Tp2>
+ [[nodiscard]]
+ inline bool
+ operator==(const polymorphic_allocator<_Tp1>& __a,
+ const polymorphic_allocator<_Tp2>& __b) noexcept
+ { return *__a.resource() == *__b.resource(); }
+
+#if __cpp_impl_three_way_comparison < 201907L
+ template<typename _Tp1, typename _Tp2>
+ [[nodiscard]]
+ inline bool
+ operator!=(const polymorphic_allocator<_Tp1>& __a,
+ const polymorphic_allocator<_Tp2>& __b) noexcept
+ { return !(__a == __b); }
+#endif
+
+} // namespace pmr
+
+ template<typename _Alloc> struct allocator_traits;
+
+ /// Partial specialization for std::pmr::polymorphic_allocator
+ template<typename _Tp>
+ struct allocator_traits<pmr::polymorphic_allocator<_Tp>>
+ {
+ /// The allocator type
+ using allocator_type = pmr::polymorphic_allocator<_Tp>;
+
+ /// The allocated type
+ using value_type = _Tp;
+
+ /// The allocator's pointer type.
+ using pointer = _Tp*;
+
+ /// The allocator's const pointer type.
+ using const_pointer = const _Tp*;
+
+ /// The allocator's void pointer type.
+ using void_pointer = void*;
+
+ /// The allocator's const void pointer type.
+ using const_void_pointer = const void*;
+
+ /// The allocator's difference type
+ using difference_type = std::ptrdiff_t;
+
+ /// The allocator's size type
+ using size_type = std::size_t;
+
+ /** @{
+ * A `polymorphic_allocator` does not propagate when a
+ * container is copied, moved, or swapped.
+ */
+ using propagate_on_container_copy_assignment = false_type;
+ using propagate_on_container_move_assignment = false_type;
+ using propagate_on_container_swap = false_type;
+
+ static allocator_type
+ select_on_container_copy_construction(const allocator_type&) noexcept
+ { return allocator_type(); }
+ /// @}
+
+ /// Whether all instances of the allocator type compare equal.
+ using is_always_equal = false_type;
+
+ template<typename _Up>
+ using rebind_alloc = pmr::polymorphic_allocator<_Up>;
+
+ template<typename _Up>
+ using rebind_traits = allocator_traits<pmr::polymorphic_allocator<_Up>>;
+
+ /**
+ * @brief Allocate memory.
+ * @param __a An allocator.
+ * @param __n The number of objects to allocate space for.
+ *
+ * Calls `a.allocate(n)`.
+ */
+ [[nodiscard]] static pointer
+ allocate(allocator_type& __a, size_type __n)
+ { return __a.allocate(__n); }
+
+ /**
+ * @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`.
+ *
+ * The third parameter is ignored..
+ *
+ * Returns `a.allocate(n)`.
+ */
+ [[nodiscard]] static pointer
+ allocate(allocator_type& __a, size_type __n, const_void_pointer)
+ { return __a.allocate(__n); }
+
+ /**
+ * @brief Deallocate memory.
+ * @param __a An allocator.
+ * @param __p Pointer to the memory to deallocate.
+ * @param __n The number of objects space was allocated for.
+ *
+ * Calls `a.deallocate(p, n)`.
+ */
+ static void
+ deallocate(allocator_type& __a, pointer __p, size_type __n)
+ { __a.deallocate(__p, __n); }
+
+ /**
+ * @brief Construct an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to memory of suitable size and alignment for
+ * an object of type `_Up`.
+ * @param __args Constructor arguments.
+ *
+ * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
+ * in C++11, C++14 and C++17. Changed in C++20 to call
+ * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
+ */
+ template<typename _Up, typename... _Args>
+ static void
+ construct(allocator_type& __a, _Up* __p, _Args&&... __args)
+ { __a.construct(__p, std::forward<_Args>(__args)...); }
+
+ /**
+ * @brief Destroy an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to the object to destroy
+ *
+ * Calls `p->_Up()`.
+ */
+ template<typename _Up>
+ static _GLIBCXX20_CONSTEXPR void
+ destroy(allocator_type&, _Up* __p)
+ noexcept(is_nothrow_destructible<_Up>::value)
+ { __p->~_Up(); }
+
+ /**
+ * @brief The maximum supported allocation size
+ * @return `numeric_limits<size_t>::max() / sizeof(value_type)`
+ */
+ static _GLIBCXX20_CONSTEXPR size_type
+ max_size(const allocator_type&) noexcept
+ { return size_t(-1) / sizeof(value_type); }
+ };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+#endif // _GLIBCXX_MEMORY_RESOURCE_H
diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index dc5c2034b8f..abdc2e04cdd 100644
--- a/libstdc++-v3/include/std/deque
+++ b/libstdc++-v3/include/std/deque
@@ -71,12 +71,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Tp>
using deque = std::deque<_Tp, polymorphic_allocator<_Tp>>;
} // namespace pmr
diff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list
index 21d617b00e9..fe99e5ed5ef 100644
--- a/libstdc++-v3/include/std/forward_list
+++ b/libstdc++-v3/include/std/forward_list
@@ -44,12 +44,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Tp>
using forward_list = std::forward_list<_Tp, polymorphic_allocator<_Tp>>;
} // namespace pmr
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index d7ef94317b1..9151e98cb88 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -68,12 +68,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Tp>
using list = std::list<_Tp, polymorphic_allocator<_Tp>>;
} // namespace pmr
diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map
index 93c956af916..ce07f29ee09 100644
--- a/libstdc++-v3/include/std/map
+++ b/libstdc++-v3/include/std/map
@@ -68,12 +68,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Key, typename _Tp, typename _Cmp = std::less<_Key>>
using map
= std::map<_Key, _Tp, _Cmp,
diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource
index 745422ad5eb..19c922516d5 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -33,22 +33,12 @@
#if __cplusplus >= 201703L
-#include <new>
+#include <bits/memory_resource.h>
#include <vector> // vector
-#include <cstddef> // size_t, max_align_t, byte
#include <shared_mutex> // shared_mutex
#include <bits/align.h> // align
-#include <bits/functexcept.h> // __throw_bad_array_new_length
-#include <bits/uses_allocator.h> // allocator_arg_t, __use_alloc
-#include <bits/uses_allocator_args.h> // uninitialized_construct_using_alloc
-#include <ext/numeric_traits.h>
#include <debug/assertions.h>
-#if ! __cpp_lib_make_obj_using_allocator
-# include <bits/utility.h> // index_sequence
-# include <tuple> // tuple, forward_as_tuple
-#endif
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -62,12 +52,7 @@ namespace pmr
# define __cpp_lib_memory_resource 1
#endif
- class memory_resource;
-
-#if __cplusplus == 201703L
- template<typename _Tp>
- class polymorphic_allocator;
-#else // C++20
+#if __cplusplus >= 202002L
# define __cpp_lib_polymorphic_allocator 201902L
template<typename _Tp = std::byte>
class polymorphic_allocator;
@@ -103,451 +88,6 @@ namespace pmr
class unsynchronized_pool_resource;
class monotonic_buffer_resource;
- /// Class memory_resource
- class memory_resource
- {
- static constexpr size_t _S_max_align = alignof(max_align_t);
-
- public:
- memory_resource() = default;
- memory_resource(const memory_resource&) = default;
- virtual ~memory_resource(); // key function
-
- memory_resource& operator=(const memory_resource&) = default;
-
- [[nodiscard]]
- void*
- allocate(size_t __bytes, size_t __alignment = _S_max_align)
- __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
- { return ::operator new(__bytes, do_allocate(__bytes, __alignment)); }
-
- void
- deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
- __attribute__((__nonnull__))
- { return do_deallocate(__p, __bytes, __alignment); }
-
- [[nodiscard]]
- bool
- is_equal(const memory_resource& __other) const noexcept
- { return do_is_equal(__other); }
-
- private:
- virtual void*
- do_allocate(size_t __bytes, size_t __alignment) = 0;
-
- virtual void
- do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;
-
- virtual bool
- do_is_equal(const memory_resource& __other) const noexcept = 0;
- };
-
- [[nodiscard]]
- inline bool
- operator==(const memory_resource& __a, const memory_resource& __b) noexcept
- { return &__a == &__b || __a.is_equal(__b); }
-
-#if __cpp_impl_three_way_comparison < 201907L
- [[nodiscard]]
- inline bool
- operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
- { return !(__a == __b); }
-#endif
-
- // C++17 23.12.3 Class template polymorphic_allocator
- template<typename _Tp>
- class polymorphic_allocator
- {
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 2975. Missing case for pair construction in polymorphic allocators
- template<typename _Up>
- struct __not_pair { using type = void; };
-
- template<typename _Up1, typename _Up2>
- struct __not_pair<pair<_Up1, _Up2>> { };
-
- public:
- using value_type = _Tp;
-
- polymorphic_allocator() noexcept
- : _M_resource(get_default_resource())
- { }
-
- polymorphic_allocator(memory_resource* __r) noexcept
- __attribute__((__nonnull__))
- : _M_resource(__r)
- { _GLIBCXX_DEBUG_ASSERT(__r); }
-
- polymorphic_allocator(const polymorphic_allocator& __other) = default;
-
- template<typename _Up>
- polymorphic_allocator(const polymorphic_allocator<_Up>& __x) noexcept
- : _M_resource(__x.resource())
- { }
-
- polymorphic_allocator&
- operator=(const polymorphic_allocator&) = delete;
-
- [[nodiscard]]
- _Tp*
- allocate(size_t __n)
- __attribute__((__returns_nonnull__))
- {
- if ((__gnu_cxx::__int_traits<size_t>::__max / sizeof(_Tp)) < __n)
- std::__throw_bad_array_new_length();
- return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
- alignof(_Tp)));
- }
-
- void
- deallocate(_Tp* __p, size_t __n) noexcept
- __attribute__((__nonnull__))
- { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
-
-#if __cplusplus > 201703L
- [[nodiscard]] void*
- allocate_bytes(size_t __nbytes,
- size_t __alignment = alignof(max_align_t))
- { return _M_resource->allocate(__nbytes, __alignment); }
-
- void
- deallocate_bytes(void* __p, size_t __nbytes,
- size_t __alignment = alignof(max_align_t))
- { _M_resource->deallocate(__p, __nbytes, __alignment); }
-
- template<typename _Up>
- [[nodiscard]] _Up*
- allocate_object(size_t __n = 1)
- {
- if ((__gnu_cxx::__int_traits<size_t>::__max / sizeof(_Up)) < __n)
- std::__throw_bad_array_new_length();
- return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up),
- alignof(_Up)));
- }
-
- template<typename _Up>
- void
- deallocate_object(_Up* __p, size_t __n = 1)
- { deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); }
-
- template<typename _Up, typename... _CtorArgs>
- [[nodiscard]] _Up*
- new_object(_CtorArgs&&... __ctor_args)
- {
- _Up* __p = allocate_object<_Up>();
- __try
- {
- construct(__p, std::forward<_CtorArgs>(__ctor_args)...);
- }
- __catch (...)
- {
- deallocate_object(__p);
- __throw_exception_again;
- }
- return __p;
- }
-
- template<typename _Up>
- void
- delete_object(_Up* __p)
- {
- __p->~_Up();
- deallocate_object(__p);
- }
-#endif // C++2a
-
-#if ! __cpp_lib_make_obj_using_allocator
- template<typename _Tp1, typename... _Args>
- __attribute__((__nonnull__))
- typename __not_pair<_Tp1>::type
- construct(_Tp1* __p, _Args&&... __args)
- {
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 2969. polymorphic_allocator::construct() shouldn't pass resource()
- using __use_tag
- = std::__uses_alloc_t<_Tp1, polymorphic_allocator, _Args...>;
- if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)
- ::new(__p) _Tp1(std::forward<_Args>(__args)...);
- else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)
- ::new(__p) _Tp1(allocator_arg, *this,
- std::forward<_Args>(__args)...);
- else
- ::new(__p) _Tp1(std::forward<_Args>(__args)..., *this);
- }
-
- template<typename _Tp1, typename _Tp2,
- typename... _Args1, typename... _Args2>
- __attribute__((__nonnull__))
- void
- construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
- tuple<_Args1...> __x, tuple<_Args2...> __y)
- {
- auto __x_tag =
- __use_alloc<_Tp1, polymorphic_allocator, _Args1...>(*this);
- auto __y_tag =
- __use_alloc<_Tp2, polymorphic_allocator, _Args2...>(*this);
- index_sequence_for<_Args1...> __x_i;
- index_sequence_for<_Args2...> __y_i;
-
- ::new(__p) pair<_Tp1, _Tp2>(piecewise_construct,
- _S_construct_p(__x_tag, __x_i, __x),
- _S_construct_p(__y_tag, __y_i, __y));
- }
-
- template<typename _Tp1, typename _Tp2>
- __attribute__((__nonnull__))
- void
- construct(pair<_Tp1, _Tp2>* __p)
- { this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
-
- template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
- __attribute__((__nonnull__))
- void
- construct(pair<_Tp1, _Tp2>* __p, _Up&& __x, _Vp&& __y)
- {
- this->construct(__p, piecewise_construct,
- std::forward_as_tuple(std::forward<_Up>(__x)),
- std::forward_as_tuple(std::forward<_Vp>(__y)));
- }
-
- template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
- __attribute__((__nonnull__))
- void
- construct(pair<_Tp1, _Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
- {
- this->construct(__p, piecewise_construct,
- std::forward_as_tuple(__pr.first),
- std::forward_as_tuple(__pr.second));
- }
-
- template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
- __attribute__((__nonnull__))
- void
- construct(pair<_Tp1, _Tp2>* __p, pair<_Up, _Vp>&& __pr)
- {
- this->construct(__p, piecewise_construct,
- std::forward_as_tuple(std::forward<_Up>(__pr.first)),
- std::forward_as_tuple(std::forward<_Vp>(__pr.second)));
- }
-#else // make_obj_using_allocator
- template<typename _Tp1, typename... _Args>
- __attribute__((__nonnull__))
- void
- construct(_Tp1* __p, _Args&&... __args)
- {
- std::uninitialized_construct_using_allocator(__p, *this,
- std::forward<_Args>(__args)...);
- }
-#endif
-
- template<typename _Up>
- _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::destroy")
- __attribute__((__nonnull__))
- void
- destroy(_Up* __p)
- { __p->~_Up(); }
-
- polymorphic_allocator
- select_on_container_copy_construction() const noexcept
- { return polymorphic_allocator(); }
-
- memory_resource*
- resource() const noexcept
- __attribute__((__returns_nonnull__))
- { return _M_resource; }
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 3683. operator== for polymorphic_allocator cannot deduce template arg
- [[nodiscard]]
- friend bool
- operator==(const polymorphic_allocator& __a,
- const polymorphic_allocator& __b) noexcept
- { return *__a.resource() == *__b.resource(); }
-
-#if __cpp_impl_three_way_comparison < 201907L
- [[nodiscard]]
- friend bool
- operator!=(const polymorphic_allocator& __a,
- const polymorphic_allocator& __b) noexcept
- { return !(__a == __b); }
-#endif
-
- private:
-#if ! __cpp_lib_make_obj_using_allocator
- using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
- using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
-
- template<typename _Ind, typename... _Args>
- static tuple<_Args&&...>
- _S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
- { return std::move(__t); }
-
- template<size_t... _Ind, typename... _Args>
- static tuple<allocator_arg_t, polymorphic_allocator, _Args&&...>
- _S_construct_p(__uses_alloc1_ __ua, index_sequence<_Ind...>,
- tuple<_Args...>& __t)
- {
- return {
- allocator_arg, *__ua._M_a, std::get<_Ind>(std::move(__t))...
- };
- }
-
- template<size_t... _Ind, typename... _Args>
- static tuple<_Args&&..., polymorphic_allocator>
- _S_construct_p(__uses_alloc2_ __ua, index_sequence<_Ind...>,
- tuple<_Args...>& __t)
- { return { std::get<_Ind>(std::move(__t))..., *__ua._M_a }; }
-#endif
-
- memory_resource* _M_resource;
- };
-
- template<typename _Tp1, typename _Tp2>
- [[nodiscard]]
- inline bool
- operator==(const polymorphic_allocator<_Tp1>& __a,
- const polymorphic_allocator<_Tp2>& __b) noexcept
- { return *__a.resource() == *__b.resource(); }
-
-#if __cpp_impl_three_way_comparison < 201907L
- template<typename _Tp1, typename _Tp2>
- [[nodiscard]]
- inline bool
- operator!=(const polymorphic_allocator<_Tp1>& __a,
- const polymorphic_allocator<_Tp2>& __b) noexcept
- { return !(__a == __b); }
-#endif
-
-} // namespace pmr
-
- /// Partial specialization for std::pmr::polymorphic_allocator
- template<typename _Tp>
- struct allocator_traits<pmr::polymorphic_allocator<_Tp>>
- {
- /// The allocator type
- using allocator_type = pmr::polymorphic_allocator<_Tp>;
-
- /// The allocated type
- using value_type = _Tp;
-
- /// The allocator's pointer type.
- using pointer = _Tp*;
-
- /// The allocator's const pointer type.
- using const_pointer = const _Tp*;
-
- /// The allocator's void pointer type.
- using void_pointer = void*;
-
- /// The allocator's const void pointer type.
- using const_void_pointer = const void*;
-
- /// The allocator's difference type
- using difference_type = std::ptrdiff_t;
-
- /// The allocator's size type
- using size_type = std::size_t;
-
- /** @{
- * A `polymorphic_allocator` does not propagate when a
- * container is copied, moved, or swapped.
- */
- using propagate_on_container_copy_assignment = false_type;
- using propagate_on_container_move_assignment = false_type;
- using propagate_on_container_swap = false_type;
-
- static allocator_type
- select_on_container_copy_construction(const allocator_type&) noexcept
- { return allocator_type(); }
- /// @}
-
- /// Whether all instances of the allocator type compare equal.
- using is_always_equal = false_type;
-
- template<typename _Up>
- using rebind_alloc = pmr::polymorphic_allocator<_Up>;
-
- template<typename _Up>
- using rebind_traits = allocator_traits<pmr::polymorphic_allocator<_Up>>;
-
- /**
- * @brief Allocate memory.
- * @param __a An allocator.
- * @param __n The number of objects to allocate space for.
- *
- * Calls `a.allocate(n)`.
- */
- [[nodiscard]] static pointer
- allocate(allocator_type& __a, size_type __n)
- { return __a.allocate(__n); }
-
- /**
- * @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`.
- *
- * The third parameter is ignored..
- *
- * Returns `a.allocate(n)`.
- */
- [[nodiscard]] static pointer
- allocate(allocator_type& __a, size_type __n, const_void_pointer)
- { return __a.allocate(__n); }
-
- /**
- * @brief Deallocate memory.
- * @param __a An allocator.
- * @param __p Pointer to the memory to deallocate.
- * @param __n The number of objects space was allocated for.
- *
- * Calls `a.deallocate(p, n)`.
- */
- static void
- deallocate(allocator_type& __a, pointer __p, size_type __n)
- { __a.deallocate(__p, __n); }
-
- /**
- * @brief Construct an object of type `_Up`
- * @param __a An allocator.
- * @param __p Pointer to memory of suitable size and alignment for
- * an object of type `_Up`.
- * @param __args Constructor arguments.
- *
- * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
- * in C++11, C++14 and C++17. Changed in C++20 to call
- * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
- */
- template<typename _Up, typename... _Args>
- static void
- construct(allocator_type& __a, _Up* __p, _Args&&... __args)
- { __a.construct(__p, std::forward<_Args>(__args)...); }
-
- /**
- * @brief Destroy an object of type `_Up`
- * @param __a An allocator.
- * @param __p Pointer to the object to destroy
- *
- * Calls `p->_Up()`.
- */
- template<typename _Up>
- static _GLIBCXX20_CONSTEXPR void
- destroy(allocator_type&, _Up* __p)
- noexcept(is_nothrow_destructible<_Up>::value)
- { __p->~_Up(); }
-
- /**
- * @brief The maximum supported allocation size
- * @return `numeric_limits<size_t>::max() / sizeof(value_type)`
- */
- static _GLIBCXX20_CONSTEXPR size_type
- max_size(const allocator_type&) noexcept
- { return size_t(-1) / sizeof(value_type); }
- };
-
-namespace pmr
-{
/// Parameters for tuning a pool resource's behaviour.
struct pool_options
{
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index d1b6a6c68c3..491bced23b5 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -67,12 +67,12 @@
#include <bits/regex_executor.h>
#if __cplusplus >= 201703L && _GLIBCXX_USE_CXX11_ABI
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _BidirectionalIterator>
using match_results
= std::match_results<_BidirectionalIterator, polymorphic_allocator<
diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set
index 45fed14c51e..551c77727f1 100644
--- a/libstdc++-v3/include/std/set
+++ b/libstdc++-v3/include/std/set
@@ -68,12 +68,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Key, typename _Cmp = std::less<_Key>>
using set = std::set<_Key, _Cmp, polymorphic_allocator<_Key>>;
template<typename _Key, typename _Cmp = std::less<_Key>>
diff --git a/libstdc++-v3/include/std/stacktrace b/libstdc++-v3/include/std/stacktrace
index 8e6c79a2f4f..1efaf253abb 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -33,6 +33,7 @@
#include <new>
#include <string>
#include <sstream>
+#include <bits/memory_resource.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#include <bits/stl_iterator.h>
@@ -758,7 +759,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
using stacktrace
= basic_stacktrace<polymorphic_allocator<stacktrace_entry>>;
}
diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string
index b1d8b6a34dd..24051663f74 100644
--- a/libstdc++-v3/include/std/string
+++ b/libstdc++-v3/include/std/string
@@ -54,11 +54,11 @@
#include <bits/basic_string.tcc>
#if __cplusplus >= 201703L && _GLIBCXX_USE_CXX11_ABI
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr {
- template<typename _Tp> class polymorphic_allocator;
template<typename _CharT, typename _Traits = char_traits<_CharT>>
using basic_string = std::basic_string<_CharT, _Traits,
polymorphic_allocator<_CharT>>;
diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map
index bb14ffa7f2e..e13bb9a2148 100644
--- a/libstdc++-v3/include/std/unordered_map
+++ b/libstdc++-v3/include/std/unordered_map
@@ -53,12 +53,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Key, typename _Tp, typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>>
using unordered_map
diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set
index 777e3b81116..8b665718a83 100644
--- a/libstdc++-v3/include/std/unordered_set
+++ b/libstdc++-v3/include/std/unordered_set
@@ -53,12 +53,12 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr
{
- template<typename _Tp> class polymorphic_allocator;
template<typename _Key, typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>>
using unordered_set
diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector
index a880dfcac6f..d7f69fd7a48 100644
--- a/libstdc++-v3/include/std/vector
+++ b/libstdc++-v3/include/std/vector
@@ -75,11 +75,11 @@
#endif
#if __cplusplus >= 201703L
+#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace pmr {
- template<typename _Tp> class polymorphic_allocator;
template<typename _Tp>
using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
} // namespace pmr
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc b/libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc
index 51bbfb0aba0..cabe59090af 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc
@@ -19,7 +19,8 @@
// { dg-require-effective-target cxx11_abi }
#include <string>
-#include <memory_resource>
+
+std::pmr::string s = "polly";
struct T : std::char_traits<char> { };
diff --git a/libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc
index f6493e8131e..c973d4f432c 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <deque>
-#include <memory_resource>
+
+std::pmr::deque<int> c{1, 2, 3, 4};
struct X { };
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc
index 8559783881f..f66e53f62a8 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <forward_list>
-#include <memory_resource>
+
+std::pmr::forward_list<int> c{1, 2, 3, 4};
struct X { };
diff --git a/libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc
index d6c408aa88f..3c5ef794720 100644
--- a/libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <list>
-#include <memory_resource>
+
+std::pmr::list<int> c{1, 2, 3, 4};
struct X { };
diff --git a/libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc
index cc82fcf5fc9..91602ccbc17 100644
--- a/libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <map>
-#include <memory_resource>
+
+std::pmr::map<int, int> c{{1,0}, {2,0}, {3,0}, {4,0}};
struct X { };
struct Y { };
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc
index 2312ad680a2..13b0970a100 100644
--- a/libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <map>
-#include <memory_resource>
+
+std::pmr::multimap<int, int> c{{1,0}, {2,0}, {3,0}, {4,0}};
struct X { };
struct Y { };
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc
index 19e28023533..f1013b6efdc 100644
--- a/libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <set>
-#include <memory_resource>
+
+std::pmr::multiset<int> c{1, 2, 3, 4};
struct X { };
struct Cmp { bool operator()(X, X) const { return false; } };
diff --git a/libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc
index a65d0719e52..4b70b984729 100644
--- a/libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <set>
-#include <memory_resource>
+
+std::pmr::set<int> c{1, 2, 3, 4};
struct X { };
struct Cmp { bool operator()(X, X) const { return false; } };
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc
index 7c00633bf1c..d8e17139f05 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <unordered_map>
-#include <memory_resource>
+
+std::pmr::unordered_map<int, int> c{{1,0}, {2,0}, {3,0}, {4,0}};
struct X { };
struct Y { };
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc
index 51d598e7e25..6dfe1d5b8bd 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <unordered_map>
-#include <memory_resource>
+
+std::pmr::unordered_multimap<int, int> c{{1,0}, {2,0}, {3,0}, {4,0}};
struct X { };
struct Y { };
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc
index f5b9d6c0282..4deeb710686 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <unordered_set>
-#include <memory_resource>
+
+std::pmr::unordered_multiset<int> c{1, 2, 3, 4};
struct X { };
struct Hash { std::size_t operator()(X) const { return 0; } };
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc
index 5fe33e880f9..4736cfff86f 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <unordered_set>
-#include <memory_resource>
+
+std::pmr::unordered_set<int> c{1, 2, 3, 4};
struct X { };
struct Hash { std::size_t operator()(X) const { return 0; } };
diff --git a/libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc b/libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc
index 0fbc32bb185..f4969e3364e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc
@@ -18,7 +18,8 @@
// { dg-do compile { target c++17 } }
#include <vector>
-#include <memory_resource>
+
+std::pmr::vector<int> c{1, 2, 3, 4};
struct X { };
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc b/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
index b8c22d03a17..5ff4c771a6c 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
@@ -20,7 +20,8 @@
// { dg-require-effective-target cxx11_abi }
#include <regex>
-#include <memory_resource>
+
+std::pmr::match_results<const char*> m;
struct X;
static_assert(std::is_same_v<std::pmr::match_results<X*>,