mirror of git://gcc.gnu.org/git/gcc.git
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>
|
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
|
PR libstdc++/70966
|
||||||
* include/experimental/memory_resource (__get_default_resource): Use
|
* include/experimental/memory_resource (__get_default_resource): Use
|
||||||
placement new to create an object with dynamic storage duration.
|
placement new to create an object with dynamic storage duration.
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,12 @@
|
||||||
#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
|
#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
|
||||||
#define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1
|
#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 <new>
|
||||||
#include <atomic>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <ext/new_allocator.h>
|
#include <ext/new_allocator.h>
|
||||||
#include <experimental/bits/lfts_config.h>
|
#include <debug/assertions.h>
|
||||||
|
|
||||||
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
||||||
{
|
{
|
||||||
|
|
@ -51,39 +51,41 @@ inline namespace fundamentals_v2 {
|
||||||
namespace pmr {
|
namespace pmr {
|
||||||
#define __cpp_lib_experimental_memory_resources 201402L
|
#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
|
// Standard memory resources
|
||||||
|
|
||||||
// 8.5 Class memory_resource
|
// 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
|
class memory_resource
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
static constexpr size_t _S_max_align = alignof(max_align_t);
|
static constexpr size_t _S_max_align = alignof(max_align_t);
|
||||||
|
|
||||||
public:
|
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*
|
void*
|
||||||
allocate(size_t __bytes, size_t __alignment = _S_max_align)
|
allocate(size_t __bytes, size_t __alignment = _S_max_align)
|
||||||
|
|
@ -109,18 +111,15 @@ namespace pmr {
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
operator==(const memory_resource& __a,
|
operator==(const memory_resource& __a, const memory_resource& __b) noexcept
|
||||||
const memory_resource& __b) noexcept
|
|
||||||
{ return &__a == &__b || __a.is_equal(__b); }
|
{ return &__a == &__b || __a.is_equal(__b); }
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
operator!=(const memory_resource& __a,
|
operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
|
||||||
const memory_resource& __b) noexcept
|
|
||||||
{ return !(__a == __b); }
|
{ return !(__a == __b); }
|
||||||
|
|
||||||
|
|
||||||
// 8.6 Class template polymorphic_allocator
|
template<typename _Tp>
|
||||||
template <class _Tp>
|
|
||||||
class polymorphic_allocator
|
class polymorphic_allocator
|
||||||
{
|
{
|
||||||
using __uses_alloc1_ = __uses_alloc1<memory_resource*>;
|
using __uses_alloc1_ = __uses_alloc1<memory_resource*>;
|
||||||
|
|
@ -134,14 +133,15 @@ namespace pmr {
|
||||||
template<typename _Tp1, typename... _Args>
|
template<typename _Tp1, typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(__uses_alloc1_, _Tp1* __p, _Args&&... __args)
|
_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>
|
template<typename _Tp1, typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(__uses_alloc2_, _Tp1* __p, _Args&&... __args)
|
_M_construct(__uses_alloc2_, _Tp1* __p, _Args&&... __args)
|
||||||
{ ::new(__p) _Tp1(std::forward<_Args>(__args)...,
|
{ ::new(__p) _Tp1(std::forward<_Args>(__args)..., this->resource()); }
|
||||||
this->resource()); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = _Tp;
|
using value_type = _Tp;
|
||||||
|
|
@ -169,11 +169,13 @@ namespace pmr {
|
||||||
{ return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
|
{ return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
|
||||||
alignof(_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)); }
|
{ _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
|
||||||
|
|
||||||
template <typename _Tp1, typename... _Args> //used here
|
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();
|
memory_resource* const __resource = this->resource();
|
||||||
auto __use_tag
|
auto __use_tag
|
||||||
|
|
@ -184,9 +186,9 @@ namespace pmr {
|
||||||
// Specializations for pair using piecewise construction
|
// Specializations for pair using piecewise construction
|
||||||
template <typename _Tp1, typename _Tp2,
|
template <typename _Tp1, typename _Tp2,
|
||||||
typename... _Args1, typename... _Args2>
|
typename... _Args1, typename... _Args2>
|
||||||
void construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
|
void
|
||||||
tuple<_Args1...> __x,
|
construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
|
||||||
tuple<_Args2...> __y)
|
tuple<_Args1...> __x, tuple<_Args2...> __y)
|
||||||
{
|
{
|
||||||
memory_resource* const __resource = this->resource();
|
memory_resource* const __resource = this->resource();
|
||||||
auto __x_use_tag =
|
auto __x_use_tag =
|
||||||
|
|
@ -200,36 +202,48 @@ namespace pmr {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Tp1, typename _Tp2>
|
template <typename _Tp1, typename _Tp2>
|
||||||
void construct(pair<_Tp1,_Tp2>* __p)
|
void
|
||||||
|
construct(pair<_Tp1,_Tp2>* __p)
|
||||||
{ this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
|
{ this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
|
||||||
|
|
||||||
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||||
void construct(pair<_Tp1,_Tp2>* __p, _Up&& __x, _Vp&& __y)
|
void
|
||||||
{ this->construct(__p, piecewise_construct,
|
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<_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>
|
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||||
void construct(pair<_Tp1,_Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
|
void
|
||||||
{ this->construct(__p, piecewise_construct, forward_as_tuple(__pr.first),
|
construct(pair<_Tp1,_Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
|
||||||
forward_as_tuple(__pr.second)); }
|
{
|
||||||
|
this->construct(__p, piecewise_construct,
|
||||||
|
forward_as_tuple(__pr.first),
|
||||||
|
forward_as_tuple(__pr.second));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||||
void construct(pair<_Tp1,_Tp2>* __p, pair<_Up, _Vp>&& __pr)
|
void
|
||||||
{ this->construct(__p, piecewise_construct,
|
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<_Up>(__pr.first)),
|
||||||
forward_as_tuple(std::forward<_Vp>(__pr.second))); }
|
forward_as_tuple(std::forward<_Vp>(__pr.second)));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename _Up>
|
template <typename _Up>
|
||||||
void destroy(_Up* __p)
|
void
|
||||||
|
destroy(_Up* __p)
|
||||||
{ __p->~_Up(); }
|
{ __p->~_Up(); }
|
||||||
|
|
||||||
// Return a default-constructed allocator (no allocator propagation)
|
// 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(); }
|
{ return polymorphic_allocator(); }
|
||||||
|
|
||||||
memory_resource* resource() const
|
memory_resource* resource() const { return _M_resource; }
|
||||||
{ return _M_resource; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename _Tuple>
|
template<typename _Tuple>
|
||||||
|
|
@ -252,18 +266,21 @@ namespace pmr {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp1, class _Tp2>
|
template <class _Tp1, class _Tp2>
|
||||||
bool operator==(const polymorphic_allocator<_Tp1>& __a,
|
bool
|
||||||
const polymorphic_allocator<_Tp2>& __b) noexcept
|
operator==(const polymorphic_allocator<_Tp1>& __a,
|
||||||
|
const polymorphic_allocator<_Tp2>& __b) noexcept
|
||||||
{ return *__a.resource() == *__b.resource(); }
|
{ return *__a.resource() == *__b.resource(); }
|
||||||
|
|
||||||
template <class _Tp1, class _Tp2>
|
template <class _Tp1, class _Tp2>
|
||||||
bool operator!=(const polymorphic_allocator<_Tp1>& __a,
|
bool
|
||||||
const polymorphic_allocator<_Tp2>& __b) noexcept
|
operator!=(const polymorphic_allocator<_Tp1>& __a,
|
||||||
|
const polymorphic_allocator<_Tp2>& __b) noexcept
|
||||||
{ return !(__a == __b); }
|
{ return !(__a == __b); }
|
||||||
|
|
||||||
|
|
||||||
class __resource_adaptor_common
|
class __resource_adaptor_common
|
||||||
{
|
{
|
||||||
template<typename> friend class __resource_adaptor_imp;
|
template<typename, typename> friend class __resource_adaptor_imp;
|
||||||
|
|
||||||
struct _AlignMgr
|
struct _AlignMgr
|
||||||
{
|
{
|
||||||
|
|
@ -376,10 +393,12 @@ namespace pmr {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 8.7.1 __resource_adaptor_imp
|
// 8.7.1 __resource_adaptor_imp
|
||||||
template <typename _Alloc>
|
template<typename _Alloc, typename _Resource>
|
||||||
class __resource_adaptor_imp
|
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,
|
static_assert(is_same<char,
|
||||||
typename allocator_traits<_Alloc>::value_type>::value,
|
typename allocator_traits<_Alloc>::value_type>::value,
|
||||||
"Allocator's value_type is char");
|
"Allocator's value_type is char");
|
||||||
|
|
@ -514,11 +533,11 @@ namespace pmr {
|
||||||
__r = new_delete_resource();
|
__r = new_delete_resource();
|
||||||
return __get_default_resource().exchange(__r);
|
return __get_default_resource().exchange(__r);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pmr
|
} // namespace pmr
|
||||||
} // namespace fundamentals_v2
|
} // namespace fundamentals_v2
|
||||||
} // namespace experimental
|
} // namespace experimental
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
#endif // _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
|
||||||
#endif
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue