Make __resource_adaptor_imp usable with C++17 memory_resource

Message ID 20180724130637.GA12085@redhat.com
State New
Headers show
Series
  • Make __resource_adaptor_imp usable with C++17 memory_resource
Related show

Commit Message

Jonathan Wakely July 24, 2018, 1:06 p.m.
By making the memory_resource base class a template parameter the
__resource_adaptor_imp can be used to adapt an allocator into a
std::pmr::memory_resource instead of experimental::pmr::memory_resource.

No uses for this in the library but somebody might want to do it, and
it costs us nothing to support.

	* include/experimental/memory_resource: Adjust comments and
	whitespace.
	(__resource_adaptor_imp): Add second template parameter for type of
	memory resource base class.
	(memory_resource): Define default constructor, destructor, copy
	constructor and copy assignment operator as defaulted.

Tested powerpc64le-linux, committed to trunk.
commit ce04fa1c00b40a938cc25a264836a2e30149056e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jul 24 12:24:53 2018 +0100

    Make __resource_adaptor_imp usable with C++17 memory_resource
    
    By making the memory_resource base class a template parameter the
    __resource_adaptor_imp can be used to adapt an allocator into a
    std::pmr::memory_resource instead of experimental::pmr::memory_resource.
    
            * include/experimental/memory_resource: Adjust comments and
            whitespace.
            (__resource_adaptor_imp): Add second template parameter for type of
            memory resource base class.
            (memory_resource): Define default constructor, destructor, copy
            constructor and copy assignment operator as defaulted.

Comments

Jonathan Wakely July 25, 2018, 5:24 p.m. | #1
On 24/07/18 14:06 +0100, Jonathan Wakely wrote:
>By making the memory_resource base class a template parameter the

>__resource_adaptor_imp can be used to adapt an allocator into a

>std::pmr::memory_resource instead of experimental::pmr::memory_resource.

>

>No uses for this in the library but somebody might want to do it, and

>it costs us nothing to support.

>

>	* include/experimental/memory_resource: Adjust comments and

>	whitespace.

>	(__resource_adaptor_imp): Add second template parameter for type of

>	memory resource base class.

>	(memory_resource): Define default constructor, destructor, copy

>	constructor and copy assignment operator as defaulted.

>

>Tested powerpc64le-linux, committed to trunk.

>


>commit ce04fa1c00b40a938cc25a264836a2e30149056e

>Author: Jonathan Wakely <jwakely@redhat.com>

>Date:   Tue Jul 24 12:24:53 2018 +0100

>

>    Make __resource_adaptor_imp usable with C++17 memory_resource

>

>    By making the memory_resource base class a template parameter the

>    __resource_adaptor_imp can be used to adapt an allocator into a

>    std::pmr::memory_resource instead of experimental::pmr::memory_resource.

>

>            * include/experimental/memory_resource: Adjust comments and

>            whitespace.

>            (__resource_adaptor_imp): Add second template parameter for type of

>            memory resource base class.

>            (memory_resource): Define default constructor, destructor, copy

>            constructor and copy assignment operator as defaulted.

>

>diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource

>index 83379d1367a..7ce64457a11 100644

>--- a/libstdc++-v3/include/experimental/memory_resource

>+++ b/libstdc++-v3/include/experimental/memory_resource

>@@ -29,12 +29,12 @@

> #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE

> #define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1

>

>-#include <memory>

>+#include <memory>			// align, uses_allocator, __uses_alloc

>+#include <experimental/utility>		// pair, experimental::erased_type

>+#include <atomic>			// atomic

> #include <new>

>-#include <atomic>

>-#include <cstddef>

> #include <ext/new_allocator.h>

>-#include <experimental/bits/lfts_config.h>

>+#include <debug/assertions.h>


I should not have removed <cstddef> here, it's needed for
std::max_align_t.

Committed to trunk as obvious.
commit 5258907ab3e829b75a70872e9d6f627461c84176
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jul 25 18:20:29 2018 +0100

    Add missing header for std::max_align_t
    
            * include/experimental/memory_resource: Include <cstddef> header.

diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 7ce64457a11..61c9ce0a14a 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -32,7 +32,8 @@
 #include <memory>			// align, uses_allocator, __uses_alloc
 #include <experimental/utility>		// pair, experimental::erased_type
 #include <atomic>			// atomic
-#include <new>
+#include <new>				// placement new
+#include <cstddef>			// max_align_t
 #include <ext/new_allocator.h>
 #include <debug/assertions.h>

Patch

diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 83379d1367a..7ce64457a11 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -29,12 +29,12 @@ 
 #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
 #define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1
 
-#include <memory>
+#include <memory>			// align, uses_allocator, __uses_alloc
+#include <experimental/utility>		// pair, experimental::erased_type
+#include <atomic>			// atomic
 #include <new>
-#include <atomic>
-#include <cstddef>
 #include <ext/new_allocator.h>
