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.

From-SVN: r262944
This commit is contained in:
Jonathan Wakely 2018-07-24 14:03:20 +01:00 committed by Jonathan Wakely
parent 0568ade6f8
commit 7a4be38049
2 changed files with 93 additions and 67 deletions

View File

@ -1,5 +1,12 @@
2018-07-24 Jonathan Wakely <jwakely@redhat.com>
* 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.
PR libstdc++/70966
* include/experimental/memory_resource (__get_default_resource): Use
placement new to create an object with dynamic storage duration.

View File

@ -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