30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
33 #if __cplusplus >= 201103L
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 template<
typename _Alloc,
typename _Tp>
44 class __alloctr_rebind_helper
46 template<
typename _Alloc2,
typename _Tp2>
48 _S_chk(
typename _Alloc2::template rebind<_Tp2>::other*)
51 template<
typename,
typename>
57 static const bool __value = _S_chk<_Alloc, _Tp>(
nullptr);
60 template<
typename _Alloc,
typename _Tp>
61 const bool __alloctr_rebind_helper<_Alloc, _Tp>::__value;
63 template<
typename _Alloc,
typename _Tp,
64 bool = __alloctr_rebind_helper<_Alloc, _Tp>::__value>
65 struct __alloctr_rebind;
67 template<
typename _Alloc,
typename _Tp>
68 struct __alloctr_rebind<_Alloc, _Tp,
true>
70 typedef typename _Alloc::template rebind<_Tp>::other __type;
73 template<
template<
typename,
typename...>
class _Alloc,
typename _Tp,
74 typename _Up,
typename... _Args>
75 struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp,
false>
77 typedef _Alloc<_Tp, _Args...> __type;
84 template<
typename _Alloc>
85 struct allocator_traits
88 typedef _Alloc allocator_type;
90 typedef typename _Alloc::value_type value_type;
92 #define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \
94 template<typename _Tp> \
95 static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \
96 static _ALT _S_##_NTYPE##_helper(...); \
97 typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \
100 _GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*)
107 typedef __pointer pointer;
109 _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer,
110 typename pointer_traits<pointer>::template rebind<const value_type>)
118 typedef __const_pointer const_pointer;
120 _GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer,
121 typename pointer_traits<pointer>::template rebind<
void>)
129 typedef __void_pointer void_pointer;
131 _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer,
132 typename pointer_traits<pointer>::template rebind<const
void>)
140 typedef __const_void_pointer const_void_pointer;
142 _GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
143 typename pointer_traits<pointer>::difference_type)
151 typedef __difference_type difference_type;
153 _GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
154 typename make_unsigned<difference_type>::type)
162 typedef __size_type size_type;
164 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
173 typedef __propagate_on_container_copy_assignment
174 propagate_on_container_copy_assignment;
176 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
185 typedef __propagate_on_container_move_assignment
186 propagate_on_container_move_assignment;
188 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
197 typedef __propagate_on_container_swap propagate_on_container_swap;
199 #undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
201 template<
typename _Tp>
202 using rebind_alloc =
typename __alloctr_rebind<_Alloc, _Tp>::__type;
203 template<
typename _Tp>
204 using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
207 template<
typename _Alloc2>
208 struct __allocate_helper
210 template<
typename _Alloc3,
211 typename = decltype(std::declval<_Alloc3*>()->allocate(
212 std::declval<size_type>(),
213 std::declval<const_void_pointer>()))>
219 typedef decltype(__test<_Alloc>(0)) type;
220 static const
bool value = type::value;
223 template<typename _Alloc2>
225 enable_if<__allocate_helper<_Alloc2>::value, pointer>::type
226 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
227 {
return __a.allocate(__n, __hint); }
229 template<
typename _Alloc2>
231 enable_if<!__allocate_helper<_Alloc2>::value, pointer>::type
232 _S_allocate(_Alloc2& __a, size_type __n, ...)
233 {
return __a.allocate(__n); }
235 template<
typename _Tp,
typename... _Args>
236 struct __construct_helper
238 template<
typename _Alloc2,
239 typename = decltype(std::declval<_Alloc2*>()->construct(
240 std::declval<_Tp*>(), std::declval<_Args>()...))>
246 typedef decltype(__test<_Alloc>(0)) type;
247 static const
bool value = type::value;
250 template<typename _Tp, typename... _Args>
252 enable_if<__construct_helper<_Tp, _Args...>::value,
void>::type
253 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
254 { __a.construct(__p, std::forward<_Args>(__args)...); }
256 template<
typename _Tp,
typename... _Args>
258 enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>,
259 is_constructible<_Tp, _Args...>>::value,
void>::type
260 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
261 { ::new((
void*)__p) _Tp(std::forward<_Args>(__args)...); }
263 template<typename _Tp>
264 struct __destroy_helper
266 template<
typename _Alloc2,
267 typename = decltype(std::declval<_Alloc2*>()->destroy(
268 std::declval<_Tp*>()))>
274 typedef decltype(__test<_Alloc>(0)) type;
275 static const
bool value = type::value;
278 template<typename _Tp>
279 static typename enable_if<__destroy_helper<_Tp>::value,
void>::type
280 _S_destroy(_Alloc& __a, _Tp* __p)
281 { __a.destroy(__p); }
283 template<
typename _Tp>
284 static typename enable_if<!__destroy_helper<_Tp>::value,
void>::type
285 _S_destroy(_Alloc&, _Tp* __p)
288 template<
typename _Alloc2>
289 struct __maxsize_helper
291 template<
typename _Alloc3,
292 typename = decltype(std::declval<_Alloc3*>()->max_size())>
298 typedef decltype(__test<_Alloc2>(0)) type;
299 static const
bool value = type::value;
302 template<typename _Alloc2>
304 enable_if<__maxsize_helper<_Alloc2>::value, size_type>::type
305 _S_max_size(_Alloc2& __a)
306 {
return __a.max_size(); }
308 template<
typename _Alloc2>
310 enable_if<!__maxsize_helper<_Alloc2>::value, size_type>::type
311 _S_max_size(_Alloc2&)
312 {
return __gnu_cxx::__numeric_traits<size_type>::__max; }
314 template<
typename _Alloc2>
315 struct __select_helper
317 template<
typename _Alloc3,
typename
318 = decltype(std::declval<_Alloc3*>()
319 ->select_on_container_copy_construction())>
325 typedef decltype(__test<_Alloc2>(0)) type;
326 static const
bool value = type::value;
328 template<typename _Alloc2>
330 enable_if<__select_helper<_Alloc2>::value, _Alloc2>::type
331 _S_select(_Alloc2& __a)
332 {
return __a.select_on_container_copy_construction(); }
334 template<
typename _Alloc2>
336 enable_if<!__select_helper<_Alloc2>::value, _Alloc2>::type
337 _S_select(_Alloc2& __a)
350 allocate(_Alloc& __a, size_type __n)
351 {
return __a.allocate(__n); }
365 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
366 {
return _S_allocate(__a, __n, __hint); }
376 static void deallocate(_Alloc& __a, pointer __p, size_type __n)
377 { __a.deallocate(__p, __n); }
390 template<
typename _Tp,
typename... _Args>
391 static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
392 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
393 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
404 static void destroy(_Alloc& __a, _Tp* __p)
405 { _S_destroy(__a, __p); }
415 static size_type max_size(
const _Alloc& __a)
416 {
return _S_max_size(__a); }
427 select_on_container_copy_construction(
const _Alloc& __rhs)
428 {
return _S_select(__rhs); }
431 template<
typename _Alloc>
432 template<
typename _Alloc2>
433 const bool allocator_traits<_Alloc>::__allocate_helper<_Alloc2>::value;
435 template<
typename _Alloc>
436 template<
typename _Tp,
typename... _Args>
438 allocator_traits<_Alloc>::__construct_helper<_Tp, _Args...>::value;
440 template<
typename _Alloc>
441 template<
typename _Tp>
442 const bool allocator_traits<_Alloc>::__destroy_helper<_Tp>::value;
444 template<
typename _Alloc>
445 template<
typename _Alloc2>
446 const bool allocator_traits<_Alloc>::__maxsize_helper<_Alloc2>::value;
448 template<
typename _Alloc>
449 template<
typename _Alloc2>
450 const bool allocator_traits<_Alloc>::__select_helper<_Alloc2>::value;
452 template<
typename _Alloc>
454 __do_alloc_on_copy(_Alloc& __one,
const _Alloc& __two,
true_type)
457 template<
typename _Alloc>
459 __do_alloc_on_copy(_Alloc&,
const _Alloc&,
false_type)
462 template<
typename _Alloc>
463 inline void __alloc_on_copy(_Alloc& __one,
const _Alloc& __two)
465 typedef allocator_traits<_Alloc> __traits;
466 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
467 __do_alloc_on_copy(__one, __two, __pocca());
470 template<
typename _Alloc>
471 inline _Alloc __alloc_on_copy(
const _Alloc& __a)
473 typedef allocator_traits<_Alloc> __traits;
474 return __traits::select_on_container_copy_construction(__a);
477 template<
typename _Alloc>
478 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two,
true_type)
479 { __one = std::move(__two); }
481 template<
typename _Alloc>
482 inline void __do_alloc_on_move(_Alloc&, _Alloc&,
false_type)
485 template<
typename _Alloc>
486 inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
488 typedef allocator_traits<_Alloc> __traits;
489 typedef typename __traits::propagate_on_container_move_assignment __pocma;
490 __do_alloc_on_move(__one, __two, __pocma());
493 template<
typename _Alloc>
494 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two,
true_type)
500 template<
typename _Alloc>
501 inline void __do_alloc_on_swap(_Alloc&, _Alloc&,
false_type)
504 template<
typename _Alloc>
505 inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
507 typedef allocator_traits<_Alloc> __traits;
508 typedef typename __traits::propagate_on_container_swap __pocs;
509 __do_alloc_on_swap(__one, __two, __pocs());
512 template<
typename _Alloc>
513 class __is_copy_insertable_impl
515 typedef allocator_traits<_Alloc> _Traits;
517 template<
typename _Up,
typename
518 = decltype(_Traits::construct(std::declval<_Alloc&>(),
519 std::declval<_Up*>(),
520 std::declval<const _Up&>()))>
524 template<
typename _Up>
529 typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
533 template<typename _Alloc>
534 struct __is_copy_insertable
535 : __is_copy_insertable_impl<_Alloc>::type
539 template<
typename _Tp>
540 struct __is_copy_insertable<allocator<_Tp>>
541 : is_copy_constructible<_Tp>
545 template<
bool>
struct __allow_copy_cons { };
549 struct __allow_copy_cons<
false>
551 __allow_copy_cons() =
default;
552 __allow_copy_cons(
const __allow_copy_cons&) =
delete;
553 __allow_copy_cons(__allow_copy_cons&&) =
default;
554 __allow_copy_cons& operator=(
const __allow_copy_cons&) =
default;
555 __allow_copy_cons& operator=(__allow_copy_cons&&) =
default;
558 template<
typename _Alloc>
559 using __check_copy_constructible
560 = __allow_copy_cons<__is_copy_insertable<_Alloc>::value>;
562 _GLIBCXX_END_NAMESPACE_VERSION
#define false
Definition: stdbool.h:35
#define true
Definition: stdbool.h:34
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
Definition: alloc_traits.h:41
std::tr1::integral_constant< int, 1 > true_type
Definition: type_utils.hpp:70
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160
std::tr1::integral_constant< int, 0 > false_type
Definition: type_utils.hpp:71