1 // Allocator traits -*- C++ -*-
3 // Copyright (C) 2011-2019 Free Software Foundation, Inc.
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)
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.
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.
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/>.
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}
30 #ifndef _ALLOC_TRAITS_H
31 #define _ALLOC_TRAITS_H 1
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>
41 namespace std
_GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 #if __cplusplus >= 201103L
46 #define __cpp_lib_allocator_traits_is_always_equal 201411
48 struct __allocator_traits_base
50 template<typename _Tp
, typename _Up
, typename
= void>
51 struct __rebind
: __replace_first_arg
<_Tp
, _Up
> { };
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
; };
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
;
77 template<typename _Alloc
, typename _Up
>
79 = typename
__allocator_traits_base::template __rebind
<_Alloc
, _Up
>::type
;
82 * @brief Uniform interface to all allocator types.
85 template<typename _Alloc
>
86 struct allocator_traits
: __allocator_traits_base
88 /// The allocator type
89 typedef _Alloc allocator_type
;
90 /// The allocated type
91 typedef typename
_Alloc::value_type value_type
;
94 * @brief The allocator's pointer type.
96 * @c Alloc::pointer if that type exists, otherwise @c value_type*
98 using pointer
= __detected_or_t
<value_type
*, __pointer
, _Alloc
>;
101 // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
102 template<template<typename
> class _Func
, typename _Tp
, typename
= void>
105 using type
= typename pointer_traits
<pointer
>::template rebind
<_Tp
>;
108 template<template<typename
> class _Func
, typename _Tp
>
109 struct _Ptr
<_Func
, _Tp
, __void_t
<_Func
<_Alloc
>>>
111 using type
= _Func
<_Alloc
>;
114 // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
115 template<typename _A2
, typename _PtrT
, typename
= void>
117 { using type
= typename pointer_traits
<_PtrT
>::difference_type
; };
119 template<typename _A2
, typename _PtrT
>
120 struct _Diff
<_A2
, _PtrT
, __void_t
<typename
_A2::difference_type
>>
121 { using type
= typename
_A2::difference_type
; };
123 // Select _A2::size_type or make_unsigned<_DiffT>::type
124 template<typename _A2
, typename _DiffT
, typename
= void>
125 struct _Size
: make_unsigned
<_DiffT
> { };
127 template<typename _A2
, typename _DiffT
>
128 struct _Size
<_A2
, _DiffT
, __void_t
<typename
_A2::size_type
>>
129 { using type
= typename
_A2::size_type
; };
133 * @brief The allocator's const pointer type.
135 * @c Alloc::const_pointer if that type exists, otherwise
136 * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
138 using const_pointer
= typename _Ptr
<__c_pointer
, const value_type
>::type
;
141 * @brief The allocator's void pointer type.
143 * @c Alloc::void_pointer if that type exists, otherwise
144 * <tt> pointer_traits<pointer>::rebind<void> </tt>
146 using void_pointer
= typename _Ptr
<__v_pointer
, void>::type
;
149 * @brief The allocator's const void pointer type.
151 * @c Alloc::const_void_pointer if that type exists, otherwise
152 * <tt> pointer_traits<pointer>::rebind<const void> </tt>
154 using const_void_pointer
= typename _Ptr
<__cv_pointer
, const void>::type
;
157 * @brief The allocator's difference type
159 * @c Alloc::difference_type if that type exists, otherwise
160 * <tt> pointer_traits<pointer>::difference_type </tt>
162 using difference_type
= typename _Diff
<_Alloc
, pointer
>::type
;
165 * @brief The allocator's size type
167 * @c Alloc::size_type if that type exists, otherwise
168 * <tt> make_unsigned<difference_type>::type </tt>
170 using size_type
= typename _Size
<_Alloc
, difference_type
>::type
;
173 * @brief How the allocator is propagated on copy assignment
175 * @c Alloc::propagate_on_container_copy_assignment if that type exists,
176 * otherwise @c false_type
178 using propagate_on_container_copy_assignment
179 = __detected_or_t
<false_type
, __pocca
, _Alloc
>;
182 * @brief How the allocator is propagated on move assignment
184 * @c Alloc::propagate_on_container_move_assignment if that type exists,
185 * otherwise @c false_type
187 using propagate_on_container_move_assignment
188 = __detected_or_t
<false_type
, __pocma
, _Alloc
>;
191 * @brief How the allocator is propagated on swap
193 * @c Alloc::propagate_on_container_swap if that type exists,
194 * otherwise @c false_type
196 using propagate_on_container_swap
197 = __detected_or_t
<false_type
, __pocs
, _Alloc
>;
200 * @brief Whether all instances of the allocator type compare equal.
202 * @c Alloc::is_always_equal if that type exists,
203 * otherwise @c is_empty<Alloc>::type
205 using is_always_equal
206 = __detected_or_t
<typename is_empty
<_Alloc
>::type
, __equal
, _Alloc
>;
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
>>;
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
); }
220 template<typename _Alloc2
>
221 static constexpr pointer
222 _S_allocate(_Alloc2
& __a
, size_type __n
, const_void_pointer
, ...)
223 { return __a
.allocate(__n
); }
225 template<typename _Tp
, typename
... _Args
>
226 struct __construct_helper
228 template<typename _Alloc2
,
229 typename
= decltype(std::declval
<_Alloc2
*>()->construct(
230 std::declval
<_Tp
*>(), std::declval
<_Args
>()...))>
231 static true_type
__test(int);
234 static false_type
__test(...);
236 using type
= decltype(__test
<_Alloc
>(0));
239 template<typename _Tp
, typename
... _Args
>
240 using __has_construct
241 = typename __construct_helper
<_Tp
, _Args
...>::type
;
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
)...); }
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
)...); }
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
); }
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
); }
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(); }
277 template<typename _Alloc2
>
278 static constexpr size_type
279 _S_max_size(_Alloc2
&, ...)
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
);
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(); }
293 template<typename _Alloc2
>
294 static constexpr _Alloc2
295 _S_select(_Alloc2
& __a
, ...)
301 * @brief Allocate memory.
302 * @param __a An allocator.
303 * @param __n The number of objects to allocate space for.
305 * Calls @c a.allocate(n)
307 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
308 allocate(_Alloc
& __a
, size_type __n
)
309 { return __a
.allocate(__n
); }
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
319 * Returns <tt> a.allocate(n, hint) </tt> if that expression is
320 * well-formed, otherwise returns @c a.allocate(n)
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); }
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.
332 * Calls <tt> a.deallocate(p, n) </tt>
334 static _GLIBCXX20_CONSTEXPR
void
335 deallocate(_Alloc
& __a
, pointer __p
, size_type __n
)
336 { __a
.deallocate(__p
, __n
); }
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.
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...
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
)...); }
358 * @brief Destroy an object of type @a _Tp
359 * @param __a An allocator.
360 * @param __p Pointer to the object to destroy
362 * Calls @c __a.destroy(__p) if that expression is well-formed,
363 * otherwise calls @c __p->~_Tp()
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); }
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()
376 * Returns @c __a.max_size() if that expression is well-formed,
377 * otherwise returns @c numeric_limits<size_type>::max()
379 static _GLIBCXX20_CONSTEXPR size_type
380 max_size(const _Alloc
& __a
) noexcept
381 { return _S_max_size(__a
, 0); }
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
388 * Returns @c __rhs.select_on_container_copy_construction() if that
389 * expression is well-formed, otherwise returns @a __rhs
391 static _GLIBCXX20_CONSTEXPR _Alloc
392 select_on_container_copy_construction(const _Alloc
& __rhs
)
393 { return _S_select(__rhs
, 0); }
396 #if __cplusplus > 201703L
397 # define __cpp_lib_constexpr_dynamic_alloc 201907L
400 /// Partial specialization for std::allocator.
401 template<typename _Tp
>
402 struct allocator_traits
<allocator
<_Tp
>>
404 /// The allocator type
405 using allocator_type
= allocator
<_Tp
>;
407 /// The allocated type
408 using value_type
= _Tp
;
410 /// The allocator's pointer type.
411 using pointer
= _Tp
*;
413 /// The allocator's const pointer type.
414 using const_pointer
= const _Tp
*;
416 /// The allocator's void pointer type.
417 using void_pointer
= void*;
419 /// The allocator's const void pointer type.
420 using const_void_pointer
= const void*;
422 /// The allocator's difference type
423 using difference_type
= std::ptrdiff_t;
425 /// The allocator's size type
426 using size_type
= std::size_t;
428 /// How the allocator is propagated on copy assignment
429 using propagate_on_container_copy_assignment
= false_type
;
431 /// How the allocator is propagated on move assignment
432 using propagate_on_container_move_assignment
= true_type
;
434 /// How the allocator is propagated on swap
435 using propagate_on_container_swap
= false_type
;
437 /// Whether all instances of the allocator type compare equal.
438 using is_always_equal
= true_type
;
440 template<typename _Up
>
441 using rebind_alloc
= allocator
<_Up
>;
443 template<typename _Up
>
444 using rebind_traits
= allocator_traits
<allocator
<_Up
>>;
447 * @brief Allocate memory.
448 * @param __a An allocator.
449 * @param __n The number of objects to allocate space for.
451 * Calls @c a.allocate(n)
453 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
454 allocate(allocator_type
& __a
, size_type __n
)
455 { return __a
.allocate(__n
); }
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
465 * Returns <tt> a.allocate(n, hint) </tt>
467 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
468 allocate(allocator_type
& __a
, size_type __n
, const_void_pointer __hint
)
470 #if __cplusplus <= 201703L
471 return __a
.allocate(__n
, __hint
);
473 return __a
.allocate(__n
);
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.
483 * Calls <tt> a.deallocate(p, n) </tt>
485 static _GLIBCXX20_CONSTEXPR
void
486 deallocate(allocator_type
& __a
, pointer __p
, size_type __n
)
487 { __a
.deallocate(__p
, __n
); }
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.
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.
500 template<typename _Up
, typename
... _Args
>
501 static _GLIBCXX20_CONSTEXPR
void
502 construct(allocator_type
& __a
__attribute__((__unused__
)), _Up
* __p
,
504 noexcept(noexcept(::new((void*)__p
) _Up(std::declval
<_Args
>()...)))
506 #if __cplusplus <= 201703L
507 __a
.construct(__p
, std::forward
<_Args
>(__args
)...);
509 std::construct_at(__p
, std::forward
<_Args
>(__args
)...);
514 * @brief Destroy an object of type @a _Up
515 * @param __a An allocator.
516 * @param __p Pointer to the object to destroy
518 * Calls @c __a.destroy(__p).
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
)
525 #if __cplusplus <= 201703L
528 std::destroy_at(__p
);
533 * @brief The maximum supported allocation size
534 * @param __a An allocator.
535 * @return @c __a.max_size()
537 static _GLIBCXX20_CONSTEXPR size_type
538 max_size(const allocator_type
& __a
__attribute__((__unused__
))) noexcept
540 #if __cplusplus <= 201703L
541 return __a
.max_size();
543 return size_t(-1) / sizeof(value_type
);
548 * @brief Obtain an allocator to use when copying a container.
549 * @param __rhs An allocator.
552 static _GLIBCXX20_CONSTEXPR allocator_type
553 select_on_container_copy_construction(const allocator_type
& __rhs
)
557 #if __cplusplus < 201703L
558 template<typename _Alloc
>
560 __do_alloc_on_copy(_Alloc
& __one
, const _Alloc
& __two
, true_type
)
563 template<typename _Alloc
>
565 __do_alloc_on_copy(_Alloc
&, const _Alloc
&, false_type
)
569 template<typename _Alloc
>
570 _GLIBCXX14_CONSTEXPR
void
571 __alloc_on_copy(_Alloc
& __one
, const _Alloc
& __two
)
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
)
579 __do_alloc_on_copy(__one
, __two
, __pocca());
583 template<typename _Alloc
>
585 __alloc_on_copy(const _Alloc
& __a
)
587 typedef allocator_traits
<_Alloc
> __traits
;
588 return __traits::select_on_container_copy_construction(__a
);
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
); }
596 template<typename _Alloc
>
597 inline void __do_alloc_on_move(_Alloc
&, _Alloc
&, false_type
)
601 template<typename _Alloc
>
602 _GLIBCXX14_CONSTEXPR
void
603 __alloc_on_move(_Alloc
& __one
, _Alloc
& __two
)
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
);
611 __do_alloc_on_move(__one
, __two
, __pocma());
615 #if __cplusplus < 201703L
616 template<typename _Alloc
>
617 inline void __do_alloc_on_swap(_Alloc
& __one
, _Alloc
& __two
, true_type
)
623 template<typename _Alloc
>
624 inline void __do_alloc_on_swap(_Alloc
&, _Alloc
&, false_type
)
628 template<typename _Alloc
>
629 _GLIBCXX14_CONSTEXPR
void
630 __alloc_on_swap(_Alloc
& __one
, _Alloc
& __two
)
632 typedef allocator_traits
<_Alloc
> __traits
;
633 typedef typename
__traits::propagate_on_container_swap __pocs
;
634 #if __cplusplus >= 201703L
635 if constexpr (__pocs::value
)
641 __do_alloc_on_swap(__one
, __two
, __pocs());
645 template<typename _Alloc
, typename _Tp
,
646 typename _ValueT
= __remove_cvref_t
<typename
_Alloc::value_type
>,
648 struct __is_alloc_insertable_impl
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
>()))>>
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
669 // std::allocator<_Tp> just requires CopyConstructible
670 template<typename _Tp
>
671 struct __is_copy_insertable
<allocator
<_Tp
>>
672 : is_copy_constructible
<_Tp
>
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
683 // std::allocator<_Tp> just requires MoveConstructible
684 template<typename _Tp
>
685 struct __is_move_insertable
<allocator
<_Tp
>>
686 : is_move_constructible
<_Tp
>
689 // Trait to detect Allocator-like types.
690 template<typename _Alloc
, typename
= void>
691 struct __is_allocator
: false_type
{ };
693 template<typename _Alloc
>
694 struct __is_allocator
<_Alloc
,
695 __void_t
<typename
_Alloc::value_type
,
696 decltype(std::declval
<_Alloc
&>().allocate(size_t{}))>>
699 template<typename _Alloc
>
700 using _RequireAllocator
701 = typename enable_if
<__is_allocator
<_Alloc
>::value
, _Alloc
>::type
;
703 template<typename _Alloc
>
704 using _RequireNotAllocator
705 = typename enable_if
<!__is_allocator
<_Alloc
>::value
, _Alloc
>::type
;
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.
714 template<typename _ForwardIterator
, typename _Allocator
>
716 _Destroy(_ForwardIterator __first
, _ForwardIterator __last
,
719 for (; __first
!= __last
; ++__first
)
720 #if __cplusplus < 201103L
721 __alloc
.destroy(std::__addressof(*__first
));
723 allocator_traits
<_Allocator
>::destroy(__alloc
,
724 std::__addressof(*__first
));
728 template<typename _ForwardIterator
, typename _Tp
>
730 _Destroy(_ForwardIterator __first
, _ForwardIterator __last
,
733 _Destroy(__first
, __last
);
736 _GLIBCXX_END_NAMESPACE_VERSION
738 #endif // _ALLOC_TRAITS_H