66 static constexpr size_t _S_max_align =
alignof(max_align_t);
69 memory_resource() =
default;
70 memory_resource(
const memory_resource&) =
default;
71 virtual ~memory_resource();
73 memory_resource& operator=(
const memory_resource&) =
default;
77 allocate(
size_t __bytes,
size_t __alignment = _S_max_align)
78 __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
79 { return ::operator
new(__bytes, do_allocate(__bytes, __alignment)); }
82 deallocate(
void* __p,
size_t __bytes,
size_t __alignment = _S_max_align)
83 __attribute__((__nonnull__))
84 {
return do_deallocate(__p, __bytes, __alignment); }
88 is_equal(
const memory_resource& __other)
const noexcept
89 {
return do_is_equal(__other); }
93 do_allocate(
size_t __bytes,
size_t __alignment) = 0;
96 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment) = 0;
99 do_is_equal(
const memory_resource& __other)
const noexcept = 0;
123 class polymorphic_allocator
127 template<
typename _Up>
128 struct __not_pair {
using type = void; };
130 template<
typename _Up1,
typename _Up2>
131 struct __not_pair<
pair<_Up1, _Up2>> { };
134 using value_type = _Tp;
136 polymorphic_allocator()
noexcept
139 __attribute__((__returns_nonnull__));
144 __attribute__((__nonnull__))
146 { _GLIBCXX_DEBUG_ASSERT(__r); }
148 polymorphic_allocator(
const polymorphic_allocator& __other) =
default;
150 template<
typename _Up>
151 polymorphic_allocator(
const polymorphic_allocator<_Up>& __x) noexcept
152 : _M_resource(__x.resource())
155 polymorphic_allocator&
156 operator=(
const polymorphic_allocator&) =
delete;
161 __attribute__((__returns_nonnull__))
163 if ((__gnu_cxx::__int_traits<size_t>::__max /
sizeof(_Tp)) < __n)
164 std::__throw_bad_array_new_length();
165 return static_cast<_Tp*
>(_M_resource->allocate(__n *
sizeof(_Tp),
170 deallocate(_Tp* __p,
size_t __n)
noexcept
171 __attribute__((__nonnull__))
172 { _M_resource->deallocate(__p, __n *
sizeof(_Tp),
alignof(_Tp)); }
174#ifdef __glibcxx_polymorphic_allocator
176 allocate_bytes(
size_t __nbytes,
177 size_t __alignment =
alignof(max_align_t))
178 {
return _M_resource->allocate(__nbytes, __alignment); }
181 deallocate_bytes(
void* __p,
size_t __nbytes,
182 size_t __alignment =
alignof(max_align_t))
183 { _M_resource->deallocate(__p, __nbytes, __alignment); }
185 template<
typename _Up>
187 allocate_object(
size_t __n = 1)
189 if ((__gnu_cxx::__int_traits<size_t>::__max /
sizeof(_Up)) < __n)
190 std::__throw_bad_array_new_length();
191 return static_cast<_Up*
>(allocate_bytes(__n *
sizeof(_Up),
195 template<
typename _Up>
197 deallocate_object(_Up* __p,
size_t __n = 1)
198 { deallocate_bytes(__p, __n *
sizeof(_Up),
alignof(_Up)); }
200 template<
typename _Up,
typename... _CtorArgs>
202 new_object(_CtorArgs&&... __ctor_args)
204 _Up* __p = allocate_object<_Up>();
211 deallocate_object(__p);
212 __throw_exception_again;
217 template<
typename _Up>
219 delete_object(_Up* __p)
222 deallocate_object(__p);
226#if ! __glibcxx_make_obj_using_allocator
227 template<
typename _Tp1,
typename... _Args>
228 __attribute__((__nonnull__))
229 typename __not_pair<_Tp1>::type
230 construct(_Tp1* __p, _Args&&... __args)
235 = std::__uses_alloc_t<_Tp1, polymorphic_allocator, _Args...>;
236 if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)
238 else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)
239 ::new(__p) _Tp1(allocator_arg, *
this,
245 template<
typename _Tp1,
typename _Tp2,
246 typename... _Args1,
typename... _Args2>
247 __attribute__((__nonnull__))
253 __use_alloc<_Tp1, polymorphic_allocator, _Args1...>(*this);
255 __use_alloc<_Tp2, polymorphic_allocator, _Args2...>(*this);
260 _S_construct_p(__x_tag, __x_i, __x),
261 _S_construct_p(__y_tag, __y_i, __y));
264 template<
typename _Tp1,
typename _Tp2>
265 __attribute__((__nonnull__))
270 template<
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
271 __attribute__((__nonnull__))
280 template <
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
281 __attribute__((__nonnull__))
290 template<
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
291 __attribute__((__nonnull__))
300 template<
typename _Tp1,
typename... _Args>
301 __attribute__((__nonnull__))
303 construct(_Tp1* __p, _Args&&... __args)
305 std::uninitialized_construct_using_allocator(__p, *
this,
310 template<
typename _Up>
311 __attribute__((__nonnull__))
316 polymorphic_allocator
317 select_on_container_copy_construction()
const noexcept
318 {
return polymorphic_allocator(); }
321 resource()
const noexcept
322 __attribute__((__returns_nonnull__))
323 {
return _M_resource; }
329 operator==(
const polymorphic_allocator& __a,
330 const polymorphic_allocator& __b)
noexcept
331 {
return *__a.resource() == *__b.resource(); }
333#if __cpp_impl_three_way_comparison < 201907L
336 operator!=(
const polymorphic_allocator& __a,
337 const polymorphic_allocator& __b)
noexcept
338 {
return !(__a == __b); }
342#if ! __glibcxx_make_obj_using_allocator
343 using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
344 using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
346 template<
typename _Ind,
typename... _Args>
347 static tuple<_Args&&...>
351 template<
size_t... _Ind,
typename... _Args>
352 static tuple<allocator_arg_t, polymorphic_allocator, _Args&&...>
357 allocator_arg, *__ua._M_a, std::get<_Ind>(
std::move(__t))...
361 template<
size_t... _Ind,
typename... _Args>
362 static tuple<_Args&&..., polymorphic_allocator>
365 {
return { std::get<_Ind>(
std::move(__t))..., *__ua._M_a }; }