]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/alloc_traits.h
libstdc++: Add inline to maybe-constexpr functions (PR 92927)
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / alloc_traits.h
1 // Allocator traits -*- C++ -*-
2
3 // Copyright (C) 2011-2019 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file bits/alloc_traits.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
32
33 #include <bits/stl_construct.h>
34 #include <bits/memoryfwd.h>
35 #if __cplusplus >= 201103L
36 # include <bits/allocator.h>
37 # include <bits/ptr_traits.h>
38 # include <ext/numeric_traits.h>
39 #endif
40
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 #if __cplusplus >= 201103L
46 #define __cpp_lib_allocator_traits_is_always_equal 201411
47
48 struct __allocator_traits_base
49 {
50 template<typename _Tp, typename _Up, typename = void>
51 struct __rebind : __replace_first_arg<_Tp, _Up> { };
52
53 template<typename _Tp, typename _Up>
54 struct __rebind<_Tp, _Up,
55 __void_t<typename _Tp::template rebind<_Up>::other>>
56 { using type = typename _Tp::template rebind<_Up>::other; };
57
58 protected:
59 template<typename _Tp>
60 using __pointer = typename _Tp::pointer;
61 template<typename _Tp>
62 using __c_pointer = typename _Tp::const_pointer;
63 template<typename _Tp>
64 using __v_pointer = typename _Tp::void_pointer;
65 template<typename _Tp>
66 using __cv_pointer = typename _Tp::const_void_pointer;
67 template<typename _Tp>
68 using __pocca = typename _Tp::propagate_on_container_copy_assignment;
69 template<typename _Tp>
70 using __pocma = typename _Tp::propagate_on_container_move_assignment;
71 template<typename _Tp>
72 using __pocs = typename _Tp::propagate_on_container_swap;
73 template<typename _Tp>
74 using __equal = typename _Tp::is_always_equal;
75 };
76
77 template<typename _Alloc, typename _Up>
78 using __alloc_rebind
79 = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
80
81 /**
82 * @brief Uniform interface to all allocator types.
83 * @ingroup allocators
84 */
85 template<typename _Alloc>
86 struct allocator_traits : __allocator_traits_base
87 {
88 /// The allocator type
89 typedef _Alloc allocator_type;
90 /// The allocated type
91 typedef typename _Alloc::value_type value_type;
92
93 /**
94 * @brief The allocator's pointer type.
95 *
96 * @c Alloc::pointer if that type exists, otherwise @c value_type*
97 */
98 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
99
100 private:
101 // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
102 template<template<typename> class _Func, typename _Tp, typename = void>
103 struct _Ptr
104 {
105 using type = typename pointer_traits<pointer>::template rebind<_Tp>;
106 };
107
108 template<template<typename> class _Func, typename _Tp>
109 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
110 {
111 using type = _Func<_Alloc>;
112 };
113
114 // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
115 template<typename _A2, typename _PtrT, typename = void>
116 struct _Diff
117 { using type = typename pointer_traits<_PtrT>::difference_type; };
118
119 template<typename _A2, typename _PtrT>
120 struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
121 { using type = typename _A2::difference_type; };
122
123 // Select _A2::size_type or make_unsigned<_DiffT>::type
124 template<typename _A2, typename _DiffT, typename = void>
125 struct _Size : make_unsigned<_DiffT> { };
126
127 template<typename _A2, typename _DiffT>
128 struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
129 { using type = typename _A2::size_type; };
130
131 public:
132 /**
133 * @brief The allocator's const pointer type.
134 *
135 * @c Alloc::const_pointer if that type exists, otherwise
136 * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
137 */
138 using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
139
140 /**
141 * @brief The allocator's void pointer type.
142 *
143 * @c Alloc::void_pointer if that type exists, otherwise
144 * <tt> pointer_traits<pointer>::rebind<void> </tt>
145 */
146 using void_pointer = typename _Ptr<__v_pointer, void>::type;
147
148 /**
149 * @brief The allocator's const void pointer type.
150 *
151 * @c Alloc::const_void_pointer if that type exists, otherwise
152 * <tt> pointer_traits<pointer>::rebind<const void> </tt>
153 */
154 using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
155
156 /**
157 * @brief The allocator's difference type
158 *
159 * @c Alloc::difference_type if that type exists, otherwise
160 * <tt> pointer_traits<pointer>::difference_type </tt>
161 */
162 using difference_type = typename _Diff<_Alloc, pointer>::type;
163
164 /**
165 * @brief The allocator's size type
166 *
167 * @c Alloc::size_type if that type exists, otherwise
168 * <tt> make_unsigned<difference_type>::type </tt>
169 */
170 using size_type = typename _Size<_Alloc, difference_type>::type;
171
172 /**
173 * @brief How the allocator is propagated on copy assignment
174 *
175 * @c Alloc::propagate_on_container_copy_assignment if that type exists,
176 * otherwise @c false_type
177 */
178 using propagate_on_container_copy_assignment
179 = __detected_or_t<false_type, __pocca, _Alloc>;
180
181 /**
182 * @brief How the allocator is propagated on move assignment
183 *
184 * @c Alloc::propagate_on_container_move_assignment if that type exists,
185 * otherwise @c false_type
186 */
187 using propagate_on_container_move_assignment
188 = __detected_or_t<false_type, __pocma, _Alloc>;
189
190 /**
191 * @brief How the allocator is propagated on swap
192 *
193 * @c Alloc::propagate_on_container_swap if that type exists,
194 * otherwise @c false_type
195 */
196 using propagate_on_container_swap
197 = __detected_or_t<false_type, __pocs, _Alloc>;
198
199 /**
200 * @brief Whether all instances of the allocator type compare equal.
201 *
202 * @c Alloc::is_always_equal if that type exists,
203 * otherwise @c is_empty<Alloc>::type
204 */
205 using is_always_equal
206 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
207
208 template<typename _Tp>
209 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
210 template<typename _Tp>
211 using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
212
213 private:
214 template<typename _Alloc2>
215 static constexpr auto
216 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
217 -> decltype(__a.allocate(__n, __hint))
218 { return __a.allocate(__n, __hint); }
219
220 template<typename _Alloc2>
221 static constexpr pointer
222 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
223 { return __a.allocate(__n); }
224
225 template<typename _Tp, typename... _Args>
226 struct __construct_helper
227 {
228 template<typename _Alloc2,
229 typename = decltype(std::declval<_Alloc2*>()->construct(
230 std::declval<_Tp*>(), std::declval<_Args>()...))>
231 static true_type __test(int);
232
233 template<typename>
234 static false_type __test(...);
235
236 using type = decltype(__test<_Alloc>(0));
237 };
238
239 template<typename _Tp, typename... _Args>
240 using __has_construct
241 = typename __construct_helper<_Tp, _Args...>::type;
242
243 template<typename _Tp, typename... _Args>
244 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
245 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
246 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
247 { __a.construct(__p, std::forward<_Args>(__args)...); }
248
249 template<typename _Tp, typename... _Args>
250 static _GLIBCXX14_CONSTEXPR
251 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
252 is_constructible<_Tp, _Args...>>>
253 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
254 noexcept(noexcept(::new((void*)__p)
255 _Tp(std::forward<_Args>(__args)...)))
256 { std::_Construct(__p, std::forward<_Args>(__args)...); }
257
258 template<typename _Alloc2, typename _Tp>
259 static _GLIBCXX14_CONSTEXPR auto
260 _S_destroy(_Alloc2& __a, _Tp* __p, int)
261 noexcept(noexcept(__a.destroy(__p)))
262 -> decltype(__a.destroy(__p))
263 { __a.destroy(__p); }
264
265 template<typename _Alloc2, typename _Tp>
266 static _GLIBCXX14_CONSTEXPR void
267 _S_destroy(_Alloc2&, _Tp* __p, ...)
268 noexcept(noexcept(__p->~_Tp()))
269 { std::_Destroy(__p); }
270
271 template<typename _Alloc2>
272 static constexpr auto
273 _S_max_size(_Alloc2& __a, int)
274 -> decltype(__a.max_size())
275 { return __a.max_size(); }
276
277 template<typename _Alloc2>
278 static constexpr size_type
279 _S_max_size(_Alloc2&, ...)
280 {
281 // _GLIBCXX_RESOLVE_LIB_DEFECTS
282 // 2466. allocator_traits::max_size() default behavior is incorrect
283 return __gnu_cxx::__numeric_traits<size_type>::__max
284 / sizeof(value_type);
285 }
286
287 template<typename _Alloc2>
288 static constexpr auto
289 _S_select(_Alloc2& __a, int)
290 -> decltype(__a.select_on_container_copy_construction())
291 { return __a.select_on_container_copy_construction(); }
292
293 template<typename _Alloc2>
294 static constexpr _Alloc2
295 _S_select(_Alloc2& __a, ...)
296 { return __a; }
297
298 public:
299
300 /**
301 * @brief Allocate memory.
302 * @param __a An allocator.
303 * @param __n The number of objects to allocate space for.
304 *
305 * Calls @c a.allocate(n)
306 */
307 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
308 allocate(_Alloc& __a, size_type __n)
309 { return __a.allocate(__n); }
310
311 /**
312 * @brief Allocate memory.
313 * @param __a An allocator.
314 * @param __n The number of objects to allocate space for.
315 * @param __hint Aid to locality.
316 * @return Memory of suitable size and alignment for @a n objects
317 * of type @c value_type
318 *
319 * Returns <tt> a.allocate(n, hint) </tt> if that expression is
320 * well-formed, otherwise returns @c a.allocate(n)
321 */
322 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
323 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
324 { return _S_allocate(__a, __n, __hint, 0); }
325
326 /**
327 * @brief Deallocate memory.
328 * @param __a An allocator.
329 * @param __p Pointer to the memory to deallocate.
330 * @param __n The number of objects space was allocated for.
331 *
332 * Calls <tt> a.deallocate(p, n) </tt>
333 */
334 static _GLIBCXX20_CONSTEXPR void
335 deallocate(_Alloc& __a, pointer __p, size_type __n)
336 { __a.deallocate(__p, __n); }
337
338 /**
339 * @brief Construct an object of type @a _Tp
340 * @param __a An allocator.
341 * @param __p Pointer to memory of suitable size and alignment for Tp
342 * @param __args Constructor arguments.
343 *
344 * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
345 * if that expression is well-formed, otherwise uses placement-new
346 * to construct an object of type @a _Tp at location @a __p from the
347 * arguments @a __args...
348 */
349 template<typename _Tp, typename... _Args>
350 static _GLIBCXX20_CONSTEXPR auto
351 construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
352 noexcept(noexcept(_S_construct(__a, __p,
353 std::forward<_Args>(__args)...)))
354 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
355 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
356
357 /**
358 * @brief Destroy an object of type @a _Tp
359 * @param __a An allocator.
360 * @param __p Pointer to the object to destroy
361 *
362 * Calls @c __a.destroy(__p) if that expression is well-formed,
363 * otherwise calls @c __p->~_Tp()
364 */
365 template<typename _Tp>
366 static _GLIBCXX20_CONSTEXPR void
367 destroy(_Alloc& __a, _Tp* __p)
368 noexcept(noexcept(_S_destroy(__a, __p, 0)))
369 { _S_destroy(__a, __p, 0); }
370
371 /**
372 * @brief The maximum supported allocation size
373 * @param __a An allocator.
374 * @return @c __a.max_size() or @c numeric_limits<size_type>::max()
375 *
376 * Returns @c __a.max_size() if that expression is well-formed,
377 * otherwise returns @c numeric_limits<size_type>::max()
378 */
379 static _GLIBCXX20_CONSTEXPR size_type
380 max_size(const _Alloc& __a) noexcept
381 { return _S_max_size(__a, 0); }
382
383 /**
384 * @brief Obtain an allocator to use when copying a container.
385 * @param __rhs An allocator.
386 * @return @c __rhs.select_on_container_copy_construction() or @a __rhs
387 *
388 * Returns @c __rhs.select_on_container_copy_construction() if that
389 * expression is well-formed, otherwise returns @a __rhs
390 */
391 static _GLIBCXX20_CONSTEXPR _Alloc
392 select_on_container_copy_construction(const _Alloc& __rhs)
393 { return _S_select(__rhs, 0); }
394 };
395
396 #if __cplusplus > 201703L
397 # define __cpp_lib_constexpr_dynamic_alloc 201907L
398 #endif
399
400 /// Partial specialization for std::allocator.
401 template<typename _Tp>
402 struct allocator_traits<allocator<_Tp>>
403 {
404 /// The allocator type
405 using allocator_type = allocator<_Tp>;
406
407 /// The allocated type
408 using value_type = _Tp;
409
410 /// The allocator's pointer type.
411 using pointer = _Tp*;
412
413 /// The allocator's const pointer type.
414 using const_pointer = const _Tp*;
415
416 /// The allocator's void pointer type.
417 using void_pointer = void*;
418
419 /// The allocator's const void pointer type.
420 using const_void_pointer = const void*;
421
422 /// The allocator's difference type
423 using difference_type = std::ptrdiff_t;
424
425 /// The allocator's size type
426 using size_type = std::size_t;
427
428 /// How the allocator is propagated on copy assignment
429 using propagate_on_container_copy_assignment = false_type;
430
431 /// How the allocator is propagated on move assignment
432 using propagate_on_container_move_assignment = true_type;
433
434 /// How the allocator is propagated on swap
435 using propagate_on_container_swap = false_type;
436
437 /// Whether all instances of the allocator type compare equal.
438 using is_always_equal = true_type;
439
440 template<typename _Up>
441 using rebind_alloc = allocator<_Up>;
442
443 template<typename _Up>
444 using rebind_traits = allocator_traits<allocator<_Up>>;
445
446 /**
447 * @brief Allocate memory.
448 * @param __a An allocator.
449 * @param __n The number of objects to allocate space for.
450 *
451 * Calls @c a.allocate(n)
452 */
453 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
454 allocate(allocator_type& __a, size_type __n)
455 { return __a.allocate(__n); }
456
457 /**
458 * @brief Allocate memory.
459 * @param __a An allocator.
460 * @param __n The number of objects to allocate space for.
461 * @param __hint Aid to locality.
462 * @return Memory of suitable size and alignment for @a n objects
463 * of type @c value_type
464 *
465 * Returns <tt> a.allocate(n, hint) </tt>
466 */
467 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
468 allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
469 {
470 #if __cplusplus <= 201703L
471 return __a.allocate(__n, __hint);
472 #else
473 return __a.allocate(__n);
474 #endif
475 }
476
477 /**
478 * @brief Deallocate memory.
479 * @param __a An allocator.
480 * @param __p Pointer to the memory to deallocate.
481 * @param __n The number of objects space was allocated for.
482 *
483 * Calls <tt> a.deallocate(p, n) </tt>
484 */
485 static _GLIBCXX20_CONSTEXPR void
486 deallocate(allocator_type& __a, pointer __p, size_type __n)
487 { __a.deallocate(__p, __n); }
488
489 /**
490 * @brief Construct an object of type `_Up`
491 * @param __a An allocator.
492 * @param __p Pointer to memory of suitable size and alignment for
493 * an object of type `_Up`.
494 * @param __args Constructor arguments.
495 *
496 * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
497 * in C++11, C++14 and C++17. Changed in C++20 to call
498 * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
499 */
500 template<typename _Up, typename... _Args>
501 static _GLIBCXX20_CONSTEXPR void
502 construct(allocator_type& __a __attribute__((__unused__)), _Up* __p,
503 _Args&&... __args)
504 noexcept(noexcept(::new((void*)__p) _Up(std::declval<_Args>()...)))
505 {
506 #if __cplusplus <= 201703L
507 __a.construct(__p, std::forward<_Args>(__args)...);
508 #else
509 std::construct_at(__p, std::forward<_Args>(__args)...);
510 #endif
511 }
512
513 /**
514 * @brief Destroy an object of type @a _Up
515 * @param __a An allocator.
516 * @param __p Pointer to the object to destroy
517 *
518 * Calls @c __a.destroy(__p).
519 */
520 template<typename _Up>
521 static _GLIBCXX20_CONSTEXPR void
522 destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p)
523 noexcept(is_nothrow_destructible<_Up>::value)
524 {
525 #if __cplusplus <= 201703L
526 __a.destroy(__p);
527 #else
528 std::destroy_at(__p);
529 #endif
530 }
531
532 /**
533 * @brief The maximum supported allocation size
534 * @param __a An allocator.
535 * @return @c __a.max_size()
536 */
537 static _GLIBCXX20_CONSTEXPR size_type
538 max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
539 {
540 #if __cplusplus <= 201703L
541 return __a.max_size();
542 #else
543 return size_t(-1) / sizeof(value_type);
544 #endif
545 }
546
547 /**
548 * @brief Obtain an allocator to use when copying a container.
549 * @param __rhs An allocator.
550 * @return @c __rhs
551 */
552 static _GLIBCXX20_CONSTEXPR allocator_type
553 select_on_container_copy_construction(const allocator_type& __rhs)
554 { return __rhs; }
555 };
556
557 #if __cplusplus < 201703L
558 template<typename _Alloc>
559 inline void
560 __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
561 { __one = __two; }
562
563 template<typename _Alloc>
564 inline void
565 __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
566 { }
567 #endif
568
569 template<typename _Alloc>
570 _GLIBCXX14_CONSTEXPR inline void
571 __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
572 {
573 typedef allocator_traits<_Alloc> __traits;
574 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
575 #if __cplusplus >= 201703L
576 if constexpr (__pocca::value)
577 __one = __two;
578 #else
579 __do_alloc_on_copy(__one, __two, __pocca());
580 #endif
581 }
582
583 template<typename _Alloc>
584 constexpr _Alloc
585 __alloc_on_copy(const _Alloc& __a)
586 {
587 typedef allocator_traits<_Alloc> __traits;
588 return __traits::select_on_container_copy_construction(__a);
589 }
590
591 #if __cplusplus < 201703L
592 template<typename _Alloc>
593 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
594 { __one = std::move(__two); }
595
596 template<typename _Alloc>
597 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
598 { }
599 #endif
600
601 template<typename _Alloc>
602 _GLIBCXX14_CONSTEXPR inline void
603 __alloc_on_move(_Alloc& __one, _Alloc& __two)
604 {
605 typedef allocator_traits<_Alloc> __traits;
606 typedef typename __traits::propagate_on_container_move_assignment __pocma;
607 #if __cplusplus >= 201703L
608 if constexpr (__pocma::value)
609 __one = std::move(__two);
610 #else
611 __do_alloc_on_move(__one, __two, __pocma());
612 #endif
613 }
614
615 #if __cplusplus < 201703L
616 template<typename _Alloc>
617 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
618 {
619 using std::swap;
620 swap(__one, __two);
621 }
622
623 template<typename _Alloc>
624 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
625 { }
626 #endif
627
628 template<typename _Alloc>
629 _GLIBCXX14_CONSTEXPR inline void
630 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
631 {
632 typedef allocator_traits<_Alloc> __traits;
633 typedef typename __traits::propagate_on_container_swap __pocs;
634 #if __cplusplus >= 201703L
635 if constexpr (__pocs::value)
636 {
637 using std::swap;
638 swap(__one, __two);
639 }
640 #else
641 __do_alloc_on_swap(__one, __two, __pocs());
642 #endif
643 }
644
645 template<typename _Alloc, typename _Tp,
646 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
647 typename = void>
648 struct __is_alloc_insertable_impl
649 : false_type
650 { };
651
652 template<typename _Alloc, typename _Tp, typename _ValueT>
653 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
654 __void_t<decltype(allocator_traits<_Alloc>::construct(
655 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
656 std::declval<_Tp>()))>>
657 : true_type
658 { };
659
660 // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
661 // (might be wrong if _Alloc::construct exists but is not constrained,
662 // i.e. actually trying to use it would still be invalid. Use with caution.)
663 template<typename _Alloc>
664 struct __is_copy_insertable
665 : __is_alloc_insertable_impl<_Alloc,
666 typename _Alloc::value_type const&>::type
667 { };
668
669 // std::allocator<_Tp> just requires CopyConstructible
670 template<typename _Tp>
671 struct __is_copy_insertable<allocator<_Tp>>
672 : is_copy_constructible<_Tp>
673 { };
674
675 // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
676 // (might be wrong if _Alloc::construct exists but is not constrained,
677 // i.e. actually trying to use it would still be invalid. Use with caution.)
678 template<typename _Alloc>
679 struct __is_move_insertable
680 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
681 { };
682
683 // std::allocator<_Tp> just requires MoveConstructible
684 template<typename _Tp>
685 struct __is_move_insertable<allocator<_Tp>>
686 : is_move_constructible<_Tp>
687 { };
688
689 // Trait to detect Allocator-like types.
690 template<typename _Alloc, typename = void>
691 struct __is_allocator : false_type { };
692
693 template<typename _Alloc>
694 struct __is_allocator<_Alloc,
695 __void_t<typename _Alloc::value_type,
696 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
697 : true_type { };
698
699 template<typename _Alloc>
700 using _RequireAllocator
701 = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
702
703 template<typename _Alloc>
704 using _RequireNotAllocator
705 = typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
706 #endif // C++11
707
708 /**
709 * Destroy a range of objects using the supplied allocator. For
710 * non-default allocators we do not optimize away invocation of
711 * destroy() even if _Tp has a trivial destructor.
712 */
713
714 template<typename _ForwardIterator, typename _Allocator>
715 void
716 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
717 _Allocator& __alloc)
718 {
719 for (; __first != __last; ++__first)
720 #if __cplusplus < 201103L
721 __alloc.destroy(std::__addressof(*__first));
722 #else
723 allocator_traits<_Allocator>::destroy(__alloc,
724 std::__addressof(*__first));
725 #endif
726 }
727
728 template<typename _ForwardIterator, typename _Tp>
729 inline void
730 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
731 allocator<_Tp>&)
732 {
733 _Destroy(__first, __last);
734 }
735
736 _GLIBCXX_END_NAMESPACE_VERSION
737 } // namespace std
738 #endif // _ALLOC_TRAITS_H