30#ifndef _ALLOC_TRAITS_H
31#define _ALLOC_TRAITS_H 1
35#if __cplusplus >= 201103L
46namespace std _GLIBCXX_VISIBILITY(default)
48_GLIBCXX_BEGIN_NAMESPACE_VERSION
50#if __cplusplus >= 201103L
52 struct __allocator_traits_base
54 template<
typename _Tp,
typename _Up,
typename =
void>
55 struct __rebind : __replace_first_arg<_Tp, _Up>
57 static_assert(is_same<
58 typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
60 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
63 template<
typename _Tp,
typename _Up>
64 struct __rebind<_Tp, _Up,
65 __void_t<typename _Tp::template rebind<_Up>::other>>
67 using type =
typename _Tp::template rebind<_Up>::other;
69 static_assert(is_same<
70 typename _Tp::template rebind<typename _Tp::value_type>::other,
72 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
76 template<
typename _Tp>
77 using __pointer =
typename _Tp::pointer;
78 template<
typename _Tp>
79 using __c_pointer =
typename _Tp::const_pointer;
80 template<
typename _Tp>
81 using __v_pointer =
typename _Tp::void_pointer;
82 template<
typename _Tp>
83 using __cv_pointer =
typename _Tp::const_void_pointer;
84 template<
typename _Tp>
85 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
86 template<
typename _Tp>
87 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
88 template<
typename _Tp>
89 using __pocs =
typename _Tp::propagate_on_container_swap;
90 template<
typename _Tp>
91 using __equal = __type_identity<typename _Tp::is_always_equal>;
94 template<
typename _Alloc,
typename _Up>
96 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
105 template<
typename _Alloc>
118 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
122 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
128 template<
template<
typename>
class _Func,
typename _Tp>
129 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
131 using type = _Func<_Alloc>;
135 template<
typename _A2,
typename _PtrT,
typename =
void>
137 {
using type =
typename pointer_traits<_PtrT>::difference_type; };
139 template<
typename _A2,
typename _PtrT>
141 {
using type =
typename _A2::difference_type; };
144 template<
typename _A2,
typename _DiffT,
typename =
void>
145 struct _Size : make_unsigned<_DiffT> { };
147 template<
typename _A2,
typename _DiffT>
148 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
149 {
using type =
typename _A2::size_type; };
190 using size_type =
typename _Size<_Alloc, difference_type>::type;
199 = __detected_or_t<false_type, __pocca, _Alloc>;
208 = __detected_or_t<false_type, __pocma, _Alloc>;
217 = __detected_or_t<false_type, __pocs, _Alloc>;
226 =
typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
228 template<
typename _Tp>
229 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
230 template<
typename _Tp>
234 template<
typename _Alloc2>
235 static constexpr auto
237 ->
decltype(__a.allocate(__n, __hint))
238 {
return __a.
allocate(__n, __hint); }
240 template<
typename _Alloc2>
243 {
return __a.allocate(__n); }
245 template<
typename _Tp,
typename... _Args>
246 struct __construct_helper
248 template<
typename _Alloc2,
249 typename =
decltype(std::declval<_Alloc2*>()->construct(
250 std::declval<_Tp*>(), std::declval<_Args>()...))>
256 using type =
decltype(__test<_Alloc>(0));
259 template<
typename _Tp,
typename... _Args>
260 using __has_construct
261 =
typename __construct_helper<_Tp, _Args...>::type;
263 template<
typename _Tp,
typename... _Args>
264 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
265 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
266 noexcept(
noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
267 { __a.construct(__p, std::forward<_Args>(__args)...); }
269 template<
typename _Tp,
typename... _Args>
270 static _GLIBCXX14_CONSTEXPR
271 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
272 is_constructible<_Tp, _Args...>>>
273 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
276#if __cplusplus <= 201703L
277 ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...);
279 std::construct_at(__p, std::forward<_Args>(__args)...);
283 template<
typename _Alloc2,
typename _Tp>
284 static _GLIBCXX14_CONSTEXPR
auto
285 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
286 noexcept(
noexcept(__a.destroy(__p)))
287 ->
decltype(__a.destroy(__p))
288 { __a.destroy(__p); }
290 template<
typename _Alloc2,
typename _Tp>
291 static _GLIBCXX14_CONSTEXPR
void
292 _S_destroy(_Alloc2&, _Tp* __p, ...)
293 noexcept(
std::is_nothrow_destructible<_Tp>::value)
296 template<
typename _Alloc2>
297 static constexpr auto
298 _S_max_size(_Alloc2& __a,
int)
299 ->
decltype(__a.max_size())
300 {
return __a.max_size(); }
302 template<
typename _Alloc2>
304 _S_max_size(_Alloc2&, ...)
308 return __gnu_cxx::__numeric_traits<size_type>::__max
312 template<
typename _Alloc2>
313 static constexpr auto
314 _S_select(_Alloc2& __a,
int)
315 ->
decltype(__a.select_on_container_copy_construction())
316 {
return __a.select_on_container_copy_construction(); }
318 template<
typename _Alloc2>
319 static constexpr _Alloc2
320 _S_select(_Alloc2& __a, ...)
332 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
334 {
return __a.allocate(__n); }
347 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
349 {
return _S_allocate(__a, __n, __hint, 0); }
359 static _GLIBCXX20_CONSTEXPR
void
361 { __a.deallocate(__p, __n); }
374 template<
typename _Tp,
typename... _Args>
375 static _GLIBCXX20_CONSTEXPR
auto
377 noexcept(
noexcept(_S_construct(__a, __p,
378 std::forward<_Args>(__args)...)))
379 ->
decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
380 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
390 template<
typename _Tp>
391 static _GLIBCXX20_CONSTEXPR
void
393 noexcept(
noexcept(_S_destroy(__a, __p, 0)))
394 { _S_destroy(__a, __p, 0); }
406 {
return _S_max_size(__a, 0); }
416 static _GLIBCXX20_CONSTEXPR _Alloc
418 {
return _S_select(__rhs, 0); }
423 template<
typename _Tp>
462 template<
typename _Up>
465 template<
typename _Up>
475 [[__nodiscard__,__gnu__::__always_inline__]]
476 static _GLIBCXX20_CONSTEXPR
pointer
478 {
return __a.allocate(__n); }
490 [[__nodiscard__,__gnu__::__always_inline__]]
491 static _GLIBCXX20_CONSTEXPR
pointer
495#if __cplusplus <= 201703L
496 return __a.allocate(__n, __hint);
498 return __a.allocate(__n);
510 [[__gnu__::__always_inline__]]
511 static _GLIBCXX20_CONSTEXPR
void
513 { __a.deallocate(__p, __n); }
526 template<
typename _Up,
typename... _Args>
527 [[__gnu__::__always_inline__]]
528 static _GLIBCXX20_CONSTEXPR
void
533#if __cplusplus <= 201703L
534 __a.construct(__p, std::forward<_Args>(__args)...);
536 std::construct_at(__p, std::forward<_Args>(__args)...);
547 template<
typename _Up>
548 [[__gnu__::__always_inline__]]
549 static _GLIBCXX20_CONSTEXPR
void
553#if __cplusplus <= 201703L
556 std::destroy_at(__p);
565 [[__gnu__::__always_inline__]]
569#if __cplusplus <= 201703L
570 return __a.max_size();
581 [[__gnu__::__always_inline__]]
627 template<
typename _Up>
630 template<
typename _Up>
652 template<
typename _Up,
typename... _Args>
653 [[__gnu__::__always_inline__]]
654 static _GLIBCXX20_CONSTEXPR
void
666 template<
typename _Up>
667 [[__gnu__::__always_inline__]]
668 static _GLIBCXX20_CONSTEXPR
void
682 [[__gnu__::__always_inline__]]
690#if __cplusplus < 201703L
691 template<
typename _Alloc>
692 [[__gnu__::__always_inline__]]
694 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
697 template<
typename _Alloc>
698 [[__gnu__::__always_inline__]]
700 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
704 template<
typename _Alloc>
705 [[__gnu__::__always_inline__]]
706 _GLIBCXX14_CONSTEXPR
inline void
707 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
709 using __traits = allocator_traits<_Alloc>;
711 typename __traits::propagate_on_container_copy_assignment::type;
712#if __cplusplus >= 201703L
713 if constexpr (__pocca::value)
716 __do_alloc_on_copy(__one, __two, __pocca());
720 template<
typename _Alloc>
721 [[__gnu__::__always_inline__]]
723 __alloc_on_copy(
const _Alloc& __a)
725 typedef allocator_traits<_Alloc> __traits;
726 return __traits::select_on_container_copy_construction(__a);
729#if __cplusplus < 201703L
730 template<
typename _Alloc>
731 [[__gnu__::__always_inline__]]
732 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
735 template<
typename _Alloc>
736 [[__gnu__::__always_inline__]]
737 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
741 template<
typename _Alloc>
742 [[__gnu__::__always_inline__]]
743 _GLIBCXX14_CONSTEXPR
inline void
744 __alloc_on_move(_Alloc& __one, _Alloc& __two)
746 using __traits = allocator_traits<_Alloc>;
748 =
typename __traits::propagate_on_container_move_assignment::type;
749#if __cplusplus >= 201703L
750 if constexpr (__pocma::value)
753 __do_alloc_on_move(__one, __two, __pocma());
757#if __cplusplus < 201703L
758 template<
typename _Alloc>
759 [[__gnu__::__always_inline__]]
760 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
766 template<
typename _Alloc>
767 [[__gnu__::__always_inline__]]
768 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
772 template<
typename _Alloc>
773 [[__gnu__::__always_inline__]]
774 _GLIBCXX14_CONSTEXPR
inline void
775 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
777 using __traits = allocator_traits<_Alloc>;
778 using __pocs =
typename __traits::propagate_on_container_swap::type;
779#if __cplusplus >= 201703L
780 if constexpr (__pocs::value)
786 __do_alloc_on_swap(__one, __two, __pocs());
790 template<
typename _Alloc,
typename _Tp,
791 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
793 struct __is_alloc_insertable_impl
797 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
798 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
799 __void_t<decltype(allocator_traits<_Alloc>::construct(
800 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
801 std::declval<_Tp>()))>>
808 template<
typename _Alloc>
809 struct __is_copy_insertable
810 : __is_alloc_insertable_impl<_Alloc,
811 typename _Alloc::value_type const&>::type
816 template<
typename _Tp>
817 struct __is_copy_insertable<allocator<_Tp>>
818 : is_copy_constructible<_Tp>
825 template<
typename _Alloc>
826 struct __is_move_insertable
827 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
832 template<
typename _Tp>
833 struct __is_move_insertable<allocator<_Tp>>
834 : is_move_constructible<_Tp>
839 template<
typename _Alloc,
typename =
void>
842 template<
typename _Alloc>
843 struct __is_allocator<_Alloc,
844 __void_t<typename _Alloc::value_type,
845 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
848 template<
typename _Alloc>
849 using _RequireAllocator
850 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
852 template<
typename _Alloc>
853 using _RequireNotAllocator
854 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
856#if __cpp_concepts >= 201907L
857 template<
typename _Alloc>
858 concept __allocator_like =
requires (_Alloc& __a) {
859 typename _Alloc::value_type;
860 __a.deallocate(__a.allocate(1u), 1u);
869 template<
typename _Alloc,
bool = __is_empty(_Alloc)>
871 {
static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
873 template<
typename _Alloc>
874 struct __alloc_swap<_Alloc, false>
877 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
885#if __cplusplus >= 201103L
886 template<
typename _Tp,
bool
887 = __or_<is_copy_constructible<typename _Tp::value_type>,
888 is_nothrow_move_constructible<typename _Tp::value_type>>::value>
889 struct __shrink_to_fit_aux
890 {
static bool _S_do_it(_Tp&)
noexcept {
return false; } };
892 template<
typename _Tp>
893 struct __shrink_to_fit_aux<_Tp, true>
897 _S_do_it(_Tp& __c)
noexcept
902 _Tp(__make_move_if_noexcept_iterator(__c.begin()),
903 __make_move_if_noexcept_iterator(__c.end()),
904 __c.get_allocator()).swap(__c);
922 template<
typename _ForwardIterator,
typename _Allocator>
925 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
928 for (; __first != __last; ++__first)
929#
if __cplusplus < 201103L
938 template<
typename _ForwardIterator,
typename _Tp>
939 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
941 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
949_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.