30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
33 #if __cplusplus >= 201103L
39 namespace std _GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 template<
typename _Alloc,
typename _Tp>
44 class __alloctr_rebind_helper
46 template<
typename _Alloc2,
typename _Tp2>
47 static constexpr true_type
48 _S_chk(
typename _Alloc2::template rebind<_Tp2>::other*);
50 template<
typename,
typename>
51 static constexpr false_type
55 using __type = decltype(_S_chk<_Alloc, _Tp>(
nullptr));
58 template<
typename _Alloc,
typename _Tp,
59 bool = __alloctr_rebind_helper<_Alloc, _Tp>::__type::value>
60 struct __alloctr_rebind;
62 template<
typename _Alloc,
typename _Tp>
63 struct __alloctr_rebind<_Alloc, _Tp, true>
65 typedef typename _Alloc::template rebind<_Tp>::other __type;
68 template<
template<
typename,
typename...>
class _Alloc,
typename _Tp,
69 typename _Up,
typename... _Args>
70 struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
72 typedef _Alloc<_Tp, _Args...> __type;
79 template<
typename _Alloc>
87 #define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \
89 template<typename _Tp> \
90 static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \
91 static _ALT _S_##_NTYPE##_helper(...); \
92 typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \
95 _GLIBCXX_ALLOC_TR_NESTED_TYPE(
pointer, value_type*)
105 typename
pointer_traits<pointer>::template rebind<const value_type>)
113 typedef __const_pointer const_pointer;
124 typedef __void_pointer void_pointer;
135 typedef __const_void_pointer const_void_pointer;
146 typedef __difference_type difference_type;
149 typename make_unsigned<difference_type>::type)
157 typedef __size_type size_type;
168 typedef __propagate_on_container_copy_assignment
169 propagate_on_container_copy_assignment;
180 typedef __propagate_on_container_move_assignment
181 propagate_on_container_move_assignment;
192 typedef __propagate_on_container_swap propagate_on_container_swap;
194 #undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
196 template<
typename _Tp>
197 using rebind_alloc =
typename __alloctr_rebind<_Alloc, _Tp>::__type;
198 template<
typename _Tp>
202 template<
typename _Alloc2>
203 struct __allocate_helper
205 template<
typename _Alloc3,
206 typename = decltype(std::declval<_Alloc3*>()->
allocate(
207 std::declval<size_type>(),
208 std::declval<const_void_pointer>()))>
209 static true_type __test(
int);
212 static false_type __test(...);
214 using type = decltype(__test<_Alloc>(0));
217 template<
typename _Alloc2>
218 using __has_allocate =
typename __allocate_helper<_Alloc2>::type;
220 template<
typename _Alloc2,
221 typename = _Require<__has_allocate<_Alloc2>>>
223 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
224 {
return __a.allocate(__n, __hint); }
226 template<
typename _Alloc2,
typename _UnusedHint,
227 typename = _Require<__not_<__has_allocate<_Alloc2>>>>
229 _S_allocate(_Alloc2& __a, size_type __n, _UnusedHint)
230 {
return __a.allocate(__n); }
232 template<
typename _Tp,
typename... _Args>
233 struct __construct_helper
235 template<
typename _Alloc2,
236 typename = decltype(std::declval<_Alloc2*>()->
construct(
237 std::declval<_Tp*>(), std::declval<_Args>()...))>
238 static true_type __test(
int);
241 static false_type __test(...);
243 using type = decltype(__test<_Alloc>(0));
246 template<
typename _Tp,
typename... _Args>
247 using __has_construct
248 =
typename __construct_helper<_Tp, _Args...>::type;
250 template<
typename _Tp,
typename... _Args>
251 static _Require<__has_construct<_Tp, _Args...>>
252 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
253 { __a.construct(__p, std::forward<_Args>(__args)...); }
255 template<
typename _Tp,
typename... _Args>
257 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
258 is_constructible<_Tp, _Args...>>>
259 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
260 { ::new((
void*)__p) _Tp(
std::
forward<_Args>(__args)...); }
262 template<typename _Tp>
263 struct __destroy_helper
265 template<
typename _Alloc2,
266 typename = decltype(std::declval<_Alloc2*>()->
destroy(
267 std::declval<_Tp*>()))>
268 static true_type __test(
int);
271 static false_type __test(...);
273 using type = decltype(__test<_Alloc>(0));
276 template<
typename _Tp>
277 using __has_destroy =
typename __destroy_helper<_Tp>::type;
279 template<
typename _Tp>
280 static _Require<__has_destroy<_Tp>>
281 _S_destroy(_Alloc& __a, _Tp* __p)
282 { __a.destroy(__p); }
284 template<
typename _Tp>
285 static _Require<__not_<__has_destroy<_Tp>>>
286 _S_destroy(_Alloc&, _Tp* __p)
289 template<
typename _Alloc2>
290 struct __maxsize_helper
292 template<
typename _Alloc3,
293 typename = decltype(std::declval<_Alloc3*>()->
max_size())>
294 static true_type __test(
int);
297 static false_type __test(...);
299 using type = decltype(__test<_Alloc2>(0));
302 template<
typename _Alloc2>
303 using __has_max_size =
typename __maxsize_helper<_Alloc2>::type;
305 template<
typename _Alloc2,
306 typename = _Require<__has_max_size<_Alloc2>>>
308 _S_max_size(_Alloc2& __a,
int)
309 {
return __a.max_size(); }
311 template<
typename _Alloc2,
312 typename = _Require<__not_<__has_max_size<_Alloc2>>>>
314 _S_max_size(_Alloc2&, ...)
315 {
return __gnu_cxx::__numeric_traits<size_type>::__max; }
317 template<
typename _Alloc2>
318 struct __select_helper
320 template<
typename _Alloc3,
typename
321 = decltype(std::declval<_Alloc3*>()
323 static true_type __test(
int);
326 static false_type __test(...);
328 using type = decltype(__test<_Alloc2>(0));
331 template<
typename _Alloc2>
332 using __has_soccc =
typename __select_helper<_Alloc2>::type;
334 template<
typename _Alloc2,
335 typename = _Require<__has_soccc<_Alloc2>>>
337 _S_select(_Alloc2& __a,
int)
338 {
return __a.select_on_container_copy_construction(); }
340 template<
typename _Alloc2,
341 typename = _Require<__not_<__has_soccc<_Alloc2>>>>
343 _S_select(_Alloc2& __a, ...)
357 {
return __a.allocate(__n); }
371 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
372 {
return _S_allocate(__a, __n, __hint); }
382 static void deallocate(_Alloc& __a, pointer __p, size_type __n)
383 { __a.deallocate(__p, __n); }
396 template<
typename _Tp,
typename... _Args>
397 static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
398 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
399 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
411 { _S_destroy(__a, __p); }
421 static size_type
max_size(
const _Alloc& __a) noexcept
422 {
return _S_max_size(__a, 0); }
434 {
return _S_select(__rhs, 0); }
437 template<
typename _Alloc>
439 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two, true_type)
442 template<
typename _Alloc>
444 __do_alloc_on_copy(_Alloc&,
const _Alloc&, false_type)
447 template<
typename _Alloc>
448 inline void __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
450 typedef allocator_traits<_Alloc> __traits;
451 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
452 __do_alloc_on_copy(__one, __two, __pocca());
455 template<
typename _Alloc>
456 inline _Alloc __alloc_on_copy(
const _Alloc& __a)
458 typedef allocator_traits<_Alloc> __traits;
459 return __traits::select_on_container_copy_construction(__a);
462 template<
typename _Alloc>
463 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
466 template<
typename _Alloc>
467 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
470 template<
typename _Alloc>
471 inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
473 typedef allocator_traits<_Alloc> __traits;
474 typedef typename __traits::propagate_on_container_move_assignment __pocma;
475 __do_alloc_on_move(__one, __two, __pocma());
478 template<
typename _Alloc>
479 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
485 template<
typename _Alloc>
486 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
489 template<
typename _Alloc>
490 inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
492 typedef allocator_traits<_Alloc> __traits;
493 typedef typename __traits::propagate_on_container_swap __pocs;
494 __do_alloc_on_swap(__one, __two, __pocs());
497 template<
typename _Alloc>
498 class __is_copy_insertable_impl
500 typedef allocator_traits<_Alloc> _Traits;
502 template<
typename _Up,
typename
503 = decltype(_Traits::construct(std::declval<_Alloc&>(),
504 std::declval<_Up*>(),
505 std::declval<const _Up&>()))>
509 template<
typename _Up>
514 typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
518 template<typename _Alloc>
519 struct __is_copy_insertable
520 : __is_copy_insertable_impl<_Alloc>::type
524 template<
typename _Tp>
525 struct __is_copy_insertable<allocator<_Tp>>
526 : is_copy_constructible<_Tp>
529 _GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
__void_pointer void_pointer
The allocator's void pointer type.
static auto construct(_Alloc &__a, _Tp *__p, _Args &&...__args) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
static void destroy(_Alloc &__a, _Tp *__p)
Destroy an object of type _Tp.
Uniform interface to all pointer-like types.
__difference_type difference_type
The allocator's difference type.
Uniform interface to all allocator types.
__const_pointer const_pointer
The allocator's const pointer type.
ISO C++ entities toplevel namespace is std.
__propagate_on_container_copy_assignment propagate_on_container_copy_assignment
How the allocator is propagated on copy assignment.
static _Alloc select_on_container_copy_construction(const _Alloc &__rhs)
Obtain an allocator to use when copying a container.
_Alloc::value_type value_type
The allocated type.
static pointer allocate(_Alloc &__a, size_type __n, const_void_pointer __hint)
Allocate memory.
__size_type size_type
The allocator's size type.
__pointer pointer
The allocator's pointer type.
__const_void_pointer const_void_pointer
The allocator's const void pointer type.
static void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
__propagate_on_container_swap propagate_on_container_swap
How the allocator is propagated on swap.
void swap(_Tp &, _Tp &) noexcept(__and_< is_nothrow_move_constructible< _Tp >, is_nothrow_move_assignable< _Tp >>::value)
Swaps two values.
static size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
_Alloc allocator_type
The allocator type.
static pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
__propagate_on_container_move_assignment propagate_on_container_move_assignment
How the allocator is propagated on move assignment.