30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
35 #if __cplusplus >= 201103L
41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 #if __cplusplus >= 201103L
46 #define __cpp_lib_allocator_traits_is_always_equal 201411
48 struct __allocator_traits_base
50 template<
typename _Tp,
typename _Up,
typename =
void>
51 struct __rebind : __replace_first_arg<_Tp, _Up> { };
53 template<
typename _Tp,
typename _Up>
54 struct __rebind<_Tp, _Up,
55 __void_t<typename _Tp::template rebind<_Up>::other>>
56 {
using type =
typename _Tp::template rebind<_Up>::other; };
59 template<
typename _Tp>
60 using __pointer =
typename _Tp::pointer;
61 template<
typename _Tp>
62 using __c_pointer =
typename _Tp::const_pointer;
63 template<
typename _Tp>
64 using __v_pointer =
typename _Tp::void_pointer;
65 template<
typename _Tp>
66 using __cv_pointer =
typename _Tp::const_void_pointer;
67 template<
typename _Tp>
68 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
69 template<
typename _Tp>
70 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
71 template<
typename _Tp>
72 using __pocs =
typename _Tp::propagate_on_container_swap;
73 template<
typename _Tp>
74 using __equal =
typename _Tp::is_always_equal;
77 template<
typename _Alloc,
typename _Up>
79 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
85 template<
typename _Alloc>
98 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
102 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
108 template<
template<
typename>
class _Func,
typename _Tp>
109 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
111 using type = _Func<_Alloc>;
115 template<
typename _A2,
typename _PtrT,
typename =
void>
119 template<
typename _A2,
typename _PtrT>
121 {
using type =
typename _A2::difference_type; };
124 template<
typename _A2,
typename _DiffT,
typename =
void>
125 struct _Size : make_unsigned<_DiffT> { };
127 template<
typename _A2,
typename _DiffT>
128 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
129 {
using type =
typename _A2::size_type; };
170 using size_type =
typename _Size<_Alloc, difference_type>::type;
179 = __detected_or_t<false_type, __pocca, _Alloc>;
188 = __detected_or_t<false_type, __pocma, _Alloc>;
197 = __detected_or_t<false_type, __pocs, _Alloc>;
206 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
208 template<
typename _Tp>
209 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
210 template<
typename _Tp>
214 template<
typename _Alloc2>
215 static constexpr
auto
217 -> decltype(__a.allocate(__n, __hint))
218 {
return __a.
allocate(__n, __hint); }
220 template<
typename _Alloc2>
223 {
return __a.allocate(__n); }
225 template<
typename _Tp,
typename... _Args>
226 struct __construct_helper
228 template<
typename _Alloc2,
229 typename = decltype(std::declval<_Alloc2*>()->
construct(
230 std::declval<_Tp*>(), std::declval<_Args>()...))>
236 using type = decltype(__test<_Alloc>(0));
239 template<
typename _Tp,
typename... _Args>
240 using __has_construct
241 =
typename __construct_helper<_Tp, _Args...>::type;
243 template<
typename _Tp,
typename... _Args>
244 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
245 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
246 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
247 { __a.construct(__p, std::forward<_Args>(__args)...); }
249 template<
typename _Tp,
typename... _Args>
250 static _GLIBCXX14_CONSTEXPR
251 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
252 is_constructible<_Tp, _Args...>>>
253 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
254 noexcept(noexcept(::
new((
void*)__p)
255 _Tp(std::forward<_Args>(__args)...)))
258 template<
typename _Alloc2,
typename _Tp>
259 static _GLIBCXX14_CONSTEXPR
auto
260 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
261 noexcept(noexcept(__a.destroy(__p)))
262 -> decltype(__a.destroy(__p))
263 { __a.destroy(__p); }
265 template<
typename _Alloc2,
typename _Tp>
266 static _GLIBCXX14_CONSTEXPR
void
267 _S_destroy(_Alloc2&, _Tp* __p, ...)
268 noexcept(noexcept(__p->~_Tp()))
271 template<
typename _Alloc2>
272 static constexpr
auto
273 _S_max_size(_Alloc2& __a,
int)
274 -> decltype(__a.max_size())
275 {
return __a.max_size(); }
277 template<
typename _Alloc2>
279 _S_max_size(_Alloc2&, ...)
283 return __gnu_cxx::__numeric_traits<size_type>::__max
287 template<
typename _Alloc2>
288 static constexpr
auto
289 _S_select(_Alloc2& __a,
int)
290 -> decltype(__a.select_on_container_copy_construction())
291 {
return __a.select_on_container_copy_construction(); }
293 template<
typename _Alloc2>
294 static constexpr _Alloc2
295 _S_select(_Alloc2& __a, ...)
307 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
309 {
return __a.allocate(__n); }
322 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
324 {
return _S_allocate(__a, __n, __hint, 0); }
334 static _GLIBCXX20_CONSTEXPR
void
336 { __a.deallocate(__p, __n); }
349 template<
typename _Tp,
typename... _Args>
350 static _GLIBCXX20_CONSTEXPR
auto
352 noexcept(noexcept(_S_construct(__a, __p,
353 std::forward<_Args>(__args)...)))
354 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
355 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
365 template<
typename _Tp>
366 static _GLIBCXX20_CONSTEXPR
void
368 noexcept(noexcept(_S_destroy(__a, __p, 0)))
369 { _S_destroy(__a, __p, 0); }
381 {
return _S_max_size(__a, 0); }
391 static _GLIBCXX20_CONSTEXPR _Alloc
393 {
return _S_select(__rhs, 0); }
396 #if __cplusplus > 201703L
397 # define __cpp_lib_constexpr_dynamic_alloc 201907L
401 template<
typename _Tp>
440 template<
typename _Up>
443 template<
typename _Up>
453 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
455 {
return __a.allocate(__n); }
467 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
470 #if __cplusplus <= 201703L
471 return __a.allocate(__n, __hint);
473 return __a.allocate(__n);
485 static _GLIBCXX20_CONSTEXPR
void
487 { __a.deallocate(__p, __n); }
500 template<
typename _Up,
typename... _Args>
501 static _GLIBCXX20_CONSTEXPR
void
504 noexcept(noexcept(::
new((
void*)__p) _Up(std::declval<_Args>()...)))
506 #if __cplusplus <= 201703L
507 __a.construct(__p, std::forward<_Args>(__args)...);
509 std::construct_at(__p, std::forward<_Args>(__args)...);
520 template<
typename _Up>
521 static _GLIBCXX20_CONSTEXPR
void
525 #if __cplusplus <= 201703L
528 std::destroy_at(__p);
540 #if __cplusplus <= 201703L
541 return __a.max_size();
557 #if __cplusplus < 201703L
558 template<
typename _Alloc>
560 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
563 template<
typename _Alloc>
565 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
569 template<
typename _Alloc>
570 _GLIBCXX14_CONSTEXPR
inline void
571 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
573 typedef allocator_traits<_Alloc> __traits;
574 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
575 #if __cplusplus >= 201703L
576 if constexpr (__pocca::value)
579 __do_alloc_on_copy(__one, __two, __pocca());
583 template<
typename _Alloc>
585 __alloc_on_copy(
const _Alloc& __a)
587 typedef allocator_traits<_Alloc> __traits;
588 return __traits::select_on_container_copy_construction(__a);
591 #if __cplusplus < 201703L
592 template<
typename _Alloc>
593 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
596 template<
typename _Alloc>
597 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
601 template<
typename _Alloc>
602 _GLIBCXX14_CONSTEXPR
inline void
603 __alloc_on_move(_Alloc& __one, _Alloc& __two)
605 typedef allocator_traits<_Alloc> __traits;
606 typedef typename __traits::propagate_on_container_move_assignment __pocma;
607 #if __cplusplus >= 201703L
608 if constexpr (__pocma::value)
611 __do_alloc_on_move(__one, __two, __pocma());
615 #if __cplusplus < 201703L
616 template<
typename _Alloc>
617 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
623 template<
typename _Alloc>
624 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
628 template<
typename _Alloc>
629 _GLIBCXX14_CONSTEXPR
inline void
630 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
632 typedef allocator_traits<_Alloc> __traits;
633 typedef typename __traits::propagate_on_container_swap __pocs;
634 #if __cplusplus >= 201703L
635 if constexpr (__pocs::value)
641 __do_alloc_on_swap(__one, __two, __pocs());
645 template<
typename _Alloc,
typename _Tp,
646 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
648 struct __is_alloc_insertable_impl
652 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
653 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
654 __void_t<decltype(allocator_traits<_Alloc>::construct(
655 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
656 std::declval<_Tp>()))>>
663 template<
typename _Alloc>
664 struct __is_copy_insertable
665 : __is_alloc_insertable_impl<_Alloc,
666 typename _Alloc::value_type const&>::type
670 template<
typename _Tp>
671 struct __is_copy_insertable<allocator<_Tp>>
672 : is_copy_constructible<_Tp>
678 template<
typename _Alloc>
679 struct __is_move_insertable
680 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
684 template<
typename _Tp>
685 struct __is_move_insertable<allocator<_Tp>>
686 : is_move_constructible<_Tp>
690 template<
typename _Alloc,
typename =
void>
693 template<
typename _Alloc>
694 struct __is_allocator<_Alloc,
695 __void_t<typename _Alloc::value_type,
696 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
699 template<
typename _Alloc>
700 using _RequireAllocator
701 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
703 template<
typename _Alloc>
704 using _RequireNotAllocator
705 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
714 template<
typename _ForwardIterator,
typename _Allocator>
716 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
719 for (; __first != __last; ++__first)
720 #
if __cplusplus < 201103L
728 template<
typename _ForwardIterator,
typename _Tp>
730 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
736 _GLIBCXX_END_NAMESPACE_VERSION
738 #endif // _ALLOC_TRAITS_H