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:
parent
0568ade6f8
commit
7a4be38049
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue