30#ifndef _ALLOC_TRAITS_H
31#define _ALLOC_TRAITS_H 1
35#if __cplusplus >= 201103L
41namespace std _GLIBCXX_VISIBILITY(default)
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
45#if __cplusplus >= 201103L
46#define __cpp_lib_allocator_traits_is_always_equal 201411L
49 struct __allocator_traits_base
51 template<
typename _Tp,
typename _Up,
typename =
void>
52 struct __rebind : __replace_first_arg<_Tp, _Up> { };
54 template<
typename _Tp,
typename _Up>
55 struct __rebind<_Tp, _Up,
56 __void_t<typename _Tp::template rebind<_Up>::other>>
57 {
using type =
typename _Tp::template rebind<_Up>::other; };
60 template<
typename _Tp>
61 using __pointer =
typename _Tp::pointer;
62 template<
typename _Tp>
63 using __c_pointer =
typename _Tp::const_pointer;
64 template<
typename _Tp>
65 using __v_pointer =
typename _Tp::void_pointer;
66 template<
typename _Tp>
67 using __cv_pointer =
typename _Tp::const_void_pointer;
68 template<
typename _Tp>
69 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
70 template<
typename _Tp>
71 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
72 template<
typename _Tp>
73 using __pocs =
typename _Tp::propagate_on_container_swap;
74 template<
typename _Tp>
75 using __equal = __type_identity<typename _Tp::is_always_equal>;
78 template<
typename _Alloc,
typename _Up>
80 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
89 template<
typename _Alloc>
106 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
112 template<
template<
typename>
class _Func,
typename _Tp>
113 struct _Ptr<_Func, _Tp,
__void_t<_Func<_Alloc>>>
119 template<
typename _A2,
typename _PtrT,
typename =
void>
121 {
using type =
typename pointer_traits<_PtrT>::difference_type; };
123 template<
typename _A2,
typename _PtrT>
125 {
using type =
typename _A2::difference_type; };
128 template<
typename _A2,
typename _DiffT,
typename =
void>
129 struct _Size : make_unsigned<_DiffT> { };
131 template<
typename _A2,
typename _DiffT>
132 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
133 {
using type =
typename _A2::size_type; };
174 using size_type =
typename _Size<_Alloc, difference_type>::type;
212 template<
typename _Tp>
214 template<
typename _Tp>
218 template<
typename _Alloc2>
219 static constexpr auto
221 ->
decltype(__a.allocate(__n,
__hint))
222 {
return __a.allocate(__n,
__hint); }
224 template<
typename _Alloc2>
227 {
return __a.allocate(__n); }
229 template<
typename _Tp,
typename... _Args>
230 struct __construct_helper
232 template<
typename _Alloc2,
240 using type =
decltype(__test<_Alloc>(0));
243 template<
typename _Tp,
typename... _Args>
244 using __has_construct
245 =
typename __construct_helper<_Tp, _Args...>::type;
247 template<
typename _Tp,
typename... _Args>
248 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
249 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
253 template<
typename _Tp,
typename... _Args>
254 static _GLIBCXX14_CONSTEXPR
255 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
256 is_constructible<_Tp, _Args...>>>
257 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
260#if __cplusplus <= 201703L
267 template<
typename _Alloc2,
typename _Tp>
268 static _GLIBCXX14_CONSTEXPR
auto
269 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
270 noexcept(
noexcept(__a.destroy(__p)))
271 ->
decltype(__a.destroy(__p))
272 { __a.destroy(__p); }
274 template<
typename _Alloc2,
typename _Tp>
275 static _GLIBCXX14_CONSTEXPR
void
276 _S_destroy(_Alloc2&, _Tp* __p, ...)
277 noexcept(
std::is_nothrow_destructible<_Tp>::value)
280 template<
typename _Alloc2>
281 static constexpr auto
282 _S_max_size(_Alloc2& __a,
int)
283 ->
decltype(__a.max_size())
284 {
return __a.max_size(); }
286 template<
typename _Alloc2>
288 _S_max_size(_Alloc2&, ...)
292 return __gnu_cxx::__numeric_traits<size_type>::__max
296 template<
typename _Alloc2>
297 static constexpr auto
298 _S_select(_Alloc2& __a,
int)
299 ->
decltype(__a.select_on_container_copy_construction())
300 {
return __a.select_on_container_copy_construction(); }
302 template<
typename _Alloc2>
303 static constexpr _Alloc2
304 _S_select(_Alloc2& __a, ...)
316 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR
pointer
318 {
return __a.allocate(__n); }
333 {
return _S_allocate(__a, __n,
__hint, 0); }
345 { __a.deallocate(__p, __n); }
358 template<
typename _Tp,
typename...
_Args>
361 noexcept(
noexcept(_S_construct(__a, __p,
374 template<
typename _Tp>
377 noexcept(
noexcept(_S_destroy(__a, __p, 0)))
378 { _S_destroy(__a, __p, 0); }
390 {
return _S_max_size(__a, 0); }
402 {
return _S_select(
__rhs, 0); }
405#if __cplusplus > 201703L
406# define __cpp_lib_constexpr_dynamic_alloc 201907L
410 template<
typename _Tp>
449 template<
typename _Up>
452 template<
typename _Up>
464 {
return __a.allocate(__n); }
479#if __cplusplus <= 201703L
480 return __a.allocate(__n,
__hint);
482 return __a.allocate(__n);
496 { __a.deallocate(__p, __n); }
509 template<
typename _Up,
typename...
_Args>
515#if __cplusplus <= 201703L
529 template<
typename _Up>
534#if __cplusplus <= 201703L
537 std::destroy_at(__p);
549#if __cplusplus <= 201703L
550 return __a.max_size();
606 template<
typename _Up>
609 template<
typename _Up>
631 template<
typename _Up,
typename...
_Args>
644 template<
typename _Up>
665#if __cplusplus < 201703L
666 template<
typename _Alloc>
668 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
671 template<
typename _Alloc>
673 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
677 template<
typename _Alloc>
678 _GLIBCXX14_CONSTEXPR
inline void
679 __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
681 typedef allocator_traits<_Alloc> __traits;
682 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
683#if __cplusplus >= 201703L
684 if constexpr (__pocca::value)
687 __do_alloc_on_copy(__one, __two, __pocca());
691 template<
typename _Alloc>
693 __alloc_on_copy(
const _Alloc& __a)
695 typedef allocator_traits<_Alloc> __traits;
696 return __traits::select_on_container_copy_construction(__a);
699#if __cplusplus < 201703L
700 template<
typename _Alloc>
701 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
704 template<
typename _Alloc>
705 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
709 template<
typename _Alloc>
710 _GLIBCXX14_CONSTEXPR
inline void
711 __alloc_on_move(_Alloc& __one, _Alloc& __two)
713 typedef allocator_traits<_Alloc> __traits;
714 typedef typename __traits::propagate_on_container_move_assignment __pocma;
715#if __cplusplus >= 201703L
716 if constexpr (__pocma::value)
719 __do_alloc_on_move(__one, __two, __pocma());
723#if __cplusplus < 201703L
724 template<
typename _Alloc>
725 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
731 template<
typename _Alloc>
732 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
736 template<
typename _Alloc>
737 _GLIBCXX14_CONSTEXPR
inline void
738 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
740 typedef allocator_traits<_Alloc> __traits;
741 typedef typename __traits::propagate_on_container_swap __pocs;
742#if __cplusplus >= 201703L
743 if constexpr (__pocs::value)
749 __do_alloc_on_swap(__one, __two, __pocs());
753 template<
typename _Alloc,
typename _Tp,
754 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
756 struct __is_alloc_insertable_impl
760 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
761 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
762 __void_t<decltype(allocator_traits<_Alloc>::construct(
763 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
764 std::declval<_Tp>()))>>
771 template<
typename _Alloc>
772 struct __is_copy_insertable
773 : __is_alloc_insertable_impl<_Alloc,
774 typename _Alloc::value_type const&>::type
778 template<
typename _Tp>
779 struct __is_copy_insertable<allocator<_Tp>>
780 : is_copy_constructible<_Tp>
786 template<
typename _Alloc>
787 struct __is_move_insertable
788 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
792 template<
typename _Tp>
793 struct __is_move_insertable<allocator<_Tp>>
794 : is_move_constructible<_Tp>
798 template<
typename _Alloc,
typename =
void>
801 template<
typename _Alloc>
802 struct __is_allocator<_Alloc,
803 __void_t<typename _Alloc::value_type,
804 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
807 template<
typename _Alloc>
808 using _RequireAllocator
809 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
811 template<
typename _Alloc>
812 using _RequireNotAllocator
813 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
815#if __cpp_concepts >= 201907L
816 template<
typename _Alloc>
817 concept __allocator_like =
requires (_Alloc& __a) {
818 typename _Alloc::value_type;
819 __a.deallocate(__a.allocate(1u), 1u);
833 template<
typename _ForwardIterator,
typename _Allocator>
836 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
839 for (; __first != __last; ++__first)
840#
if __cplusplus < 201103L
848 template<
typename _ForwardIterator,
typename _Tp>
851 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
858_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
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.
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.
_Alloc allocator_type
The allocator type.
allocator< _Tp > allocator_type
The allocator 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.
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.
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
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.
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.
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.