1 // Allocator traits -*- C++ -*-
3 // Copyright (C) 2011-2020 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(std::is_nothrow_constructible
<_Tp
, _Args
...>::value
)
256 #if __cplusplus <= 201703L
257 ::new((void*)__p
) _Tp(std::forward
<_Args
>(__args
)...);
259 std::construct_at(__p
, std::forward
<_Args
>(__args
)...);
263 template<typename _Alloc2
, typename _Tp
>
264 static _GLIBCXX14_CONSTEXPR
auto
265 _S_destroy(_Alloc2
& __a
, _Tp
* __p
, int)
266 noexcept(noexcept(__a
.destroy(__p
)))
267 -> decltype(__a
.destroy(__p
))
268 { __a
.destroy(__p
); }
270 template<typename _Alloc2
, typename _Tp
>
271 static _GLIBCXX14_CONSTEXPR
void
272 _S_destroy(_Alloc2
&, _Tp
* __p
, ...)
273 noexcept(std::is_nothrow_destructible
<_Tp
>::value
)
274 { std::_Destroy(__p
); }
276 template<typename _Alloc2
>
277 static constexpr auto
278 _S_max_size(_Alloc2
& __a
, int)
279 -> decltype(__a
.max_size())
280 { return __a
.max_size(); }
282 template<typename _Alloc2
>
283 static constexpr size_type
284 _S_max_size(_Alloc2
&, ...)
286 // _GLIBCXX_RESOLVE_LIB_DEFECTS
287 // 2466. allocator_traits::max_size() default behavior is incorrect
288 return __gnu_cxx::__numeric_traits
<size_type
>::__max
289 / sizeof(value_type
);
292 template<typename _Alloc2
>
293 static constexpr auto
294 _S_select(_Alloc2
& __a
, int)
295 -> decltype(__a
.select_on_container_copy_construction())
296 { return __a
.select_on_container_copy_construction(); }
298 template<typename _Alloc2
>
299 static constexpr _Alloc2
300 _S_select(_Alloc2
& __a
, ...)
306 * @brief Allocate memory.
307 * @param __a An allocator.
308 * @param __n The number of objects to allocate space for.
310 * Calls @c a.allocate(n)
312 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
313 allocate(_Alloc
& __a
, size_type __n
)
314 { return __a
.allocate(__n
); }
317 * @brief Allocate memory.
318 * @param __a An allocator.
319 * @param __n The number of objects to allocate space for.
320 * @param __hint Aid to locality.
321 * @return Memory of suitable size and alignment for @a n objects
322 * of type @c value_type
324 * Returns <tt> a.allocate(n, hint) </tt> if that expression is
325 * well-formed, otherwise returns @c a.allocate(n)
327 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
328 allocate(_Alloc
& __a
, size_type __n
, const_void_pointer __hint
)
329 { return _S_allocate(__a
, __n
, __hint
, 0); }
332 * @brief Deallocate memory.
333 * @param __a An allocator.
334 * @param __p Pointer to the memory to deallocate.
335 * @param __n The number of objects space was allocated for.
337 * Calls <tt> a.deallocate(p, n) </tt>
339 static _GLIBCXX20_CONSTEXPR
void
340 deallocate(_Alloc
& __a
, pointer __p
, size_type __n
)
341 { __a
.deallocate(__p
, __n
); }
344 * @brief Construct an object of type @a _Tp
345 * @param __a An allocator.
346 * @param __p Pointer to memory of suitable size and alignment for Tp
347 * @param __args Constructor arguments.
349 * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
350 * if that expression is well-formed, otherwise uses placement-new
351 * to construct an object of type @a _Tp at location @a __p from the
352 * arguments @a __args...
354 template<typename _Tp
, typename
... _Args
>
355 static _GLIBCXX20_CONSTEXPR
auto
356 construct(_Alloc
& __a
, _Tp
* __p
, _Args
&&... __args
)
357 noexcept(noexcept(_S_construct(__a
, __p
,
358 std::forward
<_Args
>(__args
)...)))
359 -> decltype(_S_construct(__a
, __p
, std::forward
<_Args
>(__args
)...))
360 { _S_construct(__a
, __p
, std::forward
<_Args
>(__args
)...); }
363 * @brief Destroy an object of type @a _Tp
364 * @param __a An allocator.
365 * @param __p Pointer to the object to destroy
367 * Calls @c __a.destroy(__p) if that expression is well-formed,
368 * otherwise calls @c __p->~_Tp()
370 template<typename _Tp
>
371 static _GLIBCXX20_CONSTEXPR
void
372 destroy(_Alloc
& __a
, _Tp
* __p
)
373 noexcept(noexcept(_S_destroy(__a
, __p
, 0)))
374 { _S_destroy(__a
, __p
, 0); }
377 * @brief The maximum supported allocation size
378 * @param __a An allocator.
379 * @return @c __a.max_size() or @c numeric_limits<size_type>::max()
381 * Returns @c __a.max_size() if that expression is well-formed,
382 * otherwise returns @c numeric_limits<size_type>::max()
384 static _GLIBCXX20_CONSTEXPR size_type
385 max_size(const _Alloc
& __a
) noexcept
386 { return _S_max_size(__a
, 0); }
389 * @brief Obtain an allocator to use when copying a container.
390 * @param __rhs An allocator.
391 * @return @c __rhs.select_on_container_copy_construction() or @a __rhs
393 * Returns @c __rhs.select_on_container_copy_construction() if that
394 * expression is well-formed, otherwise returns @a __rhs
396 static _GLIBCXX20_CONSTEXPR _Alloc
397 select_on_container_copy_construction(const _Alloc
& __rhs
)
398 { return _S_select(__rhs
, 0); }
401 #if __cplusplus > 201703L
402 # define __cpp_lib_constexpr_dynamic_alloc 201907L
405 /// Partial specialization for std::allocator.
406 template<typename _Tp
>
407 struct allocator_traits
<allocator
<_Tp
>>
409 /// The allocator type
410 using allocator_type
= allocator
<_Tp
>;
412 /// The allocated type
413 using value_type
= _Tp
;
415 /// The allocator's pointer type.
416 using pointer
= _Tp
*;
418 /// The allocator's const pointer type.
419 using const_pointer
= const _Tp
*;
421 /// The allocator's void pointer type.
422 using void_pointer
= void*;
424 /// The allocator's const void pointer type.
425 using const_void_pointer
= const void*;
427 /// The allocator's difference type
428 using difference_type
= std::ptrdiff_t;
430 /// The allocator's size type
431 using size_type
= std::size_t;
433 /// How the allocator is propagated on copy assignment
434 using propagate_on_container_copy_assignment
= false_type
;
436 /// How the allocator is propagated on move assignment
437 using propagate_on_container_move_assignment
= true_type
;
439 /// How the allocator is propagated on swap
440 using propagate_on_container_swap
= false_type
;
442 /// Whether all instances of the allocator type compare equal.
443 using is_always_equal
= true_type
;
445 template<typename _Up
>
446 using rebind_alloc
= allocator
<_Up
>;
448 template<typename _Up
>
449 using rebind_traits
= allocator_traits
<allocator
<_Up
>>;
452 * @brief Allocate memory.
453 * @param __a An allocator.
454 * @param __n The number of objects to allocate space for.
456 * Calls @c a.allocate(n)
458 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
459 allocate(allocator_type
& __a
, size_type __n
)
460 { return __a
.allocate(__n
); }
463 * @brief Allocate memory.
464 * @param __a An allocator.
465 * @param __n The number of objects to allocate space for.
466 * @param __hint Aid to locality.
467 * @return Memory of suitable size and alignment for @a n objects
468 * of type @c value_type
470 * Returns <tt> a.allocate(n, hint) </tt>
472 _GLIBCXX_NODISCARD
static _GLIBCXX20_CONSTEXPR pointer
473 allocate(allocator_type
& __a
, size_type __n
, const_void_pointer __hint
)
475 #if __cplusplus <= 201703L
476 return __a
.allocate(__n
, __hint
);
478 return __a
.allocate(__n
);
483 * @brief Deallocate memory.
484 * @param __a An allocator.
485 * @param __p Pointer to the memory to deallocate.
486 * @param __n The number of objects space was allocated for.
488 * Calls <tt> a.deallocate(p, n) </tt>
490 static _GLIBCXX20_CONSTEXPR
void
491 deallocate(allocator_type
& __a
, pointer __p
, size_type __n
)
492 { __a
.deallocate(__p
, __n
); }
495 * @brief Construct an object of type `_Up`
496 * @param __a An allocator.
497 * @param __p Pointer to memory of suitable size and alignment for
498 * an object of type `_Up`.
499 * @param __args Constructor arguments.
501 * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
502 * in C++11, C++14 and C++17. Changed in C++20 to call
503 * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
505 template<typename _Up
, typename
... _Args
>
506 static _GLIBCXX20_CONSTEXPR
void
507 construct(allocator_type
& __a
__attribute__((__unused__
)), _Up
* __p
,
509 noexcept(std::is_nothrow_constructible
<_Up
, _Args
...>::value
)
511 #if __cplusplus <= 201703L
512 __a
.construct(__p
, std::forward
<_Args
>(__args
)...);
514 std::construct_at(__p
, std::forward
<_Args
>(__args
)...);
519 * @brief Destroy an object of type @a _Up
520 * @param __a An allocator.
521 * @param __p Pointer to the object to destroy
523 * Calls @c __a.destroy(__p).
525 template<typename _Up
>
526 static _GLIBCXX20_CONSTEXPR
void
527 destroy(allocator_type
& __a
__attribute__((__unused__
)), _Up
* __p
)
528 noexcept(is_nothrow_destructible
<_Up
>::value
)
530 #if __cplusplus <= 201703L
533 std::destroy_at(__p
);
538 * @brief The maximum supported allocation size
539 * @param __a An allocator.
540 * @return @c __a.max_size()
542 static _GLIBCXX20_CONSTEXPR size_type
543 max_size(const allocator_type
& __a
__attribute__((__unused__
))) noexcept
545 #if __cplusplus <= 201703L
546 return __a
.max_size();
548 return size_t(-1) / sizeof(value_type
);
553 * @brief Obtain an allocator to use when copying a container.
554 * @param __rhs An allocator.
557 static _GLIBCXX20_CONSTEXPR allocator_type
558 select_on_container_copy_construction(const allocator_type
& __rhs
)
562 #if __cplusplus < 201703L
563 template<typename _Alloc
>
565 __do_alloc_on_copy(_Alloc
& __one
, const _Alloc
& __two
, true_type
)
568 template<typename _Alloc
>
570 __do_alloc_on_copy(_Alloc
&, const _Alloc
&, false_type
)
574 template<typename _Alloc
>
575 _GLIBCXX14_CONSTEXPR
inline void
576 __alloc_on_copy(_Alloc
& __one
, const _Alloc
& __two
)
578 typedef allocator_traits
<_Alloc
> __traits
;
579 typedef typename
__traits::propagate_on_container_copy_assignment __pocca
;
580 #if __cplusplus >= 201703L
581 if constexpr (__pocca::value
)
584 __do_alloc_on_copy(__one
, __two
, __pocca());
588 template<typename _Alloc
>
590 __alloc_on_copy(const _Alloc
& __a
)
592 typedef allocator_traits
<_Alloc
> __traits
;
593 return __traits::select_on_container_copy_construction(__a
);
596 #if __cplusplus < 201703L
597 template<typename _Alloc
>
598 inline void __do_alloc_on_move(_Alloc
& __one
, _Alloc
& __two
, true_type
)
599 { __one
= std::move(__two
); }
601 template<typename _Alloc
>
602 inline void __do_alloc_on_move(_Alloc
&, _Alloc
&, false_type
)
606 template<typename _Alloc
>
607 _GLIBCXX14_CONSTEXPR
inline void
608 __alloc_on_move(_Alloc
& __one
, _Alloc
& __two
)
610 typedef allocator_traits
<_Alloc
> __traits
;
611 typedef typename
__traits::propagate_on_container_move_assignment __pocma
;
612 #if __cplusplus >= 201703L
613 if constexpr (__pocma::value
)
614 __one
= std::move(__two
);
616 __do_alloc_on_move(__one
, __two
, __pocma());
620 #if __cplusplus < 201703L
621 template<typename _Alloc
>
622 inline void __do_alloc_on_swap(_Alloc
& __one
, _Alloc
& __two
, true_type
)
628 template<typename _Alloc
>
629 inline void __do_alloc_on_swap(_Alloc
&, _Alloc
&, false_type
)
633 template<typename _Alloc
>
634 _GLIBCXX14_CONSTEXPR
inline void
635 __alloc_on_swap(_Alloc
& __one
, _Alloc
& __two
)
637 typedef allocator_traits
<_Alloc
> __traits
;
638 typedef typename
__traits::propagate_on_container_swap __pocs
;
639 #if __cplusplus >= 201703L
640 if constexpr (__pocs::value
)
646 __do_alloc_on_swap(__one
, __two
, __pocs());
650 template<typename _Alloc
, typename _Tp
,
651 typename _ValueT
= __remove_cvref_t
<typename
_Alloc::value_type
>,
653 struct __is_alloc_insertable_impl
657 template<typename _Alloc
, typename _Tp
, typename _ValueT
>
658 struct __is_alloc_insertable_impl
<_Alloc
, _Tp
, _ValueT
,
659 __void_t
<decltype(allocator_traits
<_Alloc
>::construct(
660 std::declval
<_Alloc
&>(), std::declval
<_ValueT
*>(),
661 std::declval
<_Tp
>()))>>
665 // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
666 // (might be wrong if _Alloc::construct exists but is not constrained,
667 // i.e. actually trying to use it would still be invalid. Use with caution.)
668 template<typename _Alloc
>
669 struct __is_copy_insertable
670 : __is_alloc_insertable_impl
<_Alloc
,
671 typename
_Alloc::value_type
const&>::type
674 // std::allocator<_Tp> just requires CopyConstructible
675 template<typename _Tp
>
676 struct __is_copy_insertable
<allocator
<_Tp
>>
677 : is_copy_constructible
<_Tp
>
680 // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
681 // (might be wrong if _Alloc::construct exists but is not constrained,
682 // i.e. actually trying to use it would still be invalid. Use with caution.)
683 template<typename _Alloc
>
684 struct __is_move_insertable
685 : __is_alloc_insertable_impl
<_Alloc
, typename
_Alloc::value_type
>::type
688 // std::allocator<_Tp> just requires MoveConstructible
689 template<typename _Tp
>
690 struct __is_move_insertable
<allocator
<_Tp
>>
691 : is_move_constructible
<_Tp
>
694 // Trait to detect Allocator-like types.
695 template<typename _Alloc
, typename
= void>
696 struct __is_allocator
: false_type
{ };
698 template<typename _Alloc
>
699 struct __is_allocator
<_Alloc
,
700 __void_t
<typename
_Alloc::value_type
,
701 decltype(std::declval
<_Alloc
&>().allocate(size_t{}))>>
704 template<typename _Alloc
>
705 using _RequireAllocator
706 = typename enable_if
<__is_allocator
<_Alloc
>::value
, _Alloc
>::type
;
708 template<typename _Alloc
>
709 using _RequireNotAllocator
710 = typename enable_if
<!__is_allocator
<_Alloc
>::value
, _Alloc
>::type
;
714 * Destroy a range of objects using the supplied allocator. For
715 * non-default allocators we do not optimize away invocation of
716 * destroy() even if _Tp has a trivial destructor.
719 template<typename _ForwardIterator
, typename _Allocator
>
721 _Destroy(_ForwardIterator __first
, _ForwardIterator __last
,
724 for (; __first
!= __last
; ++__first
)
725 #if __cplusplus < 201103L
726 __alloc
.destroy(std::__addressof(*__first
));
728 allocator_traits
<_Allocator
>::destroy(__alloc
,
729 std::__addressof(*__first
));
733 template<typename _ForwardIterator
, typename _Tp
>
735 _Destroy(_ForwardIterator __first
, _ForwardIterator __last
,
738 _Destroy(__first
, __last
);
741 _GLIBCXX_END_NAMESPACE_VERSION
743 #endif // _ALLOC_TRAITS_H