Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

744 lines
24KB

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