30#ifndef _ALLOC_TRAITS_H
31#define _ALLOC_TRAITS_H 1
35#if __cplusplus >= 201103L
43namespace std _GLIBCXX_VISIBILITY(default)
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
47#if __cplusplus >= 201103L
49 struct __allocator_traits_base
51 template<
typename _Tp,
typename _Up,
typename =
void>
52 struct __rebind : __replace_first_arg<_Tp, _Up>
54 static_assert(is_same<
55 typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
57 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
60 template<
typename _Tp,
typename _Up>
61 struct __rebind<_Tp, _Up,
62 __void_t<typename _Tp::template rebind<_Up>::other>>
64 using type =
typename _Tp::template rebind<_Up>::other;
66 static_assert(is_same<
67 typename _Tp::template rebind<typename _Tp::value_type>::other,
69 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
73 template<
typename _Tp>
74 using __pointer =
typename _Tp::pointer;
75 template<
typename _Tp>
76 using __c_pointer =
typename _Tp::const_pointer;
77 template<
typename _Tp>
78 using __v_pointer =
typename _Tp::void_pointer;
79 template<
typename _Tp>
80 using __cv_pointer =
typename _Tp::const_void_pointer;
81 template<
typename _Tp>
82 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
83 template<
typename _Tp>
84 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
85 template<
typename _Tp>
86 using __pocs =
typename _Tp::propagate_on_container_swap;
87 template<
typename _Tp>
88 using __equal = __type_identity<typename _Tp::is_always_equal>;
91 template<
typename _Alloc,
typename _Up>
93 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
102 template<
typename _Alloc>
115 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
119 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
125 template<
template<
typename>
class _Func,
typename _Tp>
126 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
128 using type = _Func<_Alloc>;
132 template<
typename _A2,
typename _PtrT,
typename =
void>
134 {
using type =
typename pointer_traits<_PtrT>::difference_type; };
136 template<
typename _A2,
typename _PtrT>
138 {
using type =
typename _A2::difference_type; };
141 template<
typename _A2,
typename _DiffT,
typename =
void>
142 struct _Size : make_unsigned<_DiffT> { };
144 template<
typename _A2,
typename _DiffT>
145 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
146 {
using type =
typename _A2::size_type; };
187 using size_type =
typename _Size<_Alloc, difference_type>::type;
196 = __detected_or_t<false_type, __pocca, _Alloc>;
205 = __detected_or_t<false_type, __pocma, _Alloc>;
214 = __detected_or_t<false_type, __pocs, _Alloc>;
223 =
typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
225 template<
typename _Tp>
226 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
227 template<
typename _Tp>
231 template<
typename _Alloc2>
232 static constexpr auto
234 ->
decltype(__a.allocate(__n, __hint))
235 {
return __a.
allocate(__n, __hint); }
237 template<
typename _Alloc2>
240 {
return __a.allocate(__n); }
242 template<
typename _Tp,
typename... _Args>
243 struct __construct_helper
245 template<
typename _Alloc2,
246 typename =
decltype(std::declval<_Alloc2*>()->construct(
247 std::declval<_Tp*>(), std::declval<_Args>()...))>
253 using type =
decltype(__test<_Alloc>(0));
256 template<
typename _Tp,
typename... _Args>
257 using __has_construct
258 =
typename __construct_helper<_Tp, _Args...>::type;
260 template<
typename _Tp,
typename... _Args>
261 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
262 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
263 noexcept(
noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
264 { __a.construct(__p, std::forward<_Args>(__args)...); }
266 template<
typename _Tp,
typename... _Args>
267 static _GLIBCXX14_CONSTEXPR
268 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
269 is_constructible<_Tp, _Args...>>>
270 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
273#if __cplusplus <= 201703L
274 ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...);
276 std::construct_at(__p, std::forward<_Args>(__args)...);
280 template<
typename _Alloc2,
typename _Tp>
281 static _GLIBCXX14_CONSTEXPR
auto
282 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
283 noexcept(
noexcept(__a.destroy(__p)))
284 ->
decltype(__a.destroy(__p))
285 { __a.destroy(__p); }
287 template<
typename _Alloc2,
typename _Tp>
288 static _GLIBCXX14_CONSTEXPR
void
289 _S_destroy(_Alloc2&, _Tp* __p, ...)
290 noexcept(
std::is_nothrow_destructible<_Tp>::value)
293 template<
typename _Alloc2>
294 static constexpr auto
295 _S_max_size(_Alloc2& __a,
int)
296 ->
decltype(__a.max_size())
297 {
return __a.max_size(); }
299 template<
typename _Alloc2>
301 _S_max_size(_Alloc2&, ...)
305 return __gnu_cxx::__numeric_traits<size_type>::__max
309 template<
typename _Alloc2>
310 static constexpr auto
311 _S_select(_Alloc2& __a,
int)
312 ->
decltype(__a.select_on_container_copy_construction())
313 {
return __a.select_on_container_copy_construction(); }
315 template<
typename _Alloc2>
316 static constexpr _Alloc2
317 _S_select(_Alloc2& __a, ...)
329 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
331 {
return __a.allocate(__n); }
344 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
346 {
return _S_allocate(__a, __n, __hint, 0); }
356 static _GLIBCXX20_CONSTEXPR
void
358 { __a.deallocate(__p, __n); }
371 template<
typename _Tp,
typename... _Args>
372 static _GLIBCXX20_CONSTEXPR
auto
374 noexcept(
noexcept(_S_construct(__a, __p,
375 std::forward<_Args>(__args)...)))
376 ->
decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
377 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
387 template<
typename _Tp>
388 static _GLIBCXX20_CONSTEXPR
void
390 noexcept(
noexcept(_S_destroy(__a, __p, 0)))
391 { _S_destroy(__a, __p, 0); }
403 {
return _S_max_size(__a, 0); }
413 static _GLIBCXX20_CONSTEXPR _Alloc
415 {
return _S_select(__rhs, 0); }
420 template<
typename _Tp>
459 template<
typename _Up>
462 template<
typename _Up>
472 [[__nodiscard__,__gnu__::__always_inline__]]
473 static _GLIBCXX20_CONSTEXPR
pointer
475 {
return __a.allocate(__n); }
487 [[__nodiscard__,__gnu__::__always_inline__]]
488 static _GLIBCXX20_CONSTEXPR
pointer
492#if __cplusplus <= 201703L
493 return __a.allocate(__n, __hint);
495 return __a.allocate(__n);
507 [[__gnu__::__always_inline__]]
508 static _GLIBCXX20_CONSTEXPR
void
510 { __a.deallocate(__p, __n); }
523 template<
typename _Up,
typename... _Args>
524 [[__gnu__::__always_inline__]]
525 static _GLIBCXX20_CONSTEXPR
void
530#if __cplusplus <= 201703L
531 __a.construct(__p, std::forward<_Args>(__args)...);
533 std::construct_at(__p, std::forward<_Args>(__args)...);
544 template<
typename _Up>
545 [[__gnu__::__always_inline__]]
546 static _GLIBCXX20_CONSTEXPR
void
550#if __cplusplus <= 201703L
553 std::destroy_at(__p);
562 [[__gnu__::__always_inline__]]
566#if __cplusplus <= 201703L
567 return __a.max_size();
578 [[__gnu__::__always_inline__]]
624 template<
typename _Up>
627 template<
typename _Up>
649 template<
typename _Up,
typename... _Args>
650 [[__gnu__::__always_inline__]]
651 static _GLIBCXX20_CONSTEXPR
void
663 template<
typename _Up>
664 [[__gnu__::__always_inline__]]
665 static _GLIBCXX20_CONSTEXPR
void
679 [[__gnu__::__always_inline__]]
687#if __cplusplus < 201703L
688 template<
typename _Alloc>
689 [[__gnu__::__always_inline__]]
691 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
694 template<
typename _Alloc>
695 [[__gnu__::__always_inline__]]
697 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
701 template<
typename _Alloc>
702 [[__gnu__::__always_inline__]]
703 _GLIBCXX14_CONSTEXPR
inline void
704 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
706 using __traits = allocator_traits<_Alloc>;
708 typename __traits::propagate_on_container_copy_assignment::type;
709#if __cplusplus >= 201703L
710 if constexpr (__pocca::value)
713 __do_alloc_on_copy(__one, __two, __pocca());
717 template<
typename _Alloc>
718 [[__gnu__::__always_inline__]]
720 __alloc_on_copy(
const _Alloc& __a)
722 typedef allocator_traits<_Alloc> __traits;
723 return __traits::select_on_container_copy_construction(__a);
726#if __cplusplus < 201703L
727 template<
typename _Alloc>
728 [[__gnu__::__always_inline__]]
729 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
732 template<
typename _Alloc>
733 [[__gnu__::__always_inline__]]
734 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
738 template<
typename _Alloc>
739 [[__gnu__::__always_inline__]]
740 _GLIBCXX14_CONSTEXPR
inline void
741 __alloc_on_move(_Alloc& __one, _Alloc& __two)
743 using __traits = allocator_traits<_Alloc>;
745 =
typename __traits::propagate_on_container_move_assignment::type;
746#if __cplusplus >= 201703L
747 if constexpr (__pocma::value)
750 __do_alloc_on_move(__one, __two, __pocma());
754#if __cplusplus < 201703L
755 template<
typename _Alloc>
756 [[__gnu__::__always_inline__]]
757 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
763 template<
typename _Alloc>
764 [[__gnu__::__always_inline__]]
765 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
769 template<
typename _Alloc>
770 [[__gnu__::__always_inline__]]
771 _GLIBCXX14_CONSTEXPR
inline void
772 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
774 using __traits = allocator_traits<_Alloc>;
775 using __pocs =
typename __traits::propagate_on_container_swap::type;
776#if __cplusplus >= 201703L
777 if constexpr (__pocs::value)
783 __do_alloc_on_swap(__one, __two, __pocs());
787 template<
typename _Alloc,
typename _Tp,
788 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
790 struct __is_alloc_insertable_impl
794 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
795 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
796 __void_t<decltype(allocator_traits<_Alloc>::construct(
797 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
798 std::declval<_Tp>()))>>
805 template<
typename _Alloc>
806 struct __is_copy_insertable
807 : __is_alloc_insertable_impl<_Alloc,
808 typename _Alloc::value_type const&>::type
813 template<
typename _Tp>
814 struct __is_copy_insertable<allocator<_Tp>>
815 : is_copy_constructible<_Tp>
822 template<
typename _Alloc>
823 struct __is_move_insertable
824 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
829 template<
typename _Tp>
830 struct __is_move_insertable<allocator<_Tp>>
831 : is_move_constructible<_Tp>
836 template<
typename _Alloc,
typename =
void>
839 template<
typename _Alloc>
840 struct __is_allocator<_Alloc,
841 __void_t<typename _Alloc::value_type,
842 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
845 template<
typename _Alloc>
846 using _RequireAllocator
847 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
849 template<
typename _Alloc>
850 using _RequireNotAllocator
851 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
853#if __cpp_concepts >= 201907L
854 template<
typename _Alloc>
855 concept __allocator_like =
requires (_Alloc& __a) {
856 typename _Alloc::value_type;
857 __a.deallocate(__a.allocate(1u), 1u);
866 template<
typename _Alloc,
bool = __is_empty(_Alloc)>
868 {
static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
870 template<
typename _Alloc>
871 struct __alloc_swap<_Alloc, false>
874 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
882#if __cplusplus >= 201103L
883 template<
typename _Tp,
bool
884 = __or_<is_copy_constructible<typename _Tp::value_type>,
885 is_nothrow_move_constructible<typename _Tp::value_type>>::value>
886 struct __shrink_to_fit_aux
887 {
static bool _S_do_it(_Tp&)
noexcept {
return false; } };
889 template<
typename _Tp>
890 struct __shrink_to_fit_aux<_Tp, true>
894 _S_do_it(_Tp& __c)
noexcept
899 _Tp(__make_move_if_noexcept_iterator(__c.begin()),
900 __make_move_if_noexcept_iterator(__c.end()),
901 __c.get_allocator()).swap(__c);
919 template<
typename _ForwardIterator,
typename _Allocator>
922 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
925 for (; __first != __last; ++__first)
926#
if __cplusplus < 201103L
935 template<
typename _ForwardIterator,
typename _Tp>
936 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
938 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
946_GLIBCXX_END_NAMESPACE_VERSION
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
ISO C++ entities toplevel namespace is std.
constexpr void _Construct(_Tp *__p, _Args &&... __args)
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)
Uniform interface to all allocator types.
static constexpr auto construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(noexcept(_S_construct(__a, __p, std::forward< _Args >(__args)...))) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp
__detected_or_t< false_type, __pocma, _Alloc > propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
typename _Ptr< __v_pointer, void >::type void_pointer
The allocator's void pointer type.
__detected_or_t< value_type *, __pointer, _Alloc > pointer
The allocator's pointer type.
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
static constexpr pointer allocate(_Alloc &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
typename _Size< _Alloc, difference_type >::type size_type
The allocator's size type.
typename _Ptr< __cv_pointer, const void >::type const_void_pointer
The allocator's const void pointer type.
typename _Diff< _Alloc, pointer >::type difference_type
The allocator's difference type.
typename _Ptr< __c_pointer, const value_type >::type const_pointer
The allocator's const pointer type.
_Alloc::value_type value_type
The allocated type.
static constexpr void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
typename __detected_or_t< is_empty< _Alloc >, __equal, _Alloc >::type is_always_equal
Whether all instances of the allocator type compare equal.
static constexpr size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
__detected_or_t< false_type, __pocca, _Alloc > propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(noexcept(_S_destroy(__a, __p, 0)))
Destroy an object of type _Tp.
static constexpr _Alloc select_on_container_copy_construction(const _Alloc &__rhs)
Obtain an allocator to use when copying a container.
__detected_or_t< false_type, __pocs, _Alloc > propagate_on_container_swap
How the allocator is propagated on swap.
_Alloc allocator_type
The allocator type.
allocator< _Tp > allocator_type
The allocator type.
void * void_pointer
The allocator's void pointer type.
_Tp * pointer
The allocator's pointer type.
false_type propagate_on_container_swap
How the allocator is propagated on swap.
static constexpr pointer allocate(allocator_type &__a, size_type __n)
Allocate memory.
_Tp value_type
The allocated type.
static constexpr pointer allocate(allocator_type &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
std::ptrdiff_t difference_type
The allocator's difference type.
true_type is_always_equal
Whether all instances of the allocator type compare equal.
const _Tp * const_pointer
The allocator's const pointer type.
const void * const_void_pointer
The allocator's const void pointer type.
true_type propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
static constexpr void deallocate(allocator_type &__a, pointer __p, size_type __n)
Deallocate memory.
static constexpr size_type max_size(const allocator_type &__a) noexcept
The maximum supported allocation size.
static constexpr allocator_type select_on_container_copy_construction(const allocator_type &__rhs)
Obtain an allocator to use when copying a container.
static constexpr void construct(allocator_type &__a, _Up *__p, _Args &&... __args) noexcept(std::is_nothrow_constructible< _Up, _Args... >::value)
Construct an object of type _Up
static constexpr void destroy(allocator_type &__a, _Up *__p) noexcept(is_nothrow_destructible< _Up >::value)
Destroy an object of type _Up.
false_type propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
std::size_t size_type
The allocator's size type.
false_type propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
void * pointer
The allocator's pointer type.
void * void_pointer
The allocator's void pointer type.
static void deallocate(allocator_type &, void *, size_type)=delete
deallocate is ill-formed for allocator<void>
static constexpr void construct(allocator_type &, _Up *__p, _Args &&... __args) noexcept(std::is_nothrow_constructible< _Up, _Args... >::value)
Construct an object of type _Up
true_type is_always_equal
Whether all instances of the allocator type compare equal.
void value_type
The allocated type.
static size_type max_size(const allocator_type &)=delete
max_size is ill-formed for allocator<void>
std::size_t size_type
The allocator's size type.
true_type propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
const void * const_pointer
The allocator's const pointer type.
std::ptrdiff_t difference_type
The allocator's difference type.
static void * allocate(allocator_type &, size_type, const void *=nullptr)=delete
allocate is ill-formed for allocator<void>
static constexpr allocator_type select_on_container_copy_construction(const allocator_type &__rhs)
Obtain an allocator to use when copying a container.
const void * const_void_pointer
The allocator's const void pointer type.
static constexpr void destroy(allocator_type &, _Up *__p) noexcept(is_nothrow_destructible< _Up >::value)
Destroy an object of type _Up
false_type propagate_on_container_swap
How the allocator is propagated on swap.
The standard allocator, as per C++03 [20.4.1].
Uniform interface to all pointer-like types.