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 _Alloc,
typename _Up>
48 using __rebind =
typename _Alloc::template rebind<_Up>::other;
51 template<
typename _Tp>
52 using __pointer =
typename _Tp::pointer;
53 template<
typename _Tp>
54 using __c_pointer =
typename _Tp::const_pointer;
55 template<
typename _Tp>
56 using __v_pointer =
typename _Tp::void_pointer;
57 template<
typename _Tp>
58 using __cv_pointer =
typename _Tp::const_void_pointer;
59 template<
typename _Tp>
60 using __diff_type =
typename _Tp::difference_type;
61 template<
typename _Tp>
62 using __size_type =
typename _Tp::size_type;
63 template<
typename _Tp>
64 using __pocca =
typename _Tp::propagate_on_container_copy_assignment;
65 template<
typename _Tp>
66 using __pocma =
typename _Tp::propagate_on_container_move_assignment;
67 template<
typename _Tp>
68 using __pocs =
typename _Tp::propagate_on_container_swap;
69 template<
typename _Tp>
70 using __equal =
typename _Tp::is_always_equal;
73 template<
typename _Alloc,
typename _Up>
74 using __alloc_rebind = __detected_or_t_<__replace_first_arg_t,
75 __allocator_traits_base::__rebind,
82 template<
typename _Alloc>
95 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
104 = __detected_or_t<__ptr_rebind<pointer, const value_type>,
105 __c_pointer, _Alloc>;
114 = __detected_or_t<__ptr_rebind<pointer, void>, __v_pointer, _Alloc>;
123 = __detected_or_t<__ptr_rebind<pointer, const void>, __cv_pointer,
133 = __detected_or_t<typename pointer_traits<pointer>::difference_type,
134 __diff_type, _Alloc>;
143 = __detected_or_t<typename make_unsigned<difference_type>::type,
144 __size_type, _Alloc>;
153 = __detected_or_t<false_type, __pocca, _Alloc>;
162 = __detected_or_t<false_type, __pocma, _Alloc>;
171 = __detected_or_t<false_type, __pocs, _Alloc>;
180 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
182 template<
typename _Tp>
183 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
184 template<
typename _Tp>
187 static_assert(!is_same<rebind_alloc<value_type>, __undefined>::value,
188 "allocator defines rebind or is like Alloc<T, Args>");
191 template<
typename _Alloc2>
194 -> decltype(__a.allocate(__n, __hint))
195 {
return __a.allocate(__n, __hint); }
197 template<
typename _Alloc2>
200 {
return __a.allocate(__n); }
202 template<
typename _Tp,
typename... _Args>
203 struct __construct_helper
205 template<
typename _Alloc2,
206 typename = decltype(std::declval<_Alloc2*>()->construct(
207 std::declval<_Tp*>(), std::declval<_Args>()...))>
213 using type = decltype(__test<_Alloc>(0));
216 template<
typename _Tp,
typename... _Args>
217 using __has_construct
218 =
typename __construct_helper<_Tp, _Args...>::type;
220 template<
typename _Tp,
typename... _Args>
221 static _Require<__has_construct<_Tp, _Args...>>
222 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
223 { __a.construct(__p, std::forward<_Args>(__args)...); }
225 template<
typename _Tp,
typename... _Args>
227 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
228 is_constructible<_Tp, _Args...>>>
229 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
230 { ::new((
void*)__p) _Tp(
std::
forward<_Args>(__args)...); }
232 template<typename _Alloc2, typename _Tp>
234 _S_destroy(_Alloc2& __a, _Tp* __p,
int)
235 -> decltype(__a.destroy(__p))
236 { __a.destroy(__p); }
238 template<
typename _Alloc2,
typename _Tp>
240 _S_destroy(_Alloc2&, _Tp* __p, ...)
243 template<
typename _Alloc2>
245 _S_max_size(_Alloc2& __a,
int)
246 -> decltype(__a.max_size())
247 {
return __a.max_size(); }
249 template<
typename _Alloc2>
251 _S_max_size(_Alloc2&, ...)
255 return __gnu_cxx::__numeric_traits<size_type>::__max
256 /
sizeof(value_type);
259 template<
typename _Alloc2>
261 _S_select(_Alloc2& __a,
int)
262 -> decltype(__a.select_on_container_copy_construction())
263 {
return __a.select_on_container_copy_construction(); }
265 template<
typename _Alloc2>
267 _S_select(_Alloc2& __a, ...)
281 {
return __a.allocate(__n); }
296 {
return _S_allocate(__a, __n, __hint, 0); }
308 { __a.deallocate(__p, __n); }
321 template<
typename _Tp,
typename... _Args>
322 static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
323 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
324 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
334 template<
typename _Tp>
336 { _S_destroy(__a, __p, 0); }
347 {
return _S_max_size(__a, 0); }
359 {
return _S_select(__rhs, 0); }
363 template<
typename _Tp>
369 using value_type = _Tp;
401 template<
typename _Up>
404 template<
typename _Up>
416 {
return __a.allocate(__n); }
430 {
return __a.allocate(__n, __hint); }
442 { __a.deallocate(__p, __n); }
452 template<
typename _Up,
typename... _Args>
454 construct(allocator_type& __a, _Up* __p, _Args&&... __args)
455 { __a.construct(__p, std::forward<_Args>(__args)...); }
464 template<
typename _Up>
467 { __a.destroy(__p); }
476 {
return __a.max_size(); }
483 static allocator_type
489 template<
typename _Alloc>
491 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
494 template<
typename _Alloc>
496 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
499 template<
typename _Alloc>
500 inline void __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
503 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
504 __do_alloc_on_copy(__one, __two, __pocca());
507 template<
typename _Alloc>
508 inline _Alloc __alloc_on_copy(
const _Alloc& __a)
511 return __traits::select_on_container_copy_construction(__a);
514 template<
typename _Alloc>
515 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
516 { __one = std::move(__two); }
518 template<
typename _Alloc>
519 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
522 template<
typename _Alloc>
523 inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
526 typedef typename __traits::propagate_on_container_move_assignment __pocma;
527 __do_alloc_on_move(__one, __two, __pocma());
530 template<
typename _Alloc>
531 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
537 template<
typename _Alloc>
538 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
541 template<
typename _Alloc>
542 inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
545 typedef typename __traits::propagate_on_container_swap __pocs;
546 __do_alloc_on_swap(__one, __two, __pocs());
549 template<
typename _Alloc>
550 class __is_copy_insertable_impl
554 template<
typename _Up,
typename 555 = decltype(_Traits::construct(std::declval<_Alloc&>(),
556 std::declval<_Up*>(),
557 std::declval<const _Up&>()))>
561 template<
typename _Up>
566 typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
570 template<
typename _Alloc>
571 struct __is_copy_insertable
572 : __is_copy_insertable_impl<_Alloc>::type
576 template<
typename _Tp>
577 struct __is_copy_insertable<allocator<_Tp>>
578 : is_copy_constructible<_Tp>
581 _GLIBCXX_END_NAMESPACE_VERSION
void * void_pointer
The allocator's void pointer type.
static void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
The standard allocator, as per [20.4].
__detected_or_t< __ptr_rebind< pointer, const void >, __cv_pointer, _Tp_alloc_type > const_void_pointer
The allocator's const void pointer type.
__detected_or_t< __ptr_rebind< pointer, const value_type >, __c_pointer, _Tp_alloc_type > const_pointer
The allocator's const pointer type.
static _Alloc select_on_container_copy_construction(const _Alloc &__rhs)
Obtain an allocator to use when copying a container.
const _Tp * const_pointer
The allocator's const pointer type.
__detected_or_t< value_type *, __pointer, _Tp_alloc_type > pointer
The allocator's pointer type.
__detected_or_t< false_type, __pocs, _Tp_alloc_type > propagate_on_container_swap
How the allocator is propagated on swap.
__detected_or_t< typename make_unsigned< difference_type >::type, __size_type, _Tp_alloc_type > size_type
The allocator's size type.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
static void deallocate(allocator_type &__a, pointer __p, size_type __n)
Deallocate memory.
static size_type max_size(const allocator_type &__a) noexcept
The maximum supported allocation size.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
__detected_or_t< false_type, __pocma, _Tp_alloc_type > propagate_on_container_move_assignment
How the allocator is propagated on move assignment.
static allocator_type select_on_container_copy_construction(const allocator_type &__rhs)
Obtain an allocator to use when copying a container.
static pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
__detected_or_t< false_type, __pocca, _Tp_alloc_type > propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
__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.
_Alloc allocator_type
The allocator type.
__detected_or_t< __ptr_rebind< pointer, void >, __v_pointer, _Tp_alloc_type > void_pointer
The allocator's void pointer type.
static pointer allocate(allocator_type &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
static void destroy(allocator_type &__a, _Up *__p)
Destroy an object of type _Up.
static size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
const void * const_void_pointer
The allocator's const void pointer type.
__detected_or_t< typename pointer_traits< pointer >::difference_type, __diff_type, _Tp_alloc_type > difference_type
The allocator's difference type.
Uniform interface to all allocator types.
static auto construct(_Alloc &__a, _Tp *__p, _Args &&...__args) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp.
static pointer allocate(_Alloc &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
static void destroy(_Alloc &__a, _Tp *__p)
Destroy an object of type _Tp.
_Alloc::value_type value_type
The allocated type.
static pointer allocate(allocator_type &__a, size_type __n)
Allocate memory.
static void construct(allocator_type &__a, _Up *__p, _Args &&...__args)
Construct an object of type _Up.
std::size_t size_type
The allocator's size type.
ISO C++ entities toplevel namespace is std.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
_Tp * pointer
The allocator's pointer type.
std::ptrdiff_t difference_type
The allocator's difference type.