-#include <experimental/bits/lfts_config.h>
+#include <debug/assertions.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
@@ -51,39 +51,41 @@  inline namespace fundamentals_v2 {
 namespace pmr {
 #define __cpp_lib_experimental_memory_resources 201402L
 
-  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;
+
+  // 8.6 Class template polymorphic_allocator
+  template<typename _Tp>
+    class polymorphic_allocator;
+
+  template<typename _Alloc, typename _Resource = memory_resource>
+    class __resource_adaptor_imp;
+
+  // 8.7 Alias template resource_adaptor
+  template<typename _Alloc>
+    using resource_adaptor = __resource_adaptor_imp<
+      typename allocator_traits<_Alloc>::template rebind_alloc<char>>;
+
+  // 8.8 Global memory resources
+  memory_resource* new_delete_resource() noexcept;
+  memory_resource* null_memory_resource() noexcept;
+  memory_resource* get_default_resource() noexcept;
+  memory_resource* set_default_resource(memory_resource* __r) noexcept;
+
+  // TODO 8.9 Pool resource classes
+
   class memory_resource
   {
-  protected:
     static constexpr size_t _S_max_align = alignof(max_align_t);
 
   public:
-    virtual ~memory_resource() { }
+    memory_resource() = default;
+    memory_resource(const memory_resource&) = default;
+    virtual ~memory_resource() = default;
+
+    memory_resource& operator=(const memory_resource&) = default;
 
     void*
     allocate(size_t __bytes, size_t __alignment = _S_max_align)
@@ -109,18 +111,15 @@  namespace pmr {
   };
 
   inline bool
-  operator==(const memory_resource& __a,
-	     const memory_resource& __b) noexcept
+  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
+  operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
   { return !(__a == __b); }
 
 
-  // 8.6 Class template polymorphic_allocator
-  template <class _Tp>
+  template<typename _Tp>
     class polymorphic_allocator
     {
       using __uses_alloc1_ = __uses_alloc1<memory_resource*>;
@@ -134,14 +133,15 @@  namespace pmr {
       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)...); }
+	{
+	  ::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()); }
+	{ ::new(__p) _Tp1(std::forward<_Args>(__args)..., this->resource()); }
 
     public:
       using value_type = _Tp;
@@ -169,11 +169,13 @@  namespace pmr {
       { return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
 						       alignof(_Tp))); }
 
-      void deallocate(_Tp* __p, size_t __n)
+      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)
+	void
+	construct(_Tp1* __p, _Args&&... __args)
 	{
 	  memory_resource* const __resource = this->resource();
 	  auto __use_tag
@@ -184,9 +186,9 @@  namespace pmr {
       // 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)
+	void
+	construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
+		  tuple<_Args1...> __x, tuple<_Args2...> __y)
 	{
 	  memory_resource* const __resource = this->resource();
 	  auto __x_use_tag =
@@ -200,36 +202,48 @@  namespace pmr {
 	}
 
       template <typename _Tp1, typename _Tp2>
-	void construct(pair<_Tp1,_Tp2>* __p)
+	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,
+	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))); }
+			  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)); }
+	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,
+	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))); }
+			  forward_as_tuple(std::forward<_Vp>(__pr.second)));
+	}
 
       template <typename _Up>
-	void destroy(_Up* __p)
+	void
+	destroy(_Up* __p)
 	{ __p->~_Up(); }
 
       // Return a default-constructed allocator (no allocator propagation)
-      polymorphic_allocator select_on_container_copy_construction() const
+      polymorphic_allocator
+      select_on_container_copy_construction() const
       { return polymorphic_allocator(); }
 
-      memory_resource* resource() const
-      { return _M_resource; }
+      memory_resource* resource() const { return _M_resource; }
 
     private:
       template<typename _Tuple>
@@ -252,18 +266,21 @@  namespace pmr {
     };
 
   template <class _Tp1, class _Tp2>
-    bool operator==(const polymorphic_allocator<_Tp1>& __a,
-		    const polymorphic_allocator<_Tp2>& __b) noexcept
+    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
+    bool
+    operator!=(const polymorphic_allocator<_Tp1>& __a,
+	       const polymorphic_allocator<_Tp2>& __b) noexcept
     { return !(__a == __b); }
 
+
   class __resource_adaptor_common
   {
-    template<typename> friend class __resource_adaptor_imp;
+    template<typename, typename> friend class __resource_adaptor_imp;
 
     struct _AlignMgr
     {
@@ -376,10 +393,12 @@  namespace pmr {
   };
 
   // 8.7.1 __resource_adaptor_imp
-  template <typename _Alloc>
+  template<typename _Alloc, typename _Resource>
     class __resource_adaptor_imp
-    : public memory_resource, private __resource_adaptor_common
+    : public _Resource, private __resource_adaptor_common
     {
+      using memory_resource = _Resource;
+
       static_assert(is_same<char,
 	  typename allocator_traits<_Alloc>::value_type>::value,
 	  "Allocator's value_type is char");
@@ -514,11 +533,11 @@  namespace pmr {
       __r = new_delete_resource();
     return __get_default_resource().exchange(__r);
   }
+
 } // namespace pmr
 } // namespace fundamentals_v2
 } // namespace experimental
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-
-#endif
+#endif // _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE