libstdc++
|
00001 // Allocator traits -*- C++ -*- 00002 00003 // Copyright (C) 2011-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/alloc_traits.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{memory} 00028 */ 00029 00030 #ifndef _ALLOC_TRAITS_H 00031 #define _ALLOC_TRAITS_H 1 00032 00033 #if __cplusplus >= 201103L 00034 00035 #include <bits/memoryfwd.h> 00036 #include <bits/ptr_traits.h> 00037 #include <ext/numeric_traits.h> 00038 00039 #define __cpp_lib_allocator_traits_is_always_equal 201411 00040 00041 namespace std _GLIBCXX_VISIBILITY(default) 00042 { 00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00044 00045 struct __allocator_traits_base 00046 { 00047 template<typename _Tp, typename _Up, typename = void> 00048 struct __rebind : __replace_first_arg<_Tp, _Up> { }; 00049 00050 template<typename _Tp, typename _Up> 00051 struct __rebind<_Tp, _Up, 00052 __void_t<typename _Tp::template rebind<_Up>::other>> 00053 { using type = typename _Tp::template rebind<_Up>::other; }; 00054 00055 protected: 00056 template<typename _Tp> 00057 using __pointer = typename _Tp::pointer; 00058 template<typename _Tp> 00059 using __c_pointer = typename _Tp::const_pointer; 00060 template<typename _Tp> 00061 using __v_pointer = typename _Tp::void_pointer; 00062 template<typename _Tp> 00063 using __cv_pointer = typename _Tp::const_void_pointer; 00064 template<typename _Tp> 00065 using __pocca = typename _Tp::propagate_on_container_copy_assignment; 00066 template<typename _Tp> 00067 using __pocma = typename _Tp::propagate_on_container_move_assignment; 00068 template<typename _Tp> 00069 using __pocs = typename _Tp::propagate_on_container_swap; 00070 template<typename _Tp> 00071 using __equal = typename _Tp::is_always_equal; 00072 }; 00073 00074 template<typename _Alloc, typename _Up> 00075 using __alloc_rebind 00076 = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; 00077 00078 /** 00079 * @brief Uniform interface to all allocator types. 00080 * @ingroup allocators 00081 */ 00082 template<typename _Alloc> 00083 struct allocator_traits : __allocator_traits_base 00084 { 00085 /// The allocator type 00086 typedef _Alloc allocator_type; 00087 /// The allocated type 00088 typedef typename _Alloc::value_type value_type; 00089 00090 /** 00091 * @brief The allocator's pointer type. 00092 * 00093 * @c Alloc::pointer if that type exists, otherwise @c value_type* 00094 */ 00095 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>; 00096 00097 private: 00098 // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp> 00099 template<template<typename> class _Func, typename _Tp, typename = void> 00100 struct _Ptr 00101 { 00102 using type = typename pointer_traits<pointer>::template rebind<_Tp>; 00103 }; 00104 00105 template<template<typename> class _Func, typename _Tp> 00106 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>> 00107 { 00108 using type = _Func<_Alloc>; 00109 }; 00110 00111 // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type 00112 template<typename _A2, typename _PtrT, typename = void> 00113 struct _Diff 00114 { using type = typename pointer_traits<_PtrT>::difference_type; }; 00115 00116 template<typename _A2, typename _PtrT> 00117 struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>> 00118 { using type = typename _A2::difference_type; }; 00119 00120 // Select _A2::size_type or make_unsigned<_DiffT>::type 00121 template<typename _A2, typename _DiffT, typename = void> 00122 struct _Size : make_unsigned<_DiffT> { }; 00123 00124 template<typename _A2, typename _DiffT> 00125 struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>> 00126 { using type = typename _A2::size_type; }; 00127 00128 public: 00129 /** 00130 * @brief The allocator's const pointer type. 00131 * 00132 * @c Alloc::const_pointer if that type exists, otherwise 00133 * <tt> pointer_traits<pointer>::rebind<const value_type> </tt> 00134 */ 00135 using const_pointer = typename _Ptr<__c_pointer, const value_type>::type; 00136 00137 /** 00138 * @brief The allocator's void pointer type. 00139 * 00140 * @c Alloc::void_pointer if that type exists, otherwise 00141 * <tt> pointer_traits<pointer>::rebind<void> </tt> 00142 */ 00143 using void_pointer = typename _Ptr<__v_pointer, void>::type; 00144 00145 /** 00146 * @brief The allocator's const void pointer type. 00147 * 00148 * @c Alloc::const_void_pointer if that type exists, otherwise 00149 * <tt> pointer_traits<pointer>::rebind<const void> </tt> 00150 */ 00151 using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type; 00152 00153 /** 00154 * @brief The allocator's difference type 00155 * 00156 * @c Alloc::difference_type if that type exists, otherwise 00157 * <tt> pointer_traits<pointer>::difference_type </tt> 00158 */ 00159 using difference_type = typename _Diff<_Alloc, pointer>::type; 00160 00161 /** 00162 * @brief The allocator's size type 00163 * 00164 * @c Alloc::size_type if that type exists, otherwise 00165 * <tt> make_unsigned<difference_type>::type </tt> 00166 */ 00167 using size_type = typename _Size<_Alloc, difference_type>::type; 00168 00169 /** 00170 * @brief How the allocator is propagated on copy assignment 00171 * 00172 * @c Alloc::propagate_on_container_copy_assignment if that type exists, 00173 * otherwise @c false_type 00174 */ 00175 using propagate_on_container_copy_assignment 00176 = __detected_or_t<false_type, __pocca, _Alloc>; 00177 00178 /** 00179 * @brief How the allocator is propagated on move assignment 00180 * 00181 * @c Alloc::propagate_on_container_move_assignment if that type exists, 00182 * otherwise @c false_type 00183 */ 00184 using propagate_on_container_move_assignment 00185 = __detected_or_t<false_type, __pocma, _Alloc>; 00186 00187 /** 00188 * @brief How the allocator is propagated on swap 00189 * 00190 * @c Alloc::propagate_on_container_swap if that type exists, 00191 * otherwise @c false_type 00192 */ 00193 using propagate_on_container_swap 00194 = __detected_or_t<false_type, __pocs, _Alloc>; 00195 00196 /** 00197 * @brief Whether all instances of the allocator type compare equal. 00198 * 00199 * @c Alloc::is_always_equal if that type exists, 00200 * otherwise @c is_empty<Alloc>::type 00201 */ 00202 using is_always_equal 00203 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>; 00204 00205 template<typename _Tp> 00206 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; 00207 template<typename _Tp> 00208 using rebind_traits = allocator_traits<rebind_alloc<_Tp>>; 00209 00210 private: 00211 template<typename _Alloc2> 00212 static auto 00213 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int) 00214 -> decltype(__a.allocate(__n, __hint)) 00215 { return __a.allocate(__n, __hint); } 00216 00217 template<typename _Alloc2> 00218 static pointer 00219 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...) 00220 { return __a.allocate(__n); } 00221 00222 template<typename _Tp, typename... _Args> 00223 struct __construct_helper 00224 { 00225 template<typename _Alloc2, 00226 typename = decltype(std::declval<_Alloc2*>()->construct( 00227 std::declval<_Tp*>(), std::declval<_Args>()...))> 00228 static true_type __test(int); 00229 00230 template<typename> 00231 static false_type __test(...); 00232 00233 using type = decltype(__test<_Alloc>(0)); 00234 }; 00235 00236 template<typename _Tp, typename... _Args> 00237 using __has_construct 00238 = typename __construct_helper<_Tp, _Args...>::type; 00239 00240 template<typename _Tp, typename... _Args> 00241 static _Require<__has_construct<_Tp, _Args...>> 00242 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 00243 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...))) 00244 { __a.construct(__p, std::forward<_Args>(__args)...); } 00245 00246 template<typename _Tp, typename... _Args> 00247 static 00248 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>, 00249 is_constructible<_Tp, _Args...>>> 00250 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) 00251 noexcept(noexcept(::new((void*)__p) 00252 _Tp(std::forward<_Args>(__args)...))) 00253 { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } 00254 00255 template<typename _Alloc2, typename _Tp> 00256 static auto 00257 _S_destroy(_Alloc2& __a, _Tp* __p, int) 00258 noexcept(noexcept(__a.destroy(__p))) 00259 -> decltype(__a.destroy(__p)) 00260 { __a.destroy(__p); } 00261 00262 template<typename _Alloc2, typename _Tp> 00263 static void 00264 _S_destroy(_Alloc2&, _Tp* __p, ...) 00265 noexcept(noexcept(__p->~_Tp())) 00266 { __p->~_Tp(); } 00267 00268 template<typename _Alloc2> 00269 static auto 00270 _S_max_size(_Alloc2& __a, int) 00271 -> decltype(__a.max_size()) 00272 { return __a.max_size(); } 00273 00274 template<typename _Alloc2> 00275 static size_type 00276 _S_max_size(_Alloc2&, ...) 00277 { 00278 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00279 // 2466. allocator_traits::max_size() default behavior is incorrect 00280 return __gnu_cxx::__numeric_traits<size_type>::__max 00281 / sizeof(value_type); 00282 } 00283 00284 template<typename _Alloc2> 00285 static auto 00286 _S_select(_Alloc2& __a, int) 00287 -> decltype(__a.select_on_container_copy_construction()) 00288 { return __a.select_on_container_copy_construction(); } 00289 00290 template<typename _Alloc2> 00291 static _Alloc2 00292 _S_select(_Alloc2& __a, ...) 00293 { return __a; } 00294 00295 public: 00296 00297 /** 00298 * @brief Allocate memory. 00299 * @param __a An allocator. 00300 * @param __n The number of objects to allocate space for. 00301 * 00302 * Calls @c a.allocate(n) 00303 */ 00304 _GLIBCXX_NODISCARD static pointer 00305 allocate(_Alloc& __a, size_type __n) 00306 { return __a.allocate(__n); } 00307 00308 /** 00309 * @brief Allocate memory. 00310 * @param __a An allocator. 00311 * @param __n The number of objects to allocate space for. 00312 * @param __hint Aid to locality. 00313 * @return Memory of suitable size and alignment for @a n objects 00314 * of type @c value_type 00315 * 00316 * Returns <tt> a.allocate(n, hint) </tt> if that expression is 00317 * well-formed, otherwise returns @c a.allocate(n) 00318 */ 00319 _GLIBCXX_NODISCARD static pointer 00320 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) 00321 { return _S_allocate(__a, __n, __hint, 0); } 00322 00323 /** 00324 * @brief Deallocate memory. 00325 * @param __a An allocator. 00326 * @param __p Pointer to the memory to deallocate. 00327 * @param __n The number of objects space was allocated for. 00328 * 00329 * Calls <tt> a.deallocate(p, n) </tt> 00330 */ 00331 static void 00332 deallocate(_Alloc& __a, pointer __p, size_type __n) 00333 { __a.deallocate(__p, __n); } 00334 00335 /** 00336 * @brief Construct an object of type @a _Tp 00337 * @param __a An allocator. 00338 * @param __p Pointer to memory of suitable size and alignment for Tp 00339 * @param __args Constructor arguments. 00340 * 00341 * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt> 00342 * if that expression is well-formed, otherwise uses placement-new 00343 * to construct an object of type @a _Tp at location @a __p from the 00344 * arguments @a __args... 00345 */ 00346 template<typename _Tp, typename... _Args> 00347 static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 00348 noexcept(noexcept(_S_construct(__a, __p, 00349 std::forward<_Args>(__args)...))) 00350 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) 00351 { _S_construct(__a, __p, std::forward<_Args>(__args)...); } 00352 00353 /** 00354 * @brief Destroy an object of type @a _Tp 00355 * @param __a An allocator. 00356 * @param __p Pointer to the object to destroy 00357 * 00358 * Calls @c __a.destroy(__p) if that expression is well-formed, 00359 * otherwise calls @c __p->~_Tp() 00360 */ 00361 template<typename _Tp> 00362 static void destroy(_Alloc& __a, _Tp* __p) 00363 noexcept(noexcept(_S_destroy(__a, __p, 0))) 00364 { _S_destroy(__a, __p, 0); } 00365 00366 /** 00367 * @brief The maximum supported allocation size 00368 * @param __a An allocator. 00369 * @return @c __a.max_size() or @c numeric_limits<size_type>::max() 00370 * 00371 * Returns @c __a.max_size() if that expression is well-formed, 00372 * otherwise returns @c numeric_limits<size_type>::max() 00373 */ 00374 static size_type max_size(const _Alloc& __a) noexcept 00375 { return _S_max_size(__a, 0); } 00376 00377 /** 00378 * @brief Obtain an allocator to use when copying a container. 00379 * @param __rhs An allocator. 00380 * @return @c __rhs.select_on_container_copy_construction() or @a __rhs 00381 * 00382 * Returns @c __rhs.select_on_container_copy_construction() if that 00383 * expression is well-formed, otherwise returns @a __rhs 00384 */ 00385 static _Alloc 00386 select_on_container_copy_construction(const _Alloc& __rhs) 00387 { return _S_select(__rhs, 0); } 00388 }; 00389 00390 /// Partial specialization for std::allocator. 00391 template<typename _Tp> 00392 struct allocator_traits<allocator<_Tp>> 00393 { 00394 /// The allocator type 00395 using allocator_type = allocator<_Tp>; 00396 /// The allocated type 00397 using value_type = _Tp; 00398 00399 /// The allocator's pointer type. 00400 using pointer = _Tp*; 00401 00402 /// The allocator's const pointer type. 00403 using const_pointer = const _Tp*; 00404 00405 /// The allocator's void pointer type. 00406 using void_pointer = void*; 00407 00408 /// The allocator's const void pointer type. 00409 using const_void_pointer = const void*; 00410 00411 /// The allocator's difference type 00412 using difference_type = std::ptrdiff_t; 00413 00414 /// The allocator's size type 00415 using size_type = std::size_t; 00416 00417 /// How the allocator is propagated on copy assignment 00418 using propagate_on_container_copy_assignment = false_type; 00419 00420 /// How the allocator is propagated on move assignment 00421 using propagate_on_container_move_assignment = true_type; 00422 00423 /// How the allocator is propagated on swap 00424 using propagate_on_container_swap = false_type; 00425 00426 /// Whether all instances of the allocator type compare equal. 00427 using is_always_equal = true_type; 00428 00429 template<typename _Up> 00430 using rebind_alloc = allocator<_Up>; 00431 00432 template<typename _Up> 00433 using rebind_traits = allocator_traits<allocator<_Up>>; 00434 00435 /** 00436 * @brief Allocate memory. 00437 * @param __a An allocator. 00438 * @param __n The number of objects to allocate space for. 00439 * 00440 * Calls @c a.allocate(n) 00441 */ 00442 _GLIBCXX_NODISCARD static pointer 00443 allocate(allocator_type& __a, size_type __n) 00444 { return __a.allocate(__n); } 00445 00446 /** 00447 * @brief Allocate memory. 00448 * @param __a An allocator. 00449 * @param __n The number of objects to allocate space for. 00450 * @param __hint Aid to locality. 00451 * @return Memory of suitable size and alignment for @a n objects 00452 * of type @c value_type 00453 * 00454 * Returns <tt> a.allocate(n, hint) </tt> 00455 */ 00456 _GLIBCXX_NODISCARD static pointer 00457 allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) 00458 { return __a.allocate(__n, __hint); } 00459 00460 /** 00461 * @brief Deallocate memory. 00462 * @param __a An allocator. 00463 * @param __p Pointer to the memory to deallocate. 00464 * @param __n The number of objects space was allocated for. 00465 * 00466 * Calls <tt> a.deallocate(p, n) </tt> 00467 */ 00468 static void 00469 deallocate(allocator_type& __a, pointer __p, size_type __n) 00470 { __a.deallocate(__p, __n); } 00471 00472 /** 00473 * @brief Construct an object of type @a _Up 00474 * @param __a An allocator. 00475 * @param __p Pointer to memory of suitable size and alignment for Tp 00476 * @param __args Constructor arguments. 00477 * 00478 * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt> 00479 */ 00480 template<typename _Up, typename... _Args> 00481 static void 00482 construct(allocator_type& __a, _Up* __p, _Args&&... __args) 00483 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...))) 00484 { __a.construct(__p, std::forward<_Args>(__args)...); } 00485 00486 /** 00487 * @brief Destroy an object of type @a _Up 00488 * @param __a An allocator. 00489 * @param __p Pointer to the object to destroy 00490 * 00491 * Calls @c __a.destroy(__p). 00492 */ 00493 template<typename _Up> 00494 static void 00495 destroy(allocator_type& __a, _Up* __p) 00496 noexcept(noexcept(__a.destroy(__p))) 00497 { __a.destroy(__p); } 00498 00499 /** 00500 * @brief The maximum supported allocation size 00501 * @param __a An allocator. 00502 * @return @c __a.max_size() 00503 */ 00504 static size_type 00505 max_size(const allocator_type& __a) noexcept 00506 { return __a.max_size(); } 00507 00508 /** 00509 * @brief Obtain an allocator to use when copying a container. 00510 * @param __rhs An allocator. 00511 * @return @c __rhs 00512 */ 00513 static allocator_type 00514 select_on_container_copy_construction(const allocator_type& __rhs) 00515 { return __rhs; } 00516 }; 00517 00518 00519 template<typename _Alloc> 00520 inline void 00521 __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type) 00522 { __one = __two; } 00523 00524 template<typename _Alloc> 00525 inline void 00526 __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type) 00527 { } 00528 00529 template<typename _Alloc> 00530 inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two) 00531 { 00532 typedef allocator_traits<_Alloc> __traits; 00533 typedef typename __traits::propagate_on_container_copy_assignment __pocca; 00534 __do_alloc_on_copy(__one, __two, __pocca()); 00535 } 00536 00537 template<typename _Alloc> 00538 inline _Alloc __alloc_on_copy(const _Alloc& __a) 00539 { 00540 typedef allocator_traits<_Alloc> __traits; 00541 return __traits::select_on_container_copy_construction(__a); 00542 } 00543 00544 template<typename _Alloc> 00545 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type) 00546 { __one = std::move(__two); } 00547 00548 template<typename _Alloc> 00549 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type) 00550 { } 00551 00552 template<typename _Alloc> 00553 inline void __alloc_on_move(_Alloc& __one, _Alloc& __two) 00554 { 00555 typedef allocator_traits<_Alloc> __traits; 00556 typedef typename __traits::propagate_on_container_move_assignment __pocma; 00557 __do_alloc_on_move(__one, __two, __pocma()); 00558 } 00559 00560 template<typename _Alloc> 00561 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type) 00562 { 00563 using std::swap; 00564 swap(__one, __two); 00565 } 00566 00567 template<typename _Alloc> 00568 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type) 00569 { } 00570 00571 template<typename _Alloc> 00572 inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two) 00573 { 00574 typedef allocator_traits<_Alloc> __traits; 00575 typedef typename __traits::propagate_on_container_swap __pocs; 00576 __do_alloc_on_swap(__one, __two, __pocs()); 00577 } 00578 00579 template<typename _Alloc, typename _Tp, 00580 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>, 00581 typename = void> 00582 struct __is_alloc_insertable_impl 00583 : false_type 00584 { }; 00585 00586 template<typename _Alloc, typename _Tp, typename _ValueT> 00587 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT, 00588 __void_t<decltype(allocator_traits<_Alloc>::construct( 00589 std::declval<_Alloc&>(), std::declval<_ValueT*>(), 00590 std::declval<_Tp>()))>> 00591 : true_type 00592 { }; 00593 00594 // true if _Alloc::value_type is CopyInsertable into containers using _Alloc 00595 // (might be wrong if _Alloc::construct exists but is not constrained, 00596 // i.e. actually trying to use it would still be invalid. Use with caution.) 00597 template<typename _Alloc> 00598 struct __is_copy_insertable 00599 : __is_alloc_insertable_impl<_Alloc, 00600 typename _Alloc::value_type const&>::type 00601 { }; 00602 00603 // std::allocator<_Tp> just requires CopyConstructible 00604 template<typename _Tp> 00605 struct __is_copy_insertable<allocator<_Tp>> 00606 : is_copy_constructible<_Tp> 00607 { }; 00608 00609 // true if _Alloc::value_type is MoveInsertable into containers using _Alloc 00610 // (might be wrong if _Alloc::construct exists but is not constrained, 00611 // i.e. actually trying to use it would still be invalid. Use with caution.) 00612 template<typename _Alloc> 00613 struct __is_move_insertable 00614 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type 00615 { }; 00616 00617 // std::allocator<_Tp> just requires MoveConstructible 00618 template<typename _Tp> 00619 struct __is_move_insertable<allocator<_Tp>> 00620 : is_move_constructible<_Tp> 00621 { }; 00622 00623 // Trait to detect Allocator-like types. 00624 template<typename _Alloc, typename = void> 00625 struct __is_allocator : false_type { }; 00626 00627 template<typename _Alloc> 00628 struct __is_allocator<_Alloc, 00629 __void_t<typename _Alloc::value_type, 00630 decltype(std::declval<_Alloc&>().allocate(size_t{}))>> 00631 : true_type { }; 00632 00633 template<typename _Alloc> 00634 using _RequireAllocator 00635 = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type; 00636 00637 template<typename _Alloc> 00638 using _RequireNotAllocator 00639 = typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type; 00640 00641 _GLIBCXX_END_NAMESPACE_VERSION 00642 } // namespace std 00643 #endif // C++11 00644 #endif // _ALLOC_TRAITS_H