30 #ifndef _ALLOC_TRAITS_H 31 #define _ALLOC_TRAITS_H 1 33 #if __cplusplus >= 201103L 39 #define __cpp_lib_allocator_traits_is_always_equal 201411 41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 struct __allocator_traits_base
47 template<
typename _Tp,
typename _Up,
typename =
void>
48 struct __rebind : __replace_first_arg<_Tp, _Up> { };
50 template<
typename _Tp,
typename _Up>
51 struct __rebind<_Tp, _Up,
52 __void_t<typename _Tp::template rebind<_Up>::other>>
53 {
using type =
typename _Tp::template rebind<_Up>::other; };
56 template<
typename _Tp>
57 using __pointer =
typename _Tp::pointer;
58 template<
typename _Tp>
59 using __c_pointer =
typename _Tp::const_pointer;
60 template<
typename _Tp>
61 using __v_pointer =
typename _Tp::void_pointer;
62 template<
typename _Tp>
63 using __cv_pointer =
typename _Tp::const_void_pointer;
64 template<
typename _Tp>
65 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
66 template<
typename _Tp>
67 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
68 template<
typename _Tp>
69 using __pocs =
typename _Tp::propagate_on_container_swap;
70 template<
typename _Tp>
71 using __equal =
typename _Tp::is_always_equal;
74 template<
typename _Alloc,
typename _Up>
76 =
typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
82 template<
typename _Alloc>
95 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
99 template<
template<
typename>
class _Func,
typename _Tp,
typename =
void>
105 template<
template<
typename>
class _Func,
typename _Tp>
106 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
108 using type = _Func<_Alloc>;
112 template<
typename _A2,
typename _PtrT,
typename =
void>
116 template<
typename _A2,
typename _PtrT>
118 {
using type =
typename _A2::difference_type; };
121 template<
typename _A2,
typename _DiffT,
typename =
void>
122 struct _Size : make_unsigned<_DiffT> { };
124 template<
typename _A2,
typename _DiffT>
125 struct _Size<_A2, _DiffT, __void_t<typename _A2::
size_type>>
126 {
using type =
typename _A2::size_type; };
167 using size_type =
typename _Size<_Alloc, difference_type>::type;
176 = __detected_or_t<false_type, __pocca, _Alloc>;
185 = __detected_or_t<false_type, __pocma, _Alloc>;
194 = __detected_or_t<false_type, __pocs, _Alloc>;
203 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
205 template<
typename _Tp>
206 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
207 template<
typename _Tp>
211 template<
typename _Alloc2>
214 -> decltype(__a.allocate(__n, __hint))
215 {
return __a.
allocate(__n, __hint); }
217 template<
typename _Alloc2>
220 {
return __a.allocate(__n); }
222 template<
typename _Tp,
typename... _Args>
223 struct __construct_helper
225 template<
typename _Alloc2,
226 typename = decltype(std::declval<_Alloc2*>()->
construct(
227 std::declval<_Tp*>(), std::declval<_Args>()...))>
233 using type = decltype(__test<_Alloc>(0));
236 template<
typename _Tp,
typename... _Args>
237 using __has_construct
238 =
typename __construct_helper<_Tp, _Args...>::type;
240 template<
typename _Tp,
typename... _Args>
241 static _Require<__has_construct<_Tp, _Args...>>
242 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
243 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
244 { __a.construct(__p, std::forward<_Args>(__args)...); }
246 template<
typename _Tp,
typename... _Args>
248 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
249 is_constructible<_Tp, _Args...>>>
250 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
251 noexcept(noexcept(::
new((
void*)__p)
252 _Tp(std::forward<_Args>(__args)...)))
253 { ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...); }
255 template<
typename _Alloc2,
typename _Tp>
257 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
258 noexcept(noexcept(__a.destroy(__p)))
259 -> decltype(__a.destroy(__p))
260 { __a.destroy(__p); }
262 template<
typename _Alloc2,
typename _Tp>
264 _S_destroy(_Alloc2&, _Tp* __p, ...)
265 noexcept(noexcept(__p->~_Tp()))
268 template<
typename _Alloc2>
270 _S_max_size(_Alloc2& __a,
int)
271 -> decltype(__a.max_size())
272 {
return __a.max_size(); }
274 template<
typename _Alloc2>
276 _S_max_size(_Alloc2&, ...)
280 return __gnu_cxx::__numeric_traits<size_type>::__max
284 template<
typename _Alloc2>
286 _S_select(_Alloc2& __a,
int)
287 -> decltype(__a.select_on_container_copy_construction())
288 {
return __a.select_on_container_copy_construction(); }
290 template<
typename _Alloc2>
292 _S_select(_Alloc2& __a, ...)
304 _GLIBCXX_NODISCARD
static pointer 306 {
return __a.allocate(__n); }
319 _GLIBCXX_NODISCARD
static pointer 321 {
return _S_allocate(__a, __n, __hint, 0); }
333 { __a.deallocate(__p, __n); }
346 template<
typename _Tp,
typename... _Args>
347 static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
348 noexcept(noexcept(_S_construct(__a, __p,
349 std::forward<_Args>(__args)...)))
350 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
351 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
361 template<
typename _Tp>
363 noexcept(noexcept(_S_destroy(__a, __p, 0)))
364 { _S_destroy(__a, __p, 0); }
375 {
return _S_max_size(__a, 0); }
387 {
return _S_select(__rhs, 0); }
391 template<
typename _Tp>
429 template<
typename _Up>
432 template<
typename _Up>
442 _GLIBCXX_NODISCARD
static pointer 444 {
return __a.allocate(__n); }
456 _GLIBCXX_NODISCARD
static pointer 458 {
return __a.allocate(__n, __hint); }
470 { __a.deallocate(__p, __n); }
480 template<
typename _Up,
typename... _Args>
483 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
484 { __a.construct(__p, std::forward<_Args>(__args)...); }
493 template<
typename _Up>
496 noexcept(noexcept(__a.destroy(__p)))
497 { __a.destroy(__p); }
506 {
return __a.max_size(); }
519 template<
typename _Alloc>
521 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
524 template<
typename _Alloc>
526 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
529 template<
typename _Alloc>
530 inline void __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
532 typedef allocator_traits<_Alloc> __traits;
533 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
534 __do_alloc_on_copy(__one, __two, __pocca());
537 template<
typename _Alloc>
538 inline _Alloc __alloc_on_copy(
const _Alloc& __a)
540 typedef allocator_traits<_Alloc> __traits;
541 return __traits::select_on_container_copy_construction(__a);
544 template<
typename _Alloc>
545 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
546 { __one = std::move(__two); }
548 template<
typename _Alloc>
549 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
552 template<
typename _Alloc>
553 inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
555 typedef allocator_traits<_Alloc> __traits;
556 typedef typename __traits::propagate_on_container_move_assignment __pocma;
557 __do_alloc_on_move(__one, __two, __pocma());
560 template<
typename _Alloc>
561 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
567 template<
typename _Alloc>
568 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
571 template<
typename _Alloc>
572 inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
574 typedef allocator_traits<_Alloc> __traits;
575 typedef typename __traits::propagate_on_container_swap __pocs;
576 __do_alloc_on_swap(__one, __two, __pocs());
579 template<
typename _Alloc,
typename _Tp,
580 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
582 struct __is_alloc_insertable_impl
586 template<
typename _Alloc,
typename _Tp,
typename _ValueT>
587 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
588 __void_t<decltype(allocator_traits<_Alloc>::construct(
589 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
590 std::declval<_Tp>()))>>
597 template<
typename _Alloc>
598 struct __is_copy_insertable
599 : __is_alloc_insertable_impl<_Alloc,
600 typename _Alloc::value_type const&>::type
604 template<
typename _Tp>
605 struct __is_copy_insertable<allocator<_Tp>>
606 : is_copy_constructible<_Tp>
612 template<
typename _Alloc>
613 struct __is_move_insertable
614 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
618 template<
typename _Tp>
619 struct __is_move_insertable<allocator<_Tp>>
620 : is_move_constructible<_Tp>
624 template<
typename _Alloc,
typename =
void>
627 template<
typename _Alloc>
628 struct __is_allocator<_Alloc,
629 __void_t<typename _Alloc::value_type,
630 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
633 template<
typename _Alloc>
634 using _RequireAllocator
635 =
typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
637 template<
typename _Alloc>
638 using _RequireNotAllocator
639 =
typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
641 _GLIBCXX_END_NAMESPACE_VERSION
644 #endif // _ALLOC_TRAITS_H
__detected_or_t< value_type *, __pointer, _Tp_alloc_type > pointer
The allocator's pointer type.
static _GLIBCXX_NODISCARD pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
static allocator_type select_on_container_copy_construction(const allocator_type &__rhs)
Obtain an allocator to use when copying a container.
static void construct(allocator_type &__a, _Up *__p, _Args &&... __args) noexcept(noexcept(__a.construct(__p, std::forward< _Args >(__args)...)))
Construct an object of type _Up.
ISO C++ entities toplevel namespace is std.
std::size_t size_type
The allocator's size type.
allocator< _Tp > allocator_type
The allocator type.
const _Tp * const_pointer
The allocator's const pointer type.
typename _Ptr< __c_pointer, const value_type >::type const_pointer
The allocator's const pointer type.
_Tp * pointer
The allocator's pointer type.
const void * const_void_pointer
The allocator's const void pointer type.
__detected_or_t< ptrdiff_t, __difference_type, _Ptr > difference_type
The type used to represent the difference between two pointers.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
typename _Size< _Alloc, difference_type >::type size_type
The allocator's size type.
static void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
_Tp value_type
The allocated type.
std::ptrdiff_t difference_type
The allocator's difference type.
The standard allocator, as per [20.4].
static 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.
Uniform interface to all allocator types.
__detected_or_t< false_type, __pocca, _Tp_alloc_type > propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
_Alloc::value_type value_type
The allocated type.
static void destroy(allocator_type &__a, _Up *__p) noexcept(noexcept(__a.destroy(__p)))
Destroy an object of type _Up.
Uniform interface to all pointer-like types.
__detected_or_t< typename is_empty< _Tp_alloc_type >::type, __equal, _Tp_alloc_type > is_always_equal
Whether all instances of the allocator type compare equal.
__detected_or_t< false_type, __pocma, _Tp_alloc_type > propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
static size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
typename _Ptr< __v_pointer, void >::type void_pointer
The allocator's void pointer type.
__detected_or_t< false_type, __pocs, _Tp_alloc_type > propagate_on_container_swap
How the allocator is propagated on swap.
_Alloc allocator_type
The allocator type.
static void destroy(_Alloc &__a, _Tp *__p) noexcept(noexcept(_S_destroy(__a, __p, 0)))
Destroy an object of type _Tp.
static _Alloc select_on_container_copy_construction(const _Alloc &__rhs)
Obtain an allocator to use when copying a container.
static _GLIBCXX_NODISCARD pointer allocate(allocator_type &__a, size_type __n)
Allocate memory.
static _GLIBCXX_NODISCARD pointer allocate(allocator_type &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
typename _Diff< _Alloc, pointer >::type difference_type
The allocator's difference type.
static void deallocate(allocator_type &__a, pointer __p, size_type __n)
Deallocate memory.
void * void_pointer
The allocator's void pointer type.
static size_type max_size(const allocator_type &__a) noexcept
The maximum supported allocation size.
typename _Ptr< __cv_pointer, const void >::type const_void_pointer
The allocator's const void pointer type.