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
498#if __cplusplus <= 201703L
499 return __a.allocate(__n, __hint);
501 return __a.allocate(__n);
513 [[__gnu__::__always_inline__]]
514 static _GLIBCXX20_CONSTEXPR
void
516 { __a.deallocate(__p, __n); }
529 template<
typename _Up,
typename... _Args>
530 [[__gnu__::__always_inline__]]
531 static _GLIBCXX20_CONSTEXPR
void
536#if __cplusplus <= 201703L
537 __a.construct(__p, std::forward<_Args>(__args)...);
539 std::construct_at(__p, std::forward<_Args>(__args)...);
550 template<
typename _Up>
551 [[__gnu__::__always_inline__]]
552 static _GLIBCXX20_CONSTEXPR
void
556#if __cplusplus <= 201703L
559 std::destroy_at(__p);
568 [[__gnu__::__always_inline__]]
572#if __cplusplus <= 201703L
573 return __a.max_size();
584 [[__gnu__::__always_inline__]]
630 template<
typename _Up>
633 template<
typename _Up>
655 template<
typename _Up,
typename... _Args>
656 [[__gnu__::__always_inline__]]
657 static _GLIBCXX20_CONSTEXPR
void
669 template<
typename _Up>
670 [[__gnu__::__always_inline__]]
671 static _GLIBCXX20_CONSTEXPR
void
685 [[__gnu__::__always_inline__]]
693#if __cplusplus < 201703L
694 template<
typename _Alloc>
695 [[__gnu__::__always_inline__]]
697 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
700 template<
typename _Alloc>
701 [[__gnu__::__always_inline__]]
703 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
707 template<
typename _Alloc>
708 [[__gnu__::__always_inline__]]
709 _GLIBCXX14_CONSTEXPR
inline void
710 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
712 using __traits = allocator_traits<_Alloc>;
714 typename __traits::propagate_on_container_copy_assignment::type;
715#if __cplusplus >= 201703L
716 if constexpr (__pocca::value)
719 __do_alloc_on_copy(__one, __two, __pocca());
723 template<
typename _Alloc>
724 [[__gnu__::__always_inline__]]
726 __alloc_on_copy(
const _Alloc& __a)
728 typedef allocator_traits<_Alloc> __traits;
729 return __traits::select_on_container_copy_construction(__a);
732#if __cplusplus < 201703L
733 template<
typename _Alloc>
734 [[__gnu__::__always_inline__]]
735 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
738 template<
typename _Alloc>
739 [[__gnu__::__always_inline__]]
740 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
744 template<
typename _Alloc>
745 [[__gnu__::__always_inline__]]
746 _GLIBCXX14_CONSTEXPR
inline void
747 __alloc_on_move(_Alloc& __one, _Alloc& __two)
749 using __traits = allocator_traits<_Alloc>;
751 =
typename __traits::propagate_on_container_move_assignment::type;
752#if __cplusplus >= 201703L
753 if constexpr (__pocma::value)
756 __do_alloc_on_move(__one, __two, __pocma());
760#if __cplusplus < 201703L
761 template<
typename _Alloc>
762 [[__gnu__::__always_inline__]]
763 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
769 template<
typename _Alloc>
770 [[__gnu__::__always_inline__]]
771 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
775 template<
typename _Alloc>
776 [[__gnu__::__always_inline__]]
777 _GLIBCXX14_CONSTEXPR
inline void
778 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
780 using __traits = allocator_traits<_Alloc>;
781 using __pocs =
typename __traits::propagate_on_container_swap::type;
782#if __cplusplus >= 201703L
783 if constexpr (__pocs::value)
789 __do_alloc_on_swap(__one, __two, __pocs());
793 template<
typename _Alloc,
typename _Tp,
794 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
796 struct __is_alloc_insertable_impl
800 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
801 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
802 __void_t<decltype(allocator_traits<_Alloc>::construct(
803 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
804 std::declval<_Tp>()))>>
811 template<
typename _Alloc>
812 struct __is_copy_insertable
813 : __is_alloc_insertable_impl<_Alloc,
814 typename _Alloc::value_type const&>::type
819 template<
typename _Tp>
820 struct __is_copy_insertable<allocator<_Tp>>
821 : is_copy_constructible<_Tp>
828 template<
typename _Alloc>
829 struct __is_move_insertable
830 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
835 template<
typename _Tp>
836 struct __is_move_insertable<allocator<_Tp>>
837 : is_move_constructible<_Tp>
842 template<
typename _Alloc,
typename =
void>
845 template<
typename _Alloc>
846 struct __is_allocator<_Alloc,
847 __void_t<typename _Alloc::value_type,
848 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
851 template<
typename _Alloc>
852 using _RequireAllocator
853 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
855 template<
typename _Alloc>
856 using _RequireNotAllocator
857 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
859#if __cpp_concepts >= 201907L
860 template<
typename _Alloc>
861 concept __allocator_like =
requires (_Alloc& __a) {
862 typename _Alloc::value_type;
863 __a.deallocate(__a.allocate(1u), 1u);
872 template<
typename _Alloc,
bool = __is_empty(_Alloc)>
874 {
static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
876 template<
typename _Alloc>
877 struct __alloc_swap<_Alloc, false>
880 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
888#if __cplusplus >= 201103L
889 template<
typename _Tp,
bool
890 = __or_<is_copy_constructible<typename _Tp::value_type>,
891 is_nothrow_move_constructible<typename _Tp::value_type>>::value>
892 struct __shrink_to_fit_aux
893 {
static bool _S_do_it(_Tp&)
noexcept {
return false; } };
895 template<
typename _Tp>
896 struct __shrink_to_fit_aux<_Tp, true>
900 _S_do_it(_Tp& __c)
noexcept
905 _Tp(__make_move_if_noexcept_iterator(__c.begin()),
906 __make_move_if_noexcept_iterator(__c.end()),
907 __c.get_allocator()).swap(__c);
925 template<
typename _ForwardIterator,
typename _Allocator>
928 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
931 for (; __first != __last; ++__first)
932#
if __cplusplus < 201103L
941 template<
typename _ForwardIterator,
typename _Tp>
942 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
944 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
952_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.