public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [v3 patch] GSoC: implement polymorphic memory resources
@ 2015-11-11 20:01 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2015-11-11 20:01 UTC (permalink / raw)
  To: Fan You; +Cc: libstdc++, gcc-patches, Tim Shen

[-- Attachment #1: Type: text/plain, Size: 643 bytes --]

The first patch is the work of Fan You, who implemented the
"polymorphic memory resources" feature from the C++ Library
Fundamentals TS as a Google Summer of Code project. Thanks very much
to Fan You for contributing this work, and to Tim Shen for mentoring
the work, and Google for sponsoring it.

The second patch adds a few little pieces missing from Fan You's
patch.

Tested powerpc64le-linux.

Apart from one minor change to the definition of the
std::uses_allocator trait (which will have no effect on any existing
code) this only makes changes inside namespace std::experimental. I
intend to commit these patches before stage 1 ends.



[-- Attachment #2: patch1.txt --]
[-- Type: text/plain, Size: 29099 bytes --]

commit 8ed54c84edbdebe30cb16ab97b54a4d157be67c2
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Nov 11 18:58:51 2015 +0000

    Implement C++ LFTSv1 polymorphic memory resources
    
    2015-11-11  Fan You  <youfan.noey@gmail.com>
    
    	* include/Makefile.am: Add new headers.
    	* include/Makefile.in: Regenerate.
    	* include/bits/uses_allocator.h (__erased_type): Define.
    	(__uses_allocator_helper): Check for __erased_type.
    	* include/experimental/memory_resource: New.
    	* include/experimental/utlity: New.
    	* testsuite/experimental/type_erased_allocator/1.cc: New.
    	* testsuite/experimental/type_erased_allocator/1_neg.cc: New.
    	* testsuite/experimental/type_erased_allocator/2.cc: New.
    	* testsuite/experimental/type_erased_allocator/uses_allocator.cc: New.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 2dc0d01..ee9b6d8 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -656,6 +656,7 @@ experimental_headers = \
 	${experimental_srcdir}/list \
 	${experimental_srcdir}/map \
 	${experimental_srcdir}/memory \
+	${experimental_srcdir}/memory_resource \
 	${experimental_srcdir}/numeric \
 	${experimental_srcdir}/optional \
 	${experimental_srcdir}/propagate_const \
@@ -668,6 +669,7 @@ experimental_headers = \
 	${experimental_srcdir}/type_traits \
 	${experimental_srcdir}/unordered_map \
 	${experimental_srcdir}/unordered_set \
+	${experimental_srcdir}/utility \
 	${experimental_srcdir}/vector \
 	${experimental_filesystem_headers}
 
diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h
index a0f084d..f7566a2 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -35,6 +35,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+  struct __erased_type { };
+
+  template<typename _Alloc, typename _Tp>
+    using __is_erased_or_convertible
+      = __or_<is_same<_Tp, __erased_type>, is_convertible<_Alloc, _Tp>>;
+
   /// [allocator.tag]
   struct allocator_arg_t { explicit allocator_arg_t() = default; };
 
@@ -47,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp, typename _Alloc>
     struct __uses_allocator_helper<_Tp, _Alloc,
 				   __void_t<typename _Tp::allocator_type>>
-    : is_convertible<_Alloc, typename _Tp::allocator_type>::type
+    : __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type
     { };
 
   /// [allocator.uses.trait]
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
new file mode 100644
index 0000000..5c8cbd6
--- /dev/null
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -0,0 +1,383 @@
+// <experimental/memory_resource> -*- C++ -*-
+
+// Copyright (C) 2015 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 experimental/memory_resource
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
+#define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1
+
+#include <memory>
+#include <new>
+#include <atomic>
+#include <cstddef>
+#include <bits/alloc_traits.h>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v2 {
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  class memory_resource;
+
+  template <typename _Tp>
+    class polymorphic_allocator;
+
+  template <typename _Alloc>
+    class __resource_adaptor_imp;
+
+  template <typename _Alloc>
+    using resource_adaptor = __resource_adaptor_imp<
+      typename allocator_traits<_Alloc>::template rebind_alloc<char>>;
+
+  template <typename _Tp>
+    struct __uses_allocator_construction_helper;
+
+  // Global memory resources
+  memory_resource* new_delete_resource() noexcept;
+  memory_resource* null_memory_resource() noexcept;
+
+  // The default memory resource
+  memory_resource* get_default_resource() noexcept;
+  memory_resource* set_default_resource(memory_resource* __r) noexcept;
+
+  // Standard memory resources
+
+  // 8.5 Class memory_resource
+  class memory_resource
+  {
+    static constexpr size_t _S_max_align = alignof(max_align_t);
+
+  public:
+    virtual ~memory_resource() { }
+
+    void*
+    allocate(size_t __bytes, size_t __alignment = _S_max_align)
+    { return do_allocate(__bytes, __alignment); }
+
+    void
+    deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
+    { return do_deallocate(__p, __bytes, __alignment); }
+
+    bool
+    is_equal(const memory_resource& __other) const noexcept
+    { return do_is_equal(__other); }
+
+  protected:
+    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;
+  };
+
+  inline bool
+  operator==(const memory_resource& __a,
+	     const memory_resource& __b) noexcept
+  { return &__a == &__b || __a.is_equal(__b); }
+
+  inline bool
+  operator!=(const memory_resource& __a,
+	     const memory_resource& __b) noexcept
+  { return !(__a == __b); }
+
+
+  // 8.6 Class template polymorphic_allocator
+  template <class _Tp>
+    class polymorphic_allocator
+    {
+      using __uses_alloc1_ = __uses_alloc1<memory_resource*>;
+      using __uses_alloc2_ = __uses_alloc2<memory_resource*>;
+
+      template<typename _Tp1, typename... _Args>
+	void
+	_M_construct(__uses_alloc0, _Tp1* __p, _Args&&... __args)
+	{ ::new(__p) _Tp1(std::forward<_Args>(__args)...); }
+
+      template<typename _Tp1, typename... _Args>
+	void
+	_M_construct(__uses_alloc1_, _Tp1* __p, _Args&&...  __args)
+	{ ::new(__p) _Tp1(allocator_arg, this->resource(),
+			  std::forward<_Args>(__args)...); }
+
+      template<typename _Tp1, typename... _Args>
+	void
+	_M_construct(__uses_alloc2_, _Tp1* __p, _Args&&...  __args)
+	{ ::new(__p) _Tp1(std::forward<_Args>(__args)...,
+			  this->resource()); }
+
+    public:
+      using value_type = _Tp;
+
+      polymorphic_allocator() noexcept
+      : _M_resource(get_default_resource())
+      { }
+
+      polymorphic_allocator(memory_resource* __r)
+      : _M_resource(__r)
+      { _GLIBCXX_DEBUG_ASSERT(__r); }
+
+      polymorphic_allocator(const polymorphic_allocator& __other) = default;
+
+      template <typename _Up>
+	polymorphic_allocator(const polymorphic_allocator<_Up>&
+			      __other) noexcept
+	: _M_resource(__other.resource())
+	{ }
+
+      polymorphic_allocator&
+	operator=(const polymorphic_allocator& __rhs) = default;
+
+      _Tp* allocate(size_t __n)
+      { return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
+						       alignof(_Tp))); }
+
+      void deallocate(_Tp* __p, size_t __n)
+      { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
+
+      template <typename _Tp1, typename... _Args> //used here
+	void construct(_Tp1* __p, _Args&&... __args)
+	{
+	  auto __use_tag = __use_alloc<_Tp1, memory_resource*,
+	       _Args...>(this->resource());
+	  _M_construct(__use_tag, __p, std::forward<_Args>(__args)...);
+	}
+
+      // Specializations for pair using piecewise construction
+      template <typename _Tp1, typename _Tp2,
+	       typename... _Args1, typename... _Args2>
+	void construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
+		       tuple<_Args1...> __x,
+		       tuple<_Args2...> __y)
+	{
+	  auto __x_use_tag =
+	    __use_alloc<_Tp1, memory_resource*, _Args1...>(this->resource());
+	  auto __y_use_tag =
+	    __use_alloc<_Tp2, memory_resource*, _Args2...>(this->resource());
+
+	  ::new(__p) std::pair<_Tp1, _Tp2>(piecewise_construct,
+					   _M_construct_p(__x_use_tag, __x),
+					   _M_construct_p(__y_use_tag, __y));
+	}
+
+      template <typename _Tp1, typename _Tp2>
+	void construct(pair<_Tp1,_Tp2>* __p)
+	{ this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
+
+      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+	void construct(pair<_Tp1,_Tp2>* __p, _Up&& __x, _Vp&& __y)
+	{ this->construct(__p, piecewise_construct,
+			  forward_as_tuple(std::forward<_Up>(__x)),
+			  forward_as_tuple(std::forward<_Vp>(__y))); }
+
+      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+	void construct(pair<_Tp1,_Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
+	{ this->construct(__p, piecewise_construct, forward_as_tuple(__pr.first),
+			  forward_as_tuple(__pr.second)); }
+
+      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
+	void construct(pair<_Tp1,_Tp2>* __p, pair<_Up, _Vp>&& __pr)
+	{ this->construct(__p, piecewise_construct,
+			  forward_as_tuple(std::forward<_Up>(__pr.first)),
+			  forward_as_tuple(std::forward<_Vp>(__pr.second))); }
+
+      template <typename _Up>
+	void destroy(_Up* __p)
+	{ __p->~_Up(); }
+
+      // Return a default-constructed allocator (no allocator propagation)
+      polymorphic_allocator select_on_container_copy_construction() const
+      { return polymorphic_allocator(); }
+
+      memory_resource* resource() const
+      { return _M_resource; }
+
+    private:
+      template<typename _Tuple>
+	_Tuple&&
+	_M_construct_p(__uses_alloc0, _Tuple& __t)
+	{ return std::move(__t); }
+
+      template<typename... _Args>
+	decltype(auto)
+	_M_construct_p(__uses_alloc1_ __ua, tuple<_Args...>& __t)
+	{ return tuple_cat(make_tuple(allocator_arg, *(__ua._M_a)),
+			   std::move(__t)); }
+
+      template<typename... _Args>
+	decltype(auto)
+	_M_construct_p(__uses_alloc2_ __ua, tuple<_Args...>& __t)
+	{ return tuple_cat(std::move(__t), make_tuple(*(__ua._M_a))); }
+
+      memory_resource* _M_resource;
+    };
+
+  template <class _Tp1, class _Tp2>
+    bool operator==(const polymorphic_allocator<_Tp1>& __a,
+		    const polymorphic_allocator<_Tp2>& __b) noexcept
+    { return *__a.resource() == *__b.resource(); }
+
+  template <class _Tp1, class _Tp2>
+    bool operator!=(const polymorphic_allocator<_Tp1>& __a,
+		    const polymorphic_allocator<_Tp2>& __b) noexcept
+    { return !(__a == __b); }
+
+  // 8.7.1 __resource_adaptor_imp
+  template <typename _Alloc>
+    class __resource_adaptor_imp : public memory_resource
+    {
+    public:
+      using allocator_type = _Alloc;
+
+      __resource_adaptor_imp() = default;
+      __resource_adaptor_imp(const __resource_adaptor_imp&) = default;
+      __resource_adaptor_imp(__resource_adaptor_imp&&) = default;
+
+      explicit __resource_adaptor_imp(const _Alloc& __a2)
+      : _M_alloc(__a2)
+      { }
+
+      explicit __resource_adaptor_imp(_Alloc&& __a2)
+      : _M_alloc(std::move(__a2))
+      { }
+
+      __resource_adaptor_imp&
+      operator=(const __resource_adaptor_imp&) = default;
+
+      allocator_type get_allocator() const { return _M_alloc; }
+
+    protected:
+      virtual void*
+      do_allocate(size_t __bytes, size_t __alignment)
+      {
+	using _Aligned_alloc = std::__alloc_rebind<_Alloc, char>;
+	size_t __new_size = _S_aligned_size(__bytes,
+					    _S_supported(__alignment) ?
+					    __alignment : _S_max_align);
+	return _Aligned_alloc().allocate(__new_size);
+      }
+
+      virtual void
+      do_deallocate(void* __p, size_t __bytes, size_t __alignment)
+      {
+	using _Aligned_alloc = std::__alloc_rebind<_Alloc, char>;
+	size_t __new_size = _S_aligned_size(__bytes,
+					    _S_supported(__alignment) ?
+					    __alignment : _S_max_align);
+	_Aligned_alloc().deallocate(static_cast<typename
+				    _Aligned_alloc::pointer>(__p),
+				    __new_size);
+      }
+
+      virtual bool
+      do_is_equal(const memory_resource& __other) const noexcept
+      {
+	auto __p = dynamic_cast<const __resource_adaptor_imp*>(&__other);
+	return __p ? (_M_alloc == __p->_M_alloc) : false;
+      }
+
+    private:
+      // Calculate Aligned Size
+      // Returns a size that is larger than or equal to __size and divided by
+      // __alignment, where __alignment is required to be the power of 2.
+      static size_t
+      _S_aligned_size(size_t __size, size_t __alignment)
+      { return ((__size - 1)|(__alignment - 1)) + 1; }
+
+      // Determine whether alignment meets one of those preconditions:
+      // 1. Equals to Zero
+      // 2. Is power of two
+      static bool
+      _S_supported (size_t __x)
+      { return ((__x != 0) && !(__x & (__x - 1))); }
+
+      _Alloc _M_alloc;
+    };
+
+  // Global memory resources
+  inline std::atomic<memory_resource*>&
+  __get_default_resource()
+  {
+    static atomic<memory_resource*> _S_default_resource(new_delete_resource());
+    return _S_default_resource;
+  }
+
+  inline memory_resource*
+  new_delete_resource() noexcept
+  {
+    static resource_adaptor<std::allocator<char>> __r;
+    return static_cast<memory_resource*>(&__r);
+  }
+
+  template <typename _Alloc>
+    class __null_memory_resource : private memory_resource
+    {
+    protected:
+      void*
+      do_allocate(size_t __bytes, size_t __alignment)
+      { std::__throw_bad_alloc(); }
+
+      void
+      do_deallocate(void* __p, size_t __bytes, size_t __alignment)
+      { }
+
+      bool
+      do_is_equal(const memory_resource& __other) const noexcept
+      { }
+
+      friend memory_resource* null_memory_resource() noexcept;
+    };
+
+  inline memory_resource*
+  null_memory_resource() noexcept
+  {
+    static __null_memory_resource<void> __r;
+    return static_cast<memory_resource*>(&__r);
+  }
+
+  // The default memory resource
+  inline memory_resource*
+  get_default_resource() noexcept
+  { return __get_default_resource().load(); }
+
+  inline memory_resource*
+  set_default_resource(memory_resource* __r) noexcept
+  {
+    if (__r == nullptr)
+      __r = new_delete_resource();
+    return __get_default_resource().exchange(__r);
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/experimental/utility b/libstdc++-v3/include/experimental/utility
new file mode 100644
index 0000000..b1aacee
--- /dev/null
+++ b/libstdc++-v3/include/experimental/utility
@@ -0,0 +1,48 @@
+// <experimental/utility> -*- C++ -*-
+
+// Copyright (C) 2015 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 experimental/utility
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_UTILITY
+#define _GLIBCXX_EXPERIMENTAL_UTILITY 1
+
+#include <utility>
+#include <bits/uses_allocator.h>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v2 {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // 3.1.2, erased-type placeholder
+  using erased_type = std::__erased_type;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc b/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc
new file mode 100644
index 0000000..9545edf
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc
@@ -0,0 +1,147 @@
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2015 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <memory>
+#include <experimental/memory_resource>
+#include <vector>
+#include <bits/uses_allocator.h>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using std::experimental::pmr::polymorphic_allocator;
+using std::experimental::pmr::memory_resource;
+using std::experimental::pmr::new_delete_resource;
+using std::experimental::pmr::get_default_resource;
+using std::experimental::pmr::set_default_resource;
+
+struct A
+{
+  A() { ++ctor_count; }
+  ~A() { ++dtor_count; }
+  static int ctor_count;
+  static int dtor_count;
+};
+int A::ctor_count = 0;
+int A::dtor_count = 0;
+
+struct CountedResource : public memory_resource
+{
+public:
+  CountedResource() = default;
+  ~ CountedResource() = default;
+
+  static size_t get_alloc_count()  { return alloc_count;  }
+  static size_t get_dalloc_count() { return dalloc_count; }
+
+  static size_t  alloc_count;
+  static size_t  dalloc_count;
+protected:
+  void* do_allocate(size_t bytes, size_t alignment)
+  {
+    alloc_count += bytes;
+    if (auto ptr = std::malloc(bytes)) {
+      return ptr;
+    }
+    throw std::bad_alloc();
+  }
+
+  void do_deallocate(void *p, size_t bytes, size_t alignment)
+  {
+    dalloc_count += bytes;
+    free(p);
+  }
+
+  bool do_is_equal(const memory_resource& __other) const noexcept
+  { return this == &__other; }
+};
+  size_t  CountedResource::alloc_count  = 0;
+  size_t  CountedResource::dalloc_count = 0;
+
+void clear()
+{
+  CountedResource::alloc_count  = 0;
+  CountedResource::dalloc_count = 0;
+  A::ctor_count = 0;
+  A::dtor_count = 0;
+}
+
+// memory resource
+void test01()
+{
+  memory_resource* r = new_delete_resource();
+  VERIFY(get_default_resource() == r);
+  void *p = get_default_resource()->allocate(5);
+  VERIFY(p);
+  get_default_resource()->deallocate(p, 5);
+
+  clear();
+  CountedResource* cr = new CountedResource();
+  set_default_resource(cr);
+  VERIFY(get_default_resource() == cr);
+  void *pc = get_default_resource()->allocate(5);
+  VERIFY(pc);
+  get_default_resource()->deallocate(pc, 5);
+  VERIFY(CountedResource::get_alloc_count()  == 5);
+  VERIFY(CountedResource::get_dalloc_count() == 5);
+}
+
+// polymorphic_allocator
+void test02()
+{
+  clear();
+  {
+    CountedResource cr;
+    polymorphic_allocator<A> pa(&cr);
+    std::vector<A, polymorphic_allocator<A>> v(5, A(), pa);
+  }
+  VERIFY(A::ctor_count == 1);
+  VERIFY(A::dtor_count == 6);
+  VERIFY(CountedResource::get_alloc_count()  == 5);
+  VERIFY(CountedResource::get_dalloc_count() == 5);
+}
+
+void test03() {
+  clear();
+  CountedResource cr;
+  polymorphic_allocator<A> pa(&cr);
+  A* p = pa.allocate(1);
+  pa.construct(p);
+  pa.destroy(p);
+  pa.deallocate(p, 1);
+  VERIFY(A::ctor_count == 1);
+  VERIFY(A::dtor_count == 1);
+  VERIFY(CountedResource::get_alloc_count()  == 1);
+  VERIFY(CountedResource::get_dalloc_count() == 1);
+}
+
+void test04() {
+  polymorphic_allocator<A> pa1(get_default_resource());
+  polymorphic_allocator<A> pa2(get_default_resource());
+  VERIFY(pa1 == pa2);
+  polymorphic_allocator<A> pa3 = pa2.select_on_container_copy_construction();
+  VERIFY(pa1 == pa3);
+}
+
+int main() {
+  test01();
+  test02();
+  test03();
+  test04();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc b/libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc
new file mode 100644
index 0000000..b85e0ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc
@@ -0,0 +1,37 @@
+// { dg-do run { xfail *-*-* } }
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2015 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory_resource>
+#include <bits/uses_allocator.h>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using std::experimental::pmr::polymorphic_allocator;
+using std::experimental::pmr::null_memory_resource;
+using std::experimental::pmr::memory_resource;
+
+void test01() {
+  memory_resource* r = null_memory_resource();
+  auto p = r->allocate(1);
+}
+
+int main() {
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc b/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
new file mode 100644
index 0000000..014c357
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
@@ -0,0 +1,202 @@
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2015 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <memory>
+#include <experimental/memory_resource>
+#include <experimental/utility>
+#include <bits/uses_allocator.h>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using std::experimental::pmr::polymorphic_allocator;
+using std::experimental::pmr::memory_resource;
+using std::experimental::pmr::new_delete_resource;
+using std::experimental::pmr::get_default_resource;
+using std::experimental::pmr::set_default_resource;
+using std::allocator_arg_t;
+
+enum CtorType { Default, Copy, Move, Other, Tuple, Piecewise_Default, Piecewise_Copy};
+
+// type that takes a memory_resource before other ctor args
+struct A
+{
+  using allocator_type = std::experimental::erased_type;
+
+  CtorType type;
+  memory_resource* alloc = nullptr;
+
+  A() : type(Default) { }
+  A(allocator_arg_t, memory_resource* a) : type(Default), alloc(a) { }
+  A(const A&) : type(Copy) { }
+  A(allocator_arg_t, memory_resource* a, const A&) : type(Copy), alloc(a) { }
+  A(A&&) : type (Move) { }
+  A(allocator_arg_t, memory_resource* a, A&&) : type (Move), alloc(a) { }
+  A(int) : type(Other) { }
+  A(allocator_arg_t, memory_resource* a, int) : type(Other), alloc(a) { }
+};
+
+// type that takes a memory_resource after other ctor args
+struct B
+{
+  using allocator_type = std::experimental::erased_type;
+
+  CtorType type;
+  memory_resource* alloc = nullptr;
+
+  B() : type(Default) { }
+  B(memory_resource* a) : type(Default), alloc(a) { }
+  B(const B&) : type(Copy) { }
+  B(const B&, memory_resource* a) : type(Copy), alloc(a) { }
+  B(B&&) : type (Move) { }
+  B(B&&, memory_resource* a) : type(Move), alloc(a) { }
+  B(int) : type(Other) { }
+  B(int, memory_resource* a) : type(Other), alloc(a) { }
+};
+
+// type that takes no memory_resource
+struct C
+{
+  CtorType type;
+  C() : type(Default) { }
+  C(const C&) : type(Copy) { }
+  C(C&&) : type(Move) { }
+  C(int) : type(Other) { }
+};
+
+// test construct for type that
+// uses memory_resource* as allocator
+template<typename A>
+void test_uses_alloc() {
+  polymorphic_allocator<A> pa;
+  A* p = pa.allocate(1);
+  A a;
+
+  pa.construct(p);
+  VERIFY(p->alloc == get_default_resource());
+  VERIFY(p->type == Default);
+  pa.destroy(p);
+
+  pa.construct(p, a);
+  VERIFY(p->type == Copy);
+  pa.destroy(p);
+
+  pa.construct(p, A());
+  VERIFY(p->type == Move);
+  pa.destroy(p);
+
+  pa.construct(p, 1);
+  VERIFY(p->type == Other);
+  pa.destroy(p);
+
+  pa.deallocate(p, 1);
+}
+
+// test construct for type that not using allocator
+template <typename C>
+void test_non_alloc() {
+  polymorphic_allocator<C> pa;
+  C* p = pa.allocate(1);
+  C b;
+
+  pa.construct(p);
+  VERIFY(p->type == Default);
+  pa.destroy(p);
+
+  pa.construct(p, b);
+  VERIFY(p->type == Copy);
+  pa.destroy(p);
+
+  pa.construct(p, C());
+  VERIFY(p->type == Move);
+  pa.destroy(p);
+
+  pa.construct(p, 1);
+  VERIFY(p->type == Other);
+  pa.destroy(p);
+
+  pa.deallocate(p, 1);
+}
+
+// test piecewise_construct
+template <typename A, typename B>
+void test_pair() {
+  polymorphic_allocator<std::pair<A, B>> pa;
+  std::pair<A, B>* p = pa.allocate(1);
+  std::tuple<> t;
+
+  // construct(pair<T1, T2>* p, piecewise_construct_t, tuple<...>, tuple<...>)
+  pa.construct(p, std::piecewise_construct, t, t);
+  VERIFY(p->first.type == Default);
+  VERIFY(p->second.type == Default);
+  pa.destroy(p);
+
+  // construct(pair<T1, T2>* __p)
+  pa.construct(p);
+  VERIFY(p->first.type == Default);
+  VERIFY(p->second.type == Default);
+  pa.destroy(p);
+
+  // construct(pair<T1, T2>* p, U&& x, V&& y)
+  A a; B b;
+  pa.construct(p, a, b);
+  VERIFY(p->first.type == Copy);
+  VERIFY(p->second.type == Copy);
+  pa.destroy(p);
+
+  pa.construct(p, A(), B());
+  VERIFY(p->first.type == Move);
+  VERIFY(p->second.type == Move);
+  auto pp = *p;
+  pa.destroy(p);
+
+  // construct(pair<T1, T2>* p, const pair<U, V>& x)
+  pa.construct(p, pp);
+  VERIFY(p->first.type == Copy);
+  VERIFY(p->second.type == Copy);
+  pa.destroy(p);
+
+  // construct(pair<T1, T2>* p, pair<U, V>&& x)
+  pa.construct(p, std::move(pp));
+  VERIFY(p->first.type == Move);
+  VERIFY(p->second.type == Move);
+  pa.destroy(p);
+  pa.deallocate(p, 1);
+}
+
+void test01() {
+  test_uses_alloc<A>();
+  test_uses_alloc<B>();
+  test_non_alloc<C>();
+}
+
+void test02() {
+  test_pair<A, A>();
+  test_pair<A, B>();
+  test_pair<A, C>();
+  test_pair<B, B>();
+  test_pair<B, A>();
+  test_pair<B, C>();
+  test_pair<C, C>();
+}
+
+
+int main() {
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/uses_allocator.cc b/libstdc++-v3/testsuite/experimental/type_erased_allocator/uses_allocator.cc
new file mode 100644
index 0000000..fc8acf1
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/type_erased_allocator/uses_allocator.cc
@@ -0,0 +1,22 @@
+#include <bits/uses_allocator.h>
+#include <vector>
+#include <experimental/utility>
+#include <memory>
+
+using std::vector;
+using std::allocator;
+using std::uses_allocator;
+
+struct A {
+  using allocator_type = std::experimental::erased_type;
+};
+
+void test01() {
+    static_assert(uses_allocator<vector<int>, allocator<int>>());
+    static_assert(uses_allocator<A, allocator<A>>());
+}
+
+int main() {
+  test01();
+  return 0;
+}

[-- Attachment #3: patch2.txt --]
[-- Type: text/plain, Size: 12943 bytes --]

commit 1517d0b9bf4a246302a156d2f648799c62d7e784
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Nov 11 19:28:40 2015 +0000

    Define alias templates using polymorphic memory resources
    
    	* include/Makefile.am: Add new header.
    	* include/Makefile.in: Regenerate.
    	* include/experimental/memory_resource: Add feature-test macro.
    	* include/experimental/regex: New.
    	* include/experimental/deque: Add alias template using PMR.
    	* include/experimental/forward_list: Likewise.
    	* include/experimental/list: Likewise.
    	* include/experimental/map: Likewise.
    	* include/experimental/set: Likewise.
    	* include/experimental/string: Likewise.
    	* include/experimental/unordered_map: Likewise.
    	* include/experimental/unordered_set: Likewise.
    	* include/experimental/vector: Likewise.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index ee9b6d8..67d8379 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -661,6 +661,7 @@ experimental_headers = \
 	${experimental_srcdir}/optional \
 	${experimental_srcdir}/propagate_const \
 	${experimental_srcdir}/ratio \
+	${experimental_srcdir}/regex \
 	${experimental_srcdir}/set \
 	${experimental_srcdir}/string \
 	${experimental_srcdir}/string_view \
diff --git a/libstdc++-v3/include/experimental/deque b/libstdc++-v3/include/experimental/deque
index 8d3d895..7214993 100644
--- a/libstdc++-v3/include/experimental/deque
+++ b/libstdc++-v3/include/experimental/deque
@@ -37,6 +37,7 @@
 
 #include <deque>
 #include <algorithm>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -63,6 +64,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    using deque = std::deque<_Tp, polymorphic_allocator<_Tp>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/forward_list b/libstdc++-v3/include/experimental/forward_list
index e7e6b33..bceaccc 100644
--- a/libstdc++-v3/include/experimental/forward_list
+++ b/libstdc++-v3/include/experimental/forward_list
@@ -36,6 +36,7 @@
 #else
 
 #include <forward_list>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -59,6 +60,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    using forward_list = std::forward_list<_Tp, polymorphic_allocator<_Tp>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/list b/libstdc++-v3/include/experimental/list
index 41d6e1d..4209d0e 100644
--- a/libstdc++-v3/include/experimental/list
+++ b/libstdc++-v3/include/experimental/list
@@ -36,6 +36,7 @@
 #else
 
 #include <list>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -59,6 +60,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    using list = std::list<_Tp, polymorphic_allocator<_Tp>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/map b/libstdc++-v3/include/experimental/map
index 89bf260..757065a 100644
--- a/libstdc++-v3/include/experimental/map
+++ b/libstdc++-v3/include/experimental/map
@@ -37,6 +37,7 @@
 
 #include <map>
 #include <experimental/bits/erase_if.h>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -59,6 +60,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { __detail::__erase_nodes_if(__cont, __pred); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Key, typename _Tp, typename _Compare = less<_Key>>
+    using map
+      = std::map<_Key, _Tp, _Compare,
+		 polymorphic_allocator<pair<const _Key, _Tp>>>;
+
+  template<typename _Key, typename _Tp, typename _Compare = less<_Key>>
+    using multimap
+      = std::multimap<_Key, _Tp, _Compare,
+		      polymorphic_allocator<pair<const _Key, _Tp>>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 5c8cbd6..983b211 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -41,6 +41,8 @@ inline namespace fundamentals_v2 {
 namespace pmr {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#define __cpp_lib_experimental_memory_resources 201402L
+
   class memory_resource;
 
   template <typename _Tp>
diff --git a/libstdc++-v3/include/experimental/regex b/libstdc++-v3/include/experimental/regex
new file mode 100644
index 0000000..44ebf68
--- /dev/null
+++ b/libstdc++-v3/include/experimental/regex
@@ -0,0 +1,72 @@
+// <experimental/regex> -*- C++ -*-
+
+// Copyright (C) 2015 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 experimental/regex
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_REGEX
+#define _GLIBCXX_EXPERIMENTAL_REGEX 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+#include <regex>
+#include <experimental/string>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+inline namespace fundamentals_v2
+{
+namespace pmr
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+
+  template<typename _BidirectionalIterator>
+    using match_results
+      = std::match_results<_BidirectionalIterator, polymorphic_allocator<
+			     sub_match<_BidirectionalIterator>>>;
+
+  typedef match_results<const char*> cmatch;
+  typedef match_results<const wchar_t*> wcmatch;
+  typedef match_results<string::const_iterator> smatch;
+  typedef match_results<wstring::const_iterator> wsmatch;
+
+_GLIBCXX_END_NAMESPACE_CXX11
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+#endif // C++14
+
+#endif // _GLIBCXX_EXPERIMENTAL_REGEX
diff --git a/libstdc++-v3/include/experimental/set b/libstdc++-v3/include/experimental/set
index 709fe32..be2f213 100644
--- a/libstdc++-v3/include/experimental/set
+++ b/libstdc++-v3/include/experimental/set
@@ -37,6 +37,7 @@
 
 #include <set>
 #include <experimental/bits/erase_if.h>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -59,6 +60,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { __detail::__erase_nodes_if(__cont, __pred); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Key, typename _Compare = less<_Key>>
+    using set = std::set<_Key, _Compare, polymorphic_allocator<_Key>>;
+
+  template<typename _Key, typename _Compare = less<_Key>>
+    using multiset = std::multiset<_Key, _Compare,
+				   polymorphic_allocator<_Key>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/string b/libstdc++-v3/include/experimental/string
index 2a04ce0d..3549c09 100644
--- a/libstdc++-v3/include/experimental/string
+++ b/libstdc++-v3/include/experimental/string
@@ -37,6 +37,7 @@
 
 #include <string>
 #include <algorithm>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -64,6 +65,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+
+  // basic_string using polymorphic allocator in namespace pmr
+  template<typename _CharT, typename _Traits = char_traits<_CharT>>
+   using basic_string =
+     std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
+
+  // basic_string typedef names using polymorphic allocator in namespace
+  // std::experimental::pmr
+  typedef basic_string<char> string;
+  typedef basic_string<char16_t> u16string;
+  typedef basic_string<char32_t> u32string;
+  typedef basic_string<wchar_t> wstring;
+
+_GLIBCXX_END_NAMESPACE_CXX11
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/unordered_map b/libstdc++-v3/include/experimental/unordered_map
index c80c382..9fb14e7 100644
--- a/libstdc++-v3/include/experimental/unordered_map
+++ b/libstdc++-v3/include/experimental/unordered_map
@@ -37,6 +37,7 @@
 
 #include <unordered_map>
 #include <experimental/bits/erase_if.h>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -61,6 +62,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { __detail::__erase_nodes_if(__cont, __pred); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+	   typename _Pred = equal_to<_Key>>
+    using unordered_map
+      = std::unordered_map<_Key, _Tp, _Hash, _Pred,
+		 polymorphic_allocator<pair<const _Key, _Tp>>>;
+
+  template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+	   typename _Pred = equal_to<_Key>>
+    using unordered_multimap
+      = std::unordered_multimap<_Key, _Tp, _Hash, _Pred,
+		      polymorphic_allocator<pair<const _Key, _Tp>>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/unordered_set b/libstdc++-v3/include/experimental/unordered_set
index 8461f9c..038d234 100644
--- a/libstdc++-v3/include/experimental/unordered_set
+++ b/libstdc++-v3/include/experimental/unordered_set
@@ -37,6 +37,7 @@
 
 #include <unordered_set>
 #include <experimental/bits/erase_if.h>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -61,6 +62,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { __detail::__erase_nodes_if(__cont, __pred); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Key, typename _Hash = hash<_Key>,
+	   typename _Pred = equal_to<_Key>>
+    using unordered_set
+      = std::unordered_set<_Key, _Hash, _Pred, polymorphic_allocator<_Key>>;
+
+  template<typename _Key, typename _Hash = hash<_Key>,
+	   typename _Pred = equal_to<_Key>>
+    using unordered_multiset
+      = std::unordered_multiset<_Key, _Hash, _Pred,
+				polymorphic_allocator<_Key>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std
diff --git a/libstdc++-v3/include/experimental/vector b/libstdc++-v3/include/experimental/vector
index 37645a1..cddb747 100644
--- a/libstdc++-v3/include/experimental/vector
+++ b/libstdc++-v3/include/experimental/vector
@@ -37,6 +37,7 @@
 
 #include <vector>
 #include <algorithm>
+#include <experimental/memory_resource>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -65,6 +66,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
+
+namespace pmr {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace pmr
+
 } // namespace fundamentals_v2
 } // namespace experimental
 } // namespace std

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-11-11 20:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-11 20:01 [v3 patch] GSoC: implement polymorphic memory resources Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).