libstdc++: Ensure pmr aliases work without <memory_resource>
authorJonathan Wakely <jwakely@redhat.com>
Thu, 19 May 2022 22:38:23 +0000 (23:38 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 19 May 2022 22:38:23 +0000 (23:38 +0100)
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.

30 files changed:
gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/memory_resource.h [new file with mode: 0644]
libstdc++-v3/include/std/deque
libstdc++-v3/include/std/forward_list
libstdc++-v3/include/std/list
libstdc++-v3/include/std/map
libstdc++-v3/include/std/memory_resource
libstdc++-v3/include/std/regex
libstdc++-v3/include/std/set
libstdc++-v3/include/std/stacktrace
libstdc++-v3/include/std/string
libstdc++-v3/include/std/unordered_map
libstdc++-v3/include/std/unordered_set
libstdc++-v3/include/std/vector
libstdc++-v3/testsuite/21_strings/basic_string/types/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/deque/types/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/forward_list/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/list/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/map/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/multimap/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/multiset/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/set/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/unordered_map/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/unordered_set/pmr_typedefs.cc
libstdc++-v3/testsuite/23_containers/vector/pmr_typedefs.cc
libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc

index b1c6b3d..e2699d9 100644 (file)
@@ -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;
index 77eea7d..b46def7 100644 (file)
@@ -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 \
index 01bf3e0..f844008 100644 (file)
@@ -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 (file)
index 0000000..d8c7e16
--- /dev/null
@@ -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
index dc5c203..abdc2e0 100644 (file)
 #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
index 21d617b..fe99e5e 100644 (file)
 #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
index d7ef943..9151e98 100644 (file)
 #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
index 93c956a..ce07f29 100644 (file)
 #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,
index 745422a..19c9225 100644 (file)
 
 #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
   {
index d1b6a6c..491bced 100644 (file)
 #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<
index 45fed14..551c777 100644 (file)
 #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>>
index 8e6c79a..1efaf25 100644 (file)
@@ -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>>;
   }
index b1d8b6a..2405166 100644 (file)
 #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>>;
index bb14ffa..e13bb9a 100644 (file)
 #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
index 777e3b8..8b66571 100644 (file)
 #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
index a880dfc..d7f69fd 100644 (file)
 #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
index 51bbfb0..cabe590 100644 (file)
@@ -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> { };
 
index f6493e8..c973d4f 100644 (file)
@@ -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 { };
 
index 8559783..f66e53f 100644 (file)
@@ -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 { };
 
index d6c408a..3c5ef79 100644 (file)
@@ -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 { };
 
index cc82fcf..91602cc 100644 (file)
@@ -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 { };
index 2312ad6..13b0970 100644 (file)
@@ -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 { };
index 19e2802..f1013b6 100644 (file)
@@ -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; } };
index a65d071..4b70b98 100644 (file)
@@ -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; } };
index 7c00633..d8e1713 100644 (file)
@@ -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 { };
index 51d598e..6dfe1d5 100644 (file)
@@ -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 { };
index f5b9d6c..4deeb71 100644 (file)
@@ -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; } };
index 5fe33e8..4736cff 100644 (file)
@@ -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; } };
index 0fbc32b..f4969e3 100644 (file)
@@ -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 { };
 
index b8c22d0..5ff4c77 100644 (file)
@@ -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*>,