30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
35 #if __cplusplus >= 201103L
43 namespace 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
954 #endif // _ALLOC_TRAITS_H