alloc_traits.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. // Allocator traits -*- C++ -*-
  2. // Copyright (C) 2011-2019 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/alloc_traits.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{memory}
  23. */
  24. #ifndef _ALLOC_TRAITS_H
  25. #define _ALLOC_TRAITS_H 1
  26. #if __cplusplus >= 201103L
  27. #include <bits/memoryfwd.h>
  28. #include <bits/ptr_traits.h>
  29. #include <ext/numeric_traits.h>
  30. #define __cpp_lib_allocator_traits_is_always_equal 201411
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. struct __allocator_traits_base
  35. {
  36. template<typename _Tp, typename _Up, typename = void>
  37. struct __rebind : __replace_first_arg<_Tp, _Up> { };
  38. template<typename _Tp, typename _Up>
  39. struct __rebind<_Tp, _Up,
  40. __void_t<typename _Tp::template rebind<_Up>::other>>
  41. { using type = typename _Tp::template rebind<_Up>::other; };
  42. protected:
  43. template<typename _Tp>
  44. using __pointer = typename _Tp::pointer;
  45. template<typename _Tp>
  46. using __c_pointer = typename _Tp::const_pointer;
  47. template<typename _Tp>
  48. using __v_pointer = typename _Tp::void_pointer;
  49. template<typename _Tp>
  50. using __cv_pointer = typename _Tp::const_void_pointer;
  51. template<typename _Tp>
  52. using __pocca = typename _Tp::propagate_on_container_copy_assignment;
  53. template<typename _Tp>
  54. using __pocma = typename _Tp::propagate_on_container_move_assignment;
  55. template<typename _Tp>
  56. using __pocs = typename _Tp::propagate_on_container_swap;
  57. template<typename _Tp>
  58. using __equal = typename _Tp::is_always_equal;
  59. };
  60. template<typename _Alloc, typename _Up>
  61. using __alloc_rebind
  62. = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
  63. /**
  64. * @brief Uniform interface to all allocator types.
  65. * @ingroup allocators
  66. */
  67. template<typename _Alloc>
  68. struct allocator_traits : __allocator_traits_base
  69. {
  70. /// The allocator type
  71. typedef _Alloc allocator_type;
  72. /// The allocated type
  73. typedef typename _Alloc::value_type value_type;
  74. /**
  75. * @brief The allocator's pointer type.
  76. *
  77. * @c Alloc::pointer if that type exists, otherwise @c value_type*
  78. */
  79. using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
  80. private:
  81. // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
  82. template<template<typename> class _Func, typename _Tp, typename = void>
  83. struct _Ptr
  84. {
  85. using type = typename pointer_traits<pointer>::template rebind<_Tp>;
  86. };
  87. template<template<typename> class _Func, typename _Tp>
  88. struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
  89. {
  90. using type = _Func<_Alloc>;
  91. };
  92. // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
  93. template<typename _A2, typename _PtrT, typename = void>
  94. struct _Diff
  95. { using type = typename pointer_traits<_PtrT>::difference_type; };
  96. template<typename _A2, typename _PtrT>
  97. struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
  98. { using type = typename _A2::difference_type; };
  99. // Select _A2::size_type or make_unsigned<_DiffT>::type
  100. template<typename _A2, typename _DiffT, typename = void>
  101. struct _Size : make_unsigned<_DiffT> { };
  102. template<typename _A2, typename _DiffT>
  103. struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
  104. { using type = typename _A2::size_type; };
  105. public:
  106. /**
  107. * @brief The allocator's const pointer type.
  108. *
  109. * @c Alloc::const_pointer if that type exists, otherwise
  110. * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
  111. */
  112. using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
  113. /**
  114. * @brief The allocator's void pointer type.
  115. *
  116. * @c Alloc::void_pointer if that type exists, otherwise
  117. * <tt> pointer_traits<pointer>::rebind<void> </tt>
  118. */
  119. using void_pointer = typename _Ptr<__v_pointer, void>::type;
  120. /**
  121. * @brief The allocator's const void pointer type.
  122. *
  123. * @c Alloc::const_void_pointer if that type exists, otherwise
  124. * <tt> pointer_traits<pointer>::rebind<const void> </tt>
  125. */
  126. using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
  127. /**
  128. * @brief The allocator's difference type
  129. *
  130. * @c Alloc::difference_type if that type exists, otherwise
  131. * <tt> pointer_traits<pointer>::difference_type </tt>
  132. */
  133. using difference_type = typename _Diff<_Alloc, pointer>::type;
  134. /**
  135. * @brief The allocator's size type
  136. *
  137. * @c Alloc::size_type if that type exists, otherwise
  138. * <tt> make_unsigned<difference_type>::type </tt>
  139. */
  140. using size_type = typename _Size<_Alloc, difference_type>::type;
  141. /**
  142. * @brief How the allocator is propagated on copy assignment
  143. *
  144. * @c Alloc::propagate_on_container_copy_assignment if that type exists,
  145. * otherwise @c false_type
  146. */
  147. using propagate_on_container_copy_assignment
  148. = __detected_or_t<false_type, __pocca, _Alloc>;
  149. /**
  150. * @brief How the allocator is propagated on move assignment
  151. *
  152. * @c Alloc::propagate_on_container_move_assignment if that type exists,
  153. * otherwise @c false_type
  154. */
  155. using propagate_on_container_move_assignment
  156. = __detected_or_t<false_type, __pocma, _Alloc>;
  157. /**
  158. * @brief How the allocator is propagated on swap
  159. *
  160. * @c Alloc::propagate_on_container_swap if that type exists,
  161. * otherwise @c false_type
  162. */
  163. using propagate_on_container_swap
  164. = __detected_or_t<false_type, __pocs, _Alloc>;
  165. /**
  166. * @brief Whether all instances of the allocator type compare equal.
  167. *
  168. * @c Alloc::is_always_equal if that type exists,
  169. * otherwise @c is_empty<Alloc>::type
  170. */
  171. using is_always_equal
  172. = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
  173. template<typename _Tp>
  174. using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
  175. template<typename _Tp>
  176. using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
  177. private:
  178. template<typename _Alloc2>
  179. static auto
  180. _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
  181. -> decltype(__a.allocate(__n, __hint))
  182. { return __a.allocate(__n, __hint); }
  183. template<typename _Alloc2>
  184. static pointer
  185. _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
  186. { return __a.allocate(__n); }
  187. template<typename _Tp, typename... _Args>
  188. struct __construct_helper
  189. {
  190. template<typename _Alloc2,
  191. typename = decltype(std::declval<_Alloc2*>()->construct(
  192. std::declval<_Tp*>(), std::declval<_Args>()...))>
  193. static true_type __test(int);
  194. template<typename>
  195. static false_type __test(...);
  196. using type = decltype(__test<_Alloc>(0));
  197. };
  198. template<typename _Tp, typename... _Args>
  199. using __has_construct
  200. = typename __construct_helper<_Tp, _Args...>::type;
  201. template<typename _Tp, typename... _Args>
  202. static _Require<__has_construct<_Tp, _Args...>>
  203. _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
  204. noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
  205. { __a.construct(__p, std::forward<_Args>(__args)...); }
  206. template<typename _Tp, typename... _Args>
  207. static
  208. _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
  209. is_constructible<_Tp, _Args...>>>
  210. _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
  211. noexcept(noexcept(::new((void*)__p)
  212. _Tp(std::forward<_Args>(__args)...)))
  213. { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
  214. template<typename _Alloc2, typename _Tp>
  215. static auto
  216. _S_destroy(_Alloc2& __a, _Tp* __p, int)
  217. noexcept(noexcept(__a.destroy(__p)))
  218. -> decltype(__a.destroy(__p))
  219. { __a.destroy(__p); }
  220. template<typename _Alloc2, typename _Tp>
  221. static void
  222. _S_destroy(_Alloc2&, _Tp* __p, ...)
  223. noexcept(noexcept(__p->~_Tp()))
  224. { __p->~_Tp(); }
  225. template<typename _Alloc2>
  226. static auto
  227. _S_max_size(_Alloc2& __a, int)
  228. -> decltype(__a.max_size())
  229. { return __a.max_size(); }
  230. template<typename _Alloc2>
  231. static size_type
  232. _S_max_size(_Alloc2&, ...)
  233. {
  234. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  235. // 2466. allocator_traits::max_size() default behavior is incorrect
  236. return __gnu_cxx::__numeric_traits<size_type>::__max
  237. / sizeof(value_type);
  238. }
  239. template<typename _Alloc2>
  240. static auto
  241. _S_select(_Alloc2& __a, int)
  242. -> decltype(__a.select_on_container_copy_construction())
  243. { return __a.select_on_container_copy_construction(); }
  244. template<typename _Alloc2>
  245. static _Alloc2
  246. _S_select(_Alloc2& __a, ...)
  247. { return __a; }
  248. public:
  249. /**
  250. * @brief Allocate memory.
  251. * @param __a An allocator.
  252. * @param __n The number of objects to allocate space for.
  253. *
  254. * Calls @c a.allocate(n)
  255. */
  256. _GLIBCXX_NODISCARD static pointer
  257. allocate(_Alloc& __a, size_type __n)
  258. { return __a.allocate(__n); }
  259. /**
  260. * @brief Allocate memory.
  261. * @param __a An allocator.
  262. * @param __n The number of objects to allocate space for.
  263. * @param __hint Aid to locality.
  264. * @return Memory of suitable size and alignment for @a n objects
  265. * of type @c value_type
  266. *
  267. * Returns <tt> a.allocate(n, hint) </tt> if that expression is
  268. * well-formed, otherwise returns @c a.allocate(n)
  269. */
  270. _GLIBCXX_NODISCARD static pointer
  271. allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
  272. { return _S_allocate(__a, __n, __hint, 0); }
  273. /**
  274. * @brief Deallocate memory.
  275. * @param __a An allocator.
  276. * @param __p Pointer to the memory to deallocate.
  277. * @param __n The number of objects space was allocated for.
  278. *
  279. * Calls <tt> a.deallocate(p, n) </tt>
  280. */
  281. static void
  282. deallocate(_Alloc& __a, pointer __p, size_type __n)
  283. { __a.deallocate(__p, __n); }
  284. /**
  285. * @brief Construct an object of type @a _Tp
  286. * @param __a An allocator.
  287. * @param __p Pointer to memory of suitable size and alignment for Tp
  288. * @param __args Constructor arguments.
  289. *
  290. * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
  291. * if that expression is well-formed, otherwise uses placement-new
  292. * to construct an object of type @a _Tp at location @a __p from the
  293. * arguments @a __args...
  294. */
  295. template<typename _Tp, typename... _Args>
  296. static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
  297. noexcept(noexcept(_S_construct(__a, __p,
  298. std::forward<_Args>(__args)...)))
  299. -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
  300. { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
  301. /**
  302. * @brief Destroy an object of type @a _Tp
  303. * @param __a An allocator.
  304. * @param __p Pointer to the object to destroy
  305. *
  306. * Calls @c __a.destroy(__p) if that expression is well-formed,
  307. * otherwise calls @c __p->~_Tp()
  308. */
  309. template<typename _Tp>
  310. static void destroy(_Alloc& __a, _Tp* __p)
  311. noexcept(noexcept(_S_destroy(__a, __p, 0)))
  312. { _S_destroy(__a, __p, 0); }
  313. /**
  314. * @brief The maximum supported allocation size
  315. * @param __a An allocator.
  316. * @return @c __a.max_size() or @c numeric_limits<size_type>::max()
  317. *
  318. * Returns @c __a.max_size() if that expression is well-formed,
  319. * otherwise returns @c numeric_limits<size_type>::max()
  320. */
  321. static size_type max_size(const _Alloc& __a) noexcept
  322. { return _S_max_size(__a, 0); }
  323. /**
  324. * @brief Obtain an allocator to use when copying a container.
  325. * @param __rhs An allocator.
  326. * @return @c __rhs.select_on_container_copy_construction() or @a __rhs
  327. *
  328. * Returns @c __rhs.select_on_container_copy_construction() if that
  329. * expression is well-formed, otherwise returns @a __rhs
  330. */
  331. static _Alloc
  332. select_on_container_copy_construction(const _Alloc& __rhs)
  333. { return _S_select(__rhs, 0); }
  334. };
  335. /// Partial specialization for std::allocator.
  336. template<typename _Tp>
  337. struct allocator_traits<allocator<_Tp>>
  338. {
  339. /// The allocator type
  340. using allocator_type = allocator<_Tp>;
  341. /// The allocated type
  342. using value_type = _Tp;
  343. /// The allocator's pointer type.
  344. using pointer = _Tp*;
  345. /// The allocator's const pointer type.
  346. using const_pointer = const _Tp*;
  347. /// The allocator's void pointer type.
  348. using void_pointer = void*;
  349. /// The allocator's const void pointer type.
  350. using const_void_pointer = const void*;
  351. /// The allocator's difference type
  352. using difference_type = std::ptrdiff_t;
  353. /// The allocator's size type
  354. using size_type = std::size_t;
  355. /// How the allocator is propagated on copy assignment
  356. using propagate_on_container_copy_assignment = false_type;
  357. /// How the allocator is propagated on move assignment
  358. using propagate_on_container_move_assignment = true_type;
  359. /// How the allocator is propagated on swap
  360. using propagate_on_container_swap = false_type;
  361. /// Whether all instances of the allocator type compare equal.
  362. using is_always_equal = true_type;
  363. template<typename _Up>
  364. using rebind_alloc = allocator<_Up>;
  365. template<typename _Up>
  366. using rebind_traits = allocator_traits<allocator<_Up>>;
  367. /**
  368. * @brief Allocate memory.
  369. * @param __a An allocator.
  370. * @param __n The number of objects to allocate space for.
  371. *
  372. * Calls @c a.allocate(n)
  373. */
  374. _GLIBCXX_NODISCARD static pointer
  375. allocate(allocator_type& __a, size_type __n)
  376. { return __a.allocate(__n); }
  377. /**
  378. * @brief Allocate memory.
  379. * @param __a An allocator.
  380. * @param __n The number of objects to allocate space for.
  381. * @param __hint Aid to locality.
  382. * @return Memory of suitable size and alignment for @a n objects
  383. * of type @c value_type
  384. *
  385. * Returns <tt> a.allocate(n, hint) </tt>
  386. */
  387. _GLIBCXX_NODISCARD static pointer
  388. allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
  389. { return __a.allocate(__n, __hint); }
  390. /**
  391. * @brief Deallocate memory.
  392. * @param __a An allocator.
  393. * @param __p Pointer to the memory to deallocate.
  394. * @param __n The number of objects space was allocated for.
  395. *
  396. * Calls <tt> a.deallocate(p, n) </tt>
  397. */
  398. static void
  399. deallocate(allocator_type& __a, pointer __p, size_type __n)
  400. { __a.deallocate(__p, __n); }
  401. /**
  402. * @brief Construct an object of type @a _Up
  403. * @param __a An allocator.
  404. * @param __p Pointer to memory of suitable size and alignment for Tp
  405. * @param __args Constructor arguments.
  406. *
  407. * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
  408. */
  409. template<typename _Up, typename... _Args>
  410. static void
  411. construct(allocator_type& __a, _Up* __p, _Args&&... __args)
  412. noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
  413. { __a.construct(__p, std::forward<_Args>(__args)...); }
  414. /**
  415. * @brief Destroy an object of type @a _Up
  416. * @param __a An allocator.
  417. * @param __p Pointer to the object to destroy
  418. *
  419. * Calls @c __a.destroy(__p).
  420. */
  421. template<typename _Up>
  422. static void
  423. destroy(allocator_type& __a, _Up* __p)
  424. noexcept(noexcept(__a.destroy(__p)))
  425. { __a.destroy(__p); }
  426. /**
  427. * @brief The maximum supported allocation size
  428. * @param __a An allocator.
  429. * @return @c __a.max_size()
  430. */
  431. static size_type
  432. max_size(const allocator_type& __a) noexcept
  433. { return __a.max_size(); }
  434. /**
  435. * @brief Obtain an allocator to use when copying a container.
  436. * @param __rhs An allocator.
  437. * @return @c __rhs
  438. */
  439. static allocator_type
  440. select_on_container_copy_construction(const allocator_type& __rhs)
  441. { return __rhs; }
  442. };
  443. template<typename _Alloc>
  444. inline void
  445. __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
  446. { __one = __two; }
  447. template<typename _Alloc>
  448. inline void
  449. __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
  450. { }
  451. template<typename _Alloc>
  452. inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
  453. {
  454. typedef allocator_traits<_Alloc> __traits;
  455. typedef typename __traits::propagate_on_container_copy_assignment __pocca;
  456. __do_alloc_on_copy(__one, __two, __pocca());
  457. }
  458. template<typename _Alloc>
  459. inline _Alloc __alloc_on_copy(const _Alloc& __a)
  460. {
  461. typedef allocator_traits<_Alloc> __traits;
  462. return __traits::select_on_container_copy_construction(__a);
  463. }
  464. template<typename _Alloc>
  465. inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
  466. { __one = std::move(__two); }
  467. template<typename _Alloc>
  468. inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
  469. { }
  470. template<typename _Alloc>
  471. inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
  472. {
  473. typedef allocator_traits<_Alloc> __traits;
  474. typedef typename __traits::propagate_on_container_move_assignment __pocma;
  475. __do_alloc_on_move(__one, __two, __pocma());
  476. }
  477. template<typename _Alloc>
  478. inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
  479. {
  480. using std::swap;
  481. swap(__one, __two);
  482. }
  483. template<typename _Alloc>
  484. inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
  485. { }
  486. template<typename _Alloc>
  487. inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
  488. {
  489. typedef allocator_traits<_Alloc> __traits;
  490. typedef typename __traits::propagate_on_container_swap __pocs;
  491. __do_alloc_on_swap(__one, __two, __pocs());
  492. }
  493. template<typename _Alloc, typename _Tp,
  494. typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
  495. typename = void>
  496. struct __is_alloc_insertable_impl
  497. : false_type
  498. { };
  499. template<typename _Alloc, typename _Tp, typename _ValueT>
  500. struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
  501. __void_t<decltype(allocator_traits<_Alloc>::construct(
  502. std::declval<_Alloc&>(), std::declval<_ValueT*>(),
  503. std::declval<_Tp>()))>>
  504. : true_type
  505. { };
  506. // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
  507. // (might be wrong if _Alloc::construct exists but is not constrained,
  508. // i.e. actually trying to use it would still be invalid. Use with caution.)
  509. template<typename _Alloc>
  510. struct __is_copy_insertable
  511. : __is_alloc_insertable_impl<_Alloc,
  512. typename _Alloc::value_type const&>::type
  513. { };
  514. // std::allocator<_Tp> just requires CopyConstructible
  515. template<typename _Tp>
  516. struct __is_copy_insertable<allocator<_Tp>>
  517. : is_copy_constructible<_Tp>
  518. { };
  519. // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
  520. // (might be wrong if _Alloc::construct exists but is not constrained,
  521. // i.e. actually trying to use it would still be invalid. Use with caution.)
  522. template<typename _Alloc>
  523. struct __is_move_insertable
  524. : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
  525. { };
  526. // std::allocator<_Tp> just requires MoveConstructible
  527. template<typename _Tp>
  528. struct __is_move_insertable<allocator<_Tp>>
  529. : is_move_constructible<_Tp>
  530. { };
  531. // Trait to detect Allocator-like types.
  532. template<typename _Alloc, typename = void>
  533. struct __is_allocator : false_type { };
  534. template<typename _Alloc>
  535. struct __is_allocator<_Alloc,
  536. __void_t<typename _Alloc::value_type,
  537. decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
  538. : true_type { };
  539. template<typename _Alloc>
  540. using _RequireAllocator
  541. = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
  542. template<typename _Alloc>
  543. using _RequireNotAllocator
  544. = typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
  545. _GLIBCXX_END_NAMESPACE_VERSION
  546. } // namespace std
  547. #endif // C++11
  548. #endif // _ALLOC_TRAITS_H