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)
256 #if __cplusplus <= 201703L
257 ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...);
259 std::construct_at(__p, std::forward<_Args>(__args)...);
263 template<
typename _Alloc2,
typename _Tp>
264 static _GLIBCXX14_CONSTEXPR
auto
265 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
266 noexcept(noexcept(__a.destroy(__p)))
267 -> decltype(__a.destroy(__p))
268 { __a.destroy(__p); }
270 template<
typename _Alloc2,
typename _Tp>
271 static _GLIBCXX14_CONSTEXPR
void
272 _S_destroy(_Alloc2&, _Tp* __p, ...)
273 noexcept(
std::is_nothrow_destructible<_Tp>::value)
276 template<
typename _Alloc2>
277 static constexpr
auto
278 _S_max_size(_Alloc2& __a,
int)
279 -> decltype(__a.max_size())
280 {
return __a.max_size(); }
282 template<
typename _Alloc2>
284 _S_max_size(_Alloc2&, ...)
288 return __gnu_cxx::__numeric_traits<size_type>::__max
292 template<
typename _Alloc2>
293 static constexpr
auto
294 _S_select(_Alloc2& __a,
int)
295 -> decltype(__a.select_on_container_copy_construction())
296 {
return __a.select_on_container_copy_construction(); }
298 template<
typename _Alloc2>
299 static constexpr _Alloc2
300 _S_select(_Alloc2& __a, ...)
312 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
314 {
return __a.allocate(__n); }
327 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
329 {
return _S_allocate(__a, __n, __hint, 0); }
339 static _GLIBCXX20_CONSTEXPR
void
341 { __a.deallocate(__p, __n); }
354 template<
typename _Tp,
typename... _Args>
355 static _GLIBCXX20_CONSTEXPR
auto
357 noexcept(noexcept(_S_construct(__a, __p,
358 std::forward<_Args>(__args)...)))
359 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
360 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
370 template<
typename _Tp>
371 static _GLIBCXX20_CONSTEXPR
void
373 noexcept(noexcept(_S_destroy(__a, __p, 0)))
374 { _S_destroy(__a, __p, 0); }
386 {
return _S_max_size(__a, 0); }
396 static _GLIBCXX20_CONSTEXPR _Alloc
398 {
return _S_select(__rhs, 0); }
401 #if __cplusplus > 201703L
402 # define __cpp_lib_constexpr_dynamic_alloc 201907L
406 template<
typename _Tp>
445 template<
typename _Up>
448 template<
typename _Up>
458 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
460 {
return __a.allocate(__n); }
472 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
475 #if __cplusplus <= 201703L
476 return __a.allocate(__n, __hint);
478 return __a.allocate(__n);
490 static _GLIBCXX20_CONSTEXPR
void
492 { __a.deallocate(__p, __n); }
505 template<
typename _Up,
typename... _Args>
506 static _GLIBCXX20_CONSTEXPR
void
511 #if __cplusplus <= 201703L
512 __a.construct(__p, std::forward<_Args>(__args)...);
514 std::construct_at(__p, std::forward<_Args>(__args)...);
525 template<
typename _Up>
526 static _GLIBCXX20_CONSTEXPR
void
530 #if __cplusplus <= 201703L
533 std::destroy_at(__p);
545 #if __cplusplus <= 201703L
546 return __a.max_size();
602 template<
typename _Up>
605 template<
typename _Up>
627 template<
typename _Up,
typename... _Args>
628 static _GLIBCXX20_CONSTEXPR
void
632 #if __cplusplus <= 201703L
633 ::new((
void *)__p) _Up(std::forward<_Args>(__args)...);
635 std::construct_at(__p, std::forward<_Args>(__args)...);
646 template<
typename _Up>
647 static _GLIBCXX20_CONSTEXPR
void
666 #if __cplusplus < 201703L
667 template<
typename _Alloc>
669 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
672 template<
typename _Alloc>
674 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
678 template<
typename _Alloc>
679 _GLIBCXX14_CONSTEXPR
inline void
680 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
682 typedef allocator_traits<_Alloc> __traits;
683 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
684 #if __cplusplus >= 201703L
685 if constexpr (__pocca::value)
688 __do_alloc_on_copy(__one, __two, __pocca());
692 template<
typename _Alloc>
694 __alloc_on_copy(
const _Alloc& __a)
696 typedef allocator_traits<_Alloc> __traits;
697 return __traits::select_on_container_copy_construction(__a);
700 #if __cplusplus < 201703L
701 template<
typename _Alloc>
702 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
705 template<
typename _Alloc>
706 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
710 template<
typename _Alloc>
711 _GLIBCXX14_CONSTEXPR
inline void
712 __alloc_on_move(_Alloc& __one, _Alloc& __two)
714 typedef allocator_traits<_Alloc> __traits;
715 typedef typename __traits::propagate_on_container_move_assignment __pocma;
716 #if __cplusplus >= 201703L
717 if constexpr (__pocma::value)
720 __do_alloc_on_move(__one, __two, __pocma());
724 #if __cplusplus < 201703L
725 template<
typename _Alloc>
726 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
732 template<
typename _Alloc>
733 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
737 template<
typename _Alloc>
738 _GLIBCXX14_CONSTEXPR
inline void
739 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
741 typedef allocator_traits<_Alloc> __traits;
742 typedef typename __traits::propagate_on_container_swap __pocs;
743 #if __cplusplus >= 201703L
744 if constexpr (__pocs::value)
750 __do_alloc_on_swap(__one, __two, __pocs());
754 template<
typename _Alloc,
typename _Tp,
755 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
757 struct __is_alloc_insertable_impl
761 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
762 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
763 __void_t<decltype(allocator_traits<_Alloc>::construct(
764 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
765 std::declval<_Tp>()))>>
772 template<
typename _Alloc>
773 struct __is_copy_insertable
774 : __is_alloc_insertable_impl<_Alloc,
775 typename _Alloc::value_type const&>::type
779 template<
typename _Tp>
780 struct __is_copy_insertable<allocator<_Tp>>
781 : is_copy_constructible<_Tp>
787 template<
typename _Alloc>
788 struct __is_move_insertable
789 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
793 template<
typename _Tp>
794 struct __is_move_insertable<allocator<_Tp>>
795 : is_move_constructible<_Tp>
799 template<
typename _Alloc,
typename =
void>
802 template<
typename _Alloc>
803 struct __is_allocator<_Alloc,
804 __void_t<typename _Alloc::value_type,
805 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
808 template<
typename _Alloc>
809 using _RequireAllocator
810 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
812 template<
typename _Alloc>
813 using _RequireNotAllocator
814 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
823 template<
typename _ForwardIterator,
typename _Allocator>
825 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
828 for (; __first != __last; ++__first)
829 #
if __cplusplus < 201103L
837 template<
typename _ForwardIterator,
typename _Tp>
839 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
845 _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 _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
ISO C++ entities toplevel namespace is std.
void _Destroy(_ForwardIterator __first, _ForwardIterator __last, _Allocator &__alloc)
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.
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.
__detected_or_t< typename is_empty< _Alloc >::type, __equal, _Alloc > is_always_equal
Whether all instances of the allocator type compare equal.
_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.
static void * allocate(allocator_type &, size_type, const void *=nullptr)=delete
allocate is ill-formed for allocator<void>
std::ptrdiff_t difference_type
The allocator's difference type.
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
allocator<void> specialization.
The standard allocator, as per C++03 [20.4.1].
Uniform interface to all pointer-like types.
__detected_or_t< ptrdiff_t, __difference_type, _Ptr > difference_type
The type used to represent the difference between two pointers.