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#pragma GCC diagnostic push
53#pragma GCC diagnostic ignored "-Wc++14-extensions"
54#pragma GCC diagnostic ignored "-Wc++17-extensions"
57 struct __allocator_traits_base
59 template<
typename _Tp,
typename _Up,
typename =
void>
60 struct __rebind : __replace_first_arg<_Tp, _Up>
62 static_assert(is_same<
63 typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
65 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
68 template<
typename _Tp,
typename _Up>
69 struct __rebind<_Tp, _Up,
70 __void_t<typename _Tp::template rebind<_Up>::other>>
72 using type =
typename _Tp::template rebind<_Up>::other;
74 static_assert(is_same<
75 typename _Tp::template rebind<typename _Tp::value_type>::other,
77 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
81 template<
typename _Tp>
82 using __pointer =
typename _Tp::pointer;
83 template<
typename _Tp>
84 using __c_pointer =
typename _Tp::const_pointer;
85 template<
typename _Tp>
86 using __v_pointer =
typename _Tp::void_pointer;
87 template<
typename _Tp>
88 using __cv_pointer =
typename _Tp::const_void_pointer;
89 template<
typename _Tp>
90 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
91 template<
typename _Tp>
92 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
93 template<
typename _Tp>
94 using __pocs =
typename _Tp::propagate_on_container_swap;
95 template<
typename _Tp>
96 using __equal = __type_identity<typename _Tp::is_always_equal>;
102 template<
typename _Alloc,
typename _Tp,
typename... _Args>
106 template<
typename _Alloc,
typename _Tp,
typename,
typename... _Args>
107 static constexpr bool __has_construct_impl =
false;
108 template<
typename _Alloc,
typename _Tp,
typename... _Args>
109 static constexpr bool
110 __has_construct_impl<_Alloc, _Tp,
111 __void_t<__construct_t<_Alloc, _Tp, _Args...>>,
114 template<
typename _Alloc,
typename _Tp,
typename... _Args>
115 static constexpr bool __has_construct
116 = __has_construct_impl<_Alloc, _Tp, void, _Args...>;
117 template<
typename _Tp,
typename... _Args>
120 template<
typename _Tp,
typename,
typename... _Args>
121 static constexpr bool __has_new_expr =
false;
122 template<
typename _Tp,
typename... _Args>
123 static constexpr bool
124 __has_new_expr<_Tp, __void_t<__new_expr_t<_Tp, _Args...>>, _Args...>
126 template<
typename _Alloc,
typename _Tp,
typename... _Args>
127 static constexpr bool __can_construct
128 = __has_construct<_Alloc, _Tp, _Args...>
129 || __has_new_expr<_Tp, void, _Args...>;
132 template<
typename _Alloc,
typename _Up>
134 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
143 template<
typename _Alloc>
144 struct allocator_traits : __allocator_traits_base
156 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
160 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
166 template<
template<
typename>
class _Func,
typename _Tp>
167 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
169 using type = _Func<_Alloc>;
173 template<
typename _A2,
typename _PtrT,
typename =
void>
175 {
using type =
typename pointer_traits<_PtrT>::difference_type; };
177 template<
typename _A2,
typename _PtrT>
178 struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
179 {
using type =
typename _A2::difference_type; };
182 template<
typename _A2,
typename _DiffT,
typename =
void>
183 struct _Size : make_unsigned<_DiffT> { };
185 template<
typename _A2,
typename _DiffT>
186 struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
187 {
using type =
typename _A2::size_type; };
228 using size_type =
typename _Size<_Alloc, difference_type>::type;
237 = __detected_or_t<false_type, __pocca, _Alloc>;
246 = __detected_or_t<false_type, __pocma, _Alloc>;
255 = __detected_or_t<false_type, __pocs, _Alloc>;
264 =
typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
266 template<
typename _Tp>
267 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
268 template<
typename _Tp>
272 template<
typename _Alloc2>
273 static constexpr auto
275 ->
decltype(__a.allocate(__n, __hint))
276 {
return __a.allocate(__n, __hint); }
278 template<
typename _Alloc2>
279 static constexpr pointer
284 template<
typename _Alloc2,
typename _Tp>
285 static _GLIBCXX14_CONSTEXPR
auto
286 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
287 noexcept(
noexcept(__a.destroy(__p)))
288 ->
decltype(__a.destroy(__p))
289 { __a.destroy(__p); }
291 template<
typename _Alloc2,
typename _Tp>
292 static _GLIBCXX14_CONSTEXPR
void
293 _S_destroy(_Alloc2&, _Tp* __p, ...)
294 noexcept(
std::is_nothrow_destructible<_Tp>::value)
297 template<
typename _Alloc2>
298 static constexpr auto
299 _S_max_size(_Alloc2& __a,
int)
300 ->
decltype(__a.max_size())
301 {
return __a.max_size(); }
303 template<
typename _Alloc2>
304 static constexpr size_type
305 _S_max_size(_Alloc2&, ...)
309 return __gnu_cxx::__numeric_traits<size_type>::__max
313 template<
typename _Alloc2>
314 static constexpr auto
315 _S_select(_Alloc2& __a,
int)
316 ->
decltype(__a.select_on_container_copy_construction())
317 {
return __a.select_on_container_copy_construction(); }
319 template<
typename _Alloc2>
320 static constexpr _Alloc2
321 _S_select(_Alloc2& __a, ...)
333 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
335 {
return __a.allocate(__n); }
348 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
350 {
return _S_allocate(__a, __n, __hint, 0); }
360 static _GLIBCXX20_CONSTEXPR
void
362 { __a.deallocate(__p, __n); }
375 template<
typename _Tp,
typename... _Args>
376 static _GLIBCXX20_CONSTEXPR
377 __enable_if_t<__can_construct<_Alloc, _Tp, _Args...>>
378 construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
379 noexcept(_S_nothrow_construct<_Tp, _Args...>())
381 if constexpr (__has_construct<_Alloc, _Tp, _Args...>)
395 template<
typename _Tp>
396 static _GLIBCXX20_CONSTEXPR
void
398 noexcept(
noexcept(_S_destroy(__a, __p, 0)))
399 { _S_destroy(__a, __p, 0); }
410 max_size(
const _Alloc& __a)
noexcept
411 {
return _S_max_size(__a, 0); }
421 static _GLIBCXX20_CONSTEXPR _Alloc
423 {
return _S_select(__rhs, 0); }
426#if __cpp_constexpr >= 201304
427 template<
typename _Tp,
typename... _Args>
428 static constexpr bool
429 _S_nothrow_construct(_Alloc* __a =
nullptr, _Tp* __p =
nullptr)
431 if constexpr (__has_construct<_Alloc, _Tp, _Args...>)
434 return __is_nothrow_new_constructible<_Tp, _Args...>;
437 template<
typename _Tp,
typename... _Args>
439 __enable_if_t<__has_construct<_Alloc, _Tp, _Args...>,
bool>
440 _S_nothrow_construct(_Alloc* __a =
nullptr, _Tp* __p =
nullptr)
443 template<
typename _Tp,
typename... _Args>
445 __enable_if_t<!__has_construct<_Alloc, _Tp, _Args...>,
bool>
446 _S_nothrow_construct(_Alloc* =
nullptr, _Tp* __p =
nullptr)
447 {
return __is_nothrow_new_constructible<_Tp, _Args...>; }
450#pragma GCC diagnostic pop
454 template<
typename _Tp>
493 template<
typename _Up>
496 template<
typename _Up>
506 [[__nodiscard__,__gnu__::__always_inline__]]
507 static _GLIBCXX20_CONSTEXPR
pointer
509 {
return __a.allocate(__n); }
521 [[__nodiscard__,__gnu__::__always_inline__]]
522 static _GLIBCXX20_CONSTEXPR pointer
526#if __cplusplus <= 201703L
527 return __a.allocate(__n, __hint);
529 return __a.allocate(__n);
541 [[__gnu__::__always_inline__]]
542 static _GLIBCXX20_CONSTEXPR
void
544 { __a.deallocate(__p, __n); }
557 template<
typename _Up,
typename... _Args>
558 [[__gnu__::__always_inline__]]
559 static _GLIBCXX20_CONSTEXPR
void
561 _Up* __p, _Args&&... __args)
562#if __cplusplus <= 201703L
565 noexcept(__is_nothrow_new_constructible<_Up, _Args...>)
568#if __cplusplus <= 201703L
570#elif __cpp_constexpr_dynamic_alloc
584 template<
typename _Up>
585 [[__gnu__::__always_inline__]]
586 static _GLIBCXX20_CONSTEXPR
void
590#if __cplusplus <= 201703L
593 std::destroy_at(__p);
602 [[__gnu__::__always_inline__]]
603 static _GLIBCXX20_CONSTEXPR size_type
606#if __cplusplus <= 201703L
607 return __a.max_size();
618 [[__gnu__::__always_inline__]]
619 static _GLIBCXX20_CONSTEXPR allocator_type
664 template<
typename _Up>
667 template<
typename _Up>
689 template<
typename _Up,
typename... _Args>
690 [[__gnu__::__always_inline__]]
691 static _GLIBCXX20_CONSTEXPR
void
693 noexcept(__is_nothrow_new_constructible<_Up, _Args...>)
703 template<
typename _Up>
704 [[__gnu__::__always_inline__]]
705 static _GLIBCXX20_CONSTEXPR
void
719 [[__gnu__::__always_inline__]]
727#if __cplusplus < 201703L
728 template<
typename _Alloc>
729 [[__gnu__::__always_inline__]]
731 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two, true_type)
734 template<
typename _Alloc>
735 [[__gnu__::__always_inline__]]
737 __do_alloc_on_copy(_Alloc&,
const _Alloc&, false_type)
741 template<
typename _Alloc>
742 [[__gnu__::__always_inline__]]
743 _GLIBCXX14_CONSTEXPR
inline void
744 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
746 using __traits = allocator_traits<_Alloc>;
748 typename __traits::propagate_on_container_copy_assignment::type;
749#if __cplusplus >= 201703L
750 if constexpr (__pocca::value)
753 __do_alloc_on_copy(__one, __two, __pocca());
757 template<
typename _Alloc>
758 [[__gnu__::__always_inline__]]
760 __alloc_on_copy(
const _Alloc& __a)
762 typedef allocator_traits<_Alloc> __traits;
763 return __traits::select_on_container_copy_construction(__a);
766#if __cplusplus < 201703L
767 template<
typename _Alloc>
768 [[__gnu__::__always_inline__]]
769 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
772 template<
typename _Alloc>
773 [[__gnu__::__always_inline__]]
774 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
778 template<
typename _Alloc>
779 [[__gnu__::__always_inline__]]
780 _GLIBCXX14_CONSTEXPR
inline void
781 __alloc_on_move(_Alloc& __one, _Alloc& __two)
783 using __traits = allocator_traits<_Alloc>;
785 =
typename __traits::propagate_on_container_move_assignment::type;
786#if __cplusplus >= 201703L
787 if constexpr (__pocma::value)
790 __do_alloc_on_move(__one, __two, __pocma());
794#if __cplusplus < 201703L
795 template<
typename _Alloc>
796 [[__gnu__::__always_inline__]]
797 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
803 template<
typename _Alloc>
804 [[__gnu__::__always_inline__]]
805 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
809 template<
typename _Alloc>
810 [[__gnu__::__always_inline__]]
811 _GLIBCXX14_CONSTEXPR
inline void
812 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
814 using __traits = allocator_traits<_Alloc>;
815 using __pocs =
typename __traits::propagate_on_container_swap::type;
816#if __cplusplus >= 201703L
817 if constexpr (__pocs::value)
823 __do_alloc_on_swap(__one, __two, __pocs());
827 template<
typename _Alloc,
typename _Tp,
828 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
830 struct __is_alloc_insertable_impl
834 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
835 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
836 __void_t<decltype(allocator_traits<_Alloc>::construct(
837 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
838 std::declval<_Tp>()))>>
845 template<
typename _Alloc>
846 struct __is_copy_insertable
847 : __is_alloc_insertable_impl<_Alloc,
848 typename _Alloc::value_type const&>::type
853 template<
typename _Tp>
854 struct __is_copy_insertable<allocator<_Tp>>
855 : is_copy_constructible<_Tp>
862 template<
typename _Alloc>
863 struct __is_move_insertable
864 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
869 template<
typename _Tp>
870 struct __is_move_insertable<allocator<_Tp>>
871 : is_move_constructible<_Tp>
876 template<
typename _Alloc,
typename =
void>
877 struct __is_allocator : false_type { };
879 template<
typename _Alloc>
880 struct __is_allocator<_Alloc,
881 __void_t<typename _Alloc::value_type,
882 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
885 template<
typename _Alloc>
886 using _RequireAllocator
887 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
889 template<
typename _Alloc>
890 using _RequireNotAllocator
891 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
893#if __cpp_concepts >= 201907L
894 template<
typename _Alloc>
895 concept __allocator_like =
requires (_Alloc& __a) {
896 typename _Alloc::value_type;
897 __a.deallocate(__a.allocate(1u), 1u);
906 template<
typename _Alloc,
bool = __is_empty(_Alloc)>
908 {
static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
910 template<
typename _Alloc>
911 struct __alloc_swap<_Alloc, false>
914 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
922#if __cplusplus >= 201103L
923 template<
typename _Tp,
bool
924 = __or_<is_copy_constructible<typename _Tp::value_type>,
925 is_nothrow_move_constructible<typename _Tp::value_type>>::value>
926 struct __shrink_to_fit_aux
927 {
static bool _S_do_it(_Tp&)
noexcept {
return false; } };
929 template<
typename _Tp>
930 struct __shrink_to_fit_aux<_Tp, true>
934 _S_do_it(_Tp& __c)
noexcept
939 _Tp(__make_move_if_noexcept_iterator(__c.begin()),
940 __make_move_if_noexcept_iterator(__c.end()),
941 __c.get_allocator()).swap(__c);
959 template<
typename _ForwardIterator,
typename _Allocator>
962 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
965 for (; __first != __last; ++__first)
966#
if __cplusplus < 201103L
975 template<
typename _ForwardIterator,
typename _Tp>
976 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
978 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
986_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.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
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.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
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.
__detected_or_t< false_type, __pocma, _Alloc > propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
static constexpr _Alloc select_on_container_copy_construction(const _Alloc &__rhs)
Obtain an allocator to use when copying a container.
static constexpr void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
typename _Diff< _Alloc, pointer >::type difference_type
The allocator's difference type.
_Alloc::value_type value_type
The allocated type.
__detected_or_t< value_type *, __pointer, _Alloc > pointer
The allocator's pointer type.
_Alloc allocator_type
The allocator type.
typename __detected_or_t< is_empty< _Alloc >, __equal, _Alloc >::type is_always_equal
Whether all instances of the allocator type compare equal.
typename _Size< _Alloc, difference_type >::type size_type
The allocator's size type.
__detected_or_t< false_type, __pocs, _Alloc > propagate_on_container_swap
How the allocator is propagated on swap.
static constexpr __enable_if_t< __can_construct< _Alloc, _Tp, _Args... > > construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(_S_nothrow_construct< _Tp, _Args... >())
Construct an object of type _Tp
typename _Ptr< __v_pointer, void >::type void_pointer
The allocator's void pointer type.
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(noexcept(_S_destroy(__a, __p, 0)))
Destroy an object of type _Tp.
typename _Ptr< __cv_pointer, const void >::type const_void_pointer
The allocator's const void pointer type.
__detected_or_t< false_type, __pocca, _Alloc > propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
typename _Ptr< __c_pointer, const value_type >::type const_pointer
The allocator's const pointer type.
static constexpr size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
static constexpr void construct(allocator_type &__a, _Up *__p, _Args &&... __args) noexcept(__is_nothrow_new_constructible< _Up, _Args... >)
Construct an object of type _Up
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 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>
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.
static constexpr void construct(allocator_type &, _Up *__p, _Args &&... __args) noexcept(__is_nothrow_new_constructible< _Up, _Args... >)
Construct an object of type _Up
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.