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
48#define __cpp_lib_allocator_traits_is_always_equal 201411L
51 struct __allocator_traits_base
53 template<
typename _Tp,
typename _Up,
typename =
void>
54 struct __rebind : __replace_first_arg<_Tp, _Up>
56 static_assert(is_same<
57 typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
59 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
62 template<
typename _Tp,
typename _Up>
63 struct __rebind<_Tp, _Up,
64 __void_t<typename _Tp::template rebind<_Up>::other>>
66 using type =
typename _Tp::template rebind<_Up>::other;
68 static_assert(is_same<
69 typename _Tp::template rebind<typename _Tp::value_type>::other,
71 "allocator_traits<A>::rebind_alloc<A::value_type> must be A");
75 template<
typename _Tp>
76 using __pointer =
typename _Tp::pointer;
77 template<
typename _Tp>
78 using __c_pointer =
typename _Tp::const_pointer;
79 template<
typename _Tp>
80 using __v_pointer =
typename _Tp::void_pointer;
81 template<
typename _Tp>
82 using __cv_pointer =
typename _Tp::const_void_pointer;
83 template<
typename _Tp>
84 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
85 template<
typename _Tp>
86 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
87 template<
typename _Tp>
88 using __pocs =
typename _Tp::propagate_on_container_swap;
89 template<
typename _Tp>
90 using __equal = __type_identity<typename _Tp::is_always_equal>;
93 template<
typename _Alloc,
typename _Up>
95 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
104 template<
typename _Alloc>
117 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
121 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
127 template<
template<
typename>
class _Func,
typename _Tp>
128 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
130 using type = _Func<_Alloc>;
134 template<
typename _A2,
typename _PtrT,
typename =
void>
136 {
using type =
typename pointer_traits<_PtrT>::difference_type; };
138 template<
typename _A2,
typename _PtrT>
140 {
using type =
typename _A2::difference_type; };
143 template<
typename _A2,
typename _DiffT,
typename =
void>
144 struct _Size : make_unsigned<_DiffT> { };
146 template<
typename _A2,
typename _DiffT>
147 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
148 {
using type =
typename _A2::size_type; };
189 using size_type =
typename _Size<_Alloc, difference_type>::type;
198 = __detected_or_t<false_type, __pocca, _Alloc>;
207 = __detected_or_t<false_type, __pocma, _Alloc>;
216 = __detected_or_t<false_type, __pocs, _Alloc>;
225 =
typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
227 template<
typename _Tp>
228 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
229 template<
typename _Tp>
233 template<
typename _Alloc2>
234 static constexpr auto
236 ->
decltype(__a.allocate(__n, __hint))
237 {
return __a.
allocate(__n, __hint); }
239 template<
typename _Alloc2>
242 {
return __a.allocate(__n); }
244 template<
typename _Tp,
typename... _Args>
245 struct __construct_helper
247 template<
typename _Alloc2,
248 typename =
decltype(std::declval<_Alloc2*>()->construct(
249 std::declval<_Tp*>(), std::declval<_Args>()...))>
255 using type =
decltype(__test<_Alloc>(0));
258 template<
typename _Tp,
typename... _Args>
259 using __has_construct
260 =
typename __construct_helper<_Tp, _Args...>::type;
262 template<
typename _Tp,
typename... _Args>
263 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
264 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
265 noexcept(
noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
266 { __a.construct(__p, std::forward<_Args>(__args)...); }
268 template<
typename _Tp,
typename... _Args>
269 static _GLIBCXX14_CONSTEXPR
270 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
271 is_constructible<_Tp, _Args...>>>
272 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
275#if __cplusplus <= 201703L
276 ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...);
278 std::construct_at(__p, std::forward<_Args>(__args)...);
282 template<
typename _Alloc2,
typename _Tp>
283 static _GLIBCXX14_CONSTEXPR
auto
284 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
285 noexcept(
noexcept(__a.destroy(__p)))
286 ->
decltype(__a.destroy(__p))
287 { __a.destroy(__p); }
289 template<
typename _Alloc2,
typename _Tp>
290 static _GLIBCXX14_CONSTEXPR
void
291 _S_destroy(_Alloc2&, _Tp* __p, ...)
292 noexcept(
std::is_nothrow_destructible<_Tp>::value)
295 template<
typename _Alloc2>
296 static constexpr auto
297 _S_max_size(_Alloc2& __a,
int)
298 ->
decltype(__a.max_size())
299 {
return __a.max_size(); }
301 template<
typename _Alloc2>
303 _S_max_size(_Alloc2&, ...)
307 return __gnu_cxx::__numeric_traits<size_type>::__max
311 template<
typename _Alloc2>
312 static constexpr auto
313 _S_select(_Alloc2& __a,
int)
314 ->
decltype(__a.select_on_container_copy_construction())
315 {
return __a.select_on_container_copy_construction(); }
317 template<
typename _Alloc2>
318 static constexpr _Alloc2
319 _S_select(_Alloc2& __a, ...)
331 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
333 {
return __a.allocate(__n); }
346 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
348 {
return _S_allocate(__a, __n, __hint, 0); }
358 static _GLIBCXX20_CONSTEXPR
void
360 { __a.deallocate(__p, __n); }
373 template<
typename _Tp,
typename... _Args>
374 static _GLIBCXX20_CONSTEXPR
auto
376 noexcept(
noexcept(_S_construct(__a, __p,
377 std::forward<_Args>(__args)...)))
378 ->
decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
379 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
389 template<
typename _Tp>
390 static _GLIBCXX20_CONSTEXPR
void
392 noexcept(
noexcept(_S_destroy(__a, __p, 0)))
393 { _S_destroy(__a, __p, 0); }
405 {
return _S_max_size(__a, 0); }
415 static _GLIBCXX20_CONSTEXPR _Alloc
417 {
return _S_select(__rhs, 0); }
422#if __cplusplus > 201703L
423# define __cpp_lib_constexpr_dynamic_alloc 201907L
427 template<
typename _Tp>
466 template<
typename _Up>
469 template<
typename _Up>
479 [[__nodiscard__,__gnu__::__always_inline__]]
480 static _GLIBCXX20_CONSTEXPR
pointer
482 {
return __a.allocate(__n); }
494 [[__nodiscard__,__gnu__::__always_inline__]]
495 static _GLIBCXX20_CONSTEXPR
pointer
499#if __cplusplus <= 201703L
500 return __a.allocate(__n, __hint);
502 return __a.allocate(__n);
514 [[__gnu__::__always_inline__]]
515 static _GLIBCXX20_CONSTEXPR
void
517 { __a.deallocate(__p, __n); }
530 template<
typename _Up,
typename... _Args>
531 [[__gnu__::__always_inline__]]
532 static _GLIBCXX20_CONSTEXPR
void
537#if __cplusplus <= 201703L
538 __a.construct(__p, std::forward<_Args>(__args)...);
540 std::construct_at(__p, std::forward<_Args>(__args)...);
551 template<
typename _Up>
552 [[__gnu__::__always_inline__]]
553 static _GLIBCXX20_CONSTEXPR
void
557#if __cplusplus <= 201703L
560 std::destroy_at(__p);
569 [[__gnu__::__always_inline__]]
573#if __cplusplus <= 201703L
574 return __a.max_size();
585 [[__gnu__::__always_inline__]]
631 template<
typename _Up>
634 template<
typename _Up>
656 template<
typename _Up,
typename... _Args>
657 [[__gnu__::__always_inline__]]
658 static _GLIBCXX20_CONSTEXPR
void
670 template<
typename _Up>
671 [[__gnu__::__always_inline__]]
672 static _GLIBCXX20_CONSTEXPR
void
686 [[__gnu__::__always_inline__]]
694#if __cplusplus < 201703L
695 template<
typename _Alloc>
696 [[__gnu__::__always_inline__]]
698 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
701 template<
typename _Alloc>
702 [[__gnu__::__always_inline__]]
704 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
708 template<
typename _Alloc>
709 [[__gnu__::__always_inline__]]
710 _GLIBCXX14_CONSTEXPR
inline void
711 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
713 using __traits = allocator_traits<_Alloc>;
715 typename __traits::propagate_on_container_copy_assignment::type;
716#if __cplusplus >= 201703L
717 if constexpr (__pocca::value)
720 __do_alloc_on_copy(__one, __two, __pocca());
724 template<
typename _Alloc>
725 [[__gnu__::__always_inline__]]
727 __alloc_on_copy(
const _Alloc& __a)
729 typedef allocator_traits<_Alloc> __traits;
730 return __traits::select_on_container_copy_construction(__a);
733#if __cplusplus < 201703L
734 template<
typename _Alloc>
735 [[__gnu__::__always_inline__]]
736 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
739 template<
typename _Alloc>
740 [[__gnu__::__always_inline__]]
741 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
745 template<
typename _Alloc>
746 [[__gnu__::__always_inline__]]
747 _GLIBCXX14_CONSTEXPR
inline void
748 __alloc_on_move(_Alloc& __one, _Alloc& __two)
750 using __traits = allocator_traits<_Alloc>;
752 =
typename __traits::propagate_on_container_move_assignment::type;
753#if __cplusplus >= 201703L
754 if constexpr (__pocma::value)
757 __do_alloc_on_move(__one, __two, __pocma());
761#if __cplusplus < 201703L
762 template<
typename _Alloc>
763 [[__gnu__::__always_inline__]]
764 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
770 template<
typename _Alloc>
771 [[__gnu__::__always_inline__]]
772 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
776 template<
typename _Alloc>
777 [[__gnu__::__always_inline__]]
778 _GLIBCXX14_CONSTEXPR
inline void
779 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
781 using __traits = allocator_traits<_Alloc>;
782 using __pocs =
typename __traits::propagate_on_container_swap::type;
783#if __cplusplus >= 201703L
784 if constexpr (__pocs::value)
790 __do_alloc_on_swap(__one, __two, __pocs());
794 template<
typename _Alloc,
typename _Tp,
795 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
797 struct __is_alloc_insertable_impl
801 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
802 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
803 __void_t<decltype(allocator_traits<_Alloc>::construct(
804 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
805 std::declval<_Tp>()))>>
812 template<
typename _Alloc>
813 struct __is_copy_insertable
814 : __is_alloc_insertable_impl<_Alloc,
815 typename _Alloc::value_type const&>::type
820 template<
typename _Tp>
821 struct __is_copy_insertable<allocator<_Tp>>
822 : is_copy_constructible<_Tp>
829 template<
typename _Alloc>
830 struct __is_move_insertable
831 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
836 template<
typename _Tp>
837 struct __is_move_insertable<allocator<_Tp>>
838 : is_move_constructible<_Tp>
843 template<
typename _Alloc,
typename =
void>
846 template<
typename _Alloc>
847 struct __is_allocator<_Alloc,
848 __void_t<typename _Alloc::value_type,
849 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
852 template<
typename _Alloc>
853 using _RequireAllocator
854 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
856 template<
typename _Alloc>
857 using _RequireNotAllocator
858 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
860#if __cpp_concepts >= 201907L
861 template<
typename _Alloc>
862 concept __allocator_like =
requires (_Alloc& __a) {
863 typename _Alloc::value_type;
864 __a.deallocate(__a.allocate(1u), 1u);
873 template<
typename _Alloc,
bool = __is_empty(_Alloc)>
875 {
static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
877 template<
typename _Alloc>
878 struct __alloc_swap<_Alloc, false>
881 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
889#if __cplusplus >= 201103L
890 template<
typename _Tp,
bool
891 = __or_<is_copy_constructible<typename _Tp::value_type>,
892 is_nothrow_move_constructible<typename _Tp::value_type>>::value>
893 struct __shrink_to_fit_aux
894 {
static bool _S_do_it(_Tp&)
noexcept {
return false; } };
896 template<
typename _Tp>
897 struct __shrink_to_fit_aux<_Tp, true>
901 _S_do_it(_Tp& __c)
noexcept
906 _Tp(__make_move_if_noexcept_iterator(__c.begin()),
907 __make_move_if_noexcept_iterator(__c.end()),
908 __c.get_allocator()).swap(__c);
926 template<
typename _ForwardIterator,
typename _Allocator>
929 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
932 for (; __first != __last; ++__first)
933#
if __cplusplus < 201103L
942 template<
typename _ForwardIterator,
typename _Tp>
943 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
945 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
953_GLIBCXX_END_NAMESPACE_VERSION
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
integral_constant< bool, 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.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
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.
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.
const _Tp * const_pointer
The allocator's const pointer type.
const void * const_void_pointer
The allocator's const void pointer type.
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.
std::size_t size_type
The allocator's size type.
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
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.
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
The standard allocator, as per C++03 [20.4.1].
Uniform interface to all pointer-like types.