You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1765 satır
59KB

  1. // <tuple> -*- C++ -*-
  2. // Copyright (C) 2007-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 include/tuple
  21. * This is a Standard C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_TUPLE
  24. #define _GLIBCXX_TUPLE 1
  25. #pragma GCC system_header
  26. #if __cplusplus < 201103L
  27. # include <bits/c++0x_warning.h>
  28. #else
  29. #include <utility>
  30. #include <array>
  31. #include <bits/uses_allocator.h>
  32. #include <bits/invoke.h>
  33. #if __cplusplus > 201703L
  34. # include <compare>
  35. # define __cpp_lib_constexpr_tuple 201811L
  36. #endif
  37. namespace std _GLIBCXX_VISIBILITY(default)
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. /**
  41. * @addtogroup utilities
  42. * @{
  43. */
  44. template<typename... _Elements>
  45. class tuple;
  46. template<typename _Tp>
  47. struct __is_empty_non_tuple : is_empty<_Tp> { };
  48. // Using EBO for elements that are tuples causes ambiguous base errors.
  49. template<typename _El0, typename... _El>
  50. struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
  51. // Use the Empty Base-class Optimization for empty, non-final types.
  52. template<typename _Tp>
  53. using __empty_not_final
  54. = typename conditional<__is_final(_Tp), false_type,
  55. __is_empty_non_tuple<_Tp>>::type;
  56. template<std::size_t _Idx, typename _Head,
  57. bool = __empty_not_final<_Head>::value>
  58. struct _Head_base;
  59. template<std::size_t _Idx, typename _Head>
  60. struct _Head_base<_Idx, _Head, true>
  61. : public _Head
  62. {
  63. constexpr _Head_base()
  64. : _Head() { }
  65. constexpr _Head_base(const _Head& __h)
  66. : _Head(__h) { }
  67. constexpr _Head_base(const _Head_base&) = default;
  68. constexpr _Head_base(_Head_base&&) = default;
  69. template<typename _UHead>
  70. constexpr _Head_base(_UHead&& __h)
  71. : _Head(std::forward<_UHead>(__h)) { }
  72. _Head_base(allocator_arg_t, __uses_alloc0)
  73. : _Head() { }
  74. template<typename _Alloc>
  75. _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
  76. : _Head(allocator_arg, *__a._M_a) { }
  77. template<typename _Alloc>
  78. _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
  79. : _Head(*__a._M_a) { }
  80. template<typename _UHead>
  81. _Head_base(__uses_alloc0, _UHead&& __uhead)
  82. : _Head(std::forward<_UHead>(__uhead)) { }
  83. template<typename _Alloc, typename _UHead>
  84. _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
  85. : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
  86. template<typename _Alloc, typename _UHead>
  87. _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
  88. : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
  89. static constexpr _Head&
  90. _M_head(_Head_base& __b) noexcept { return __b; }
  91. static constexpr const _Head&
  92. _M_head(const _Head_base& __b) noexcept { return __b; }
  93. };
  94. template<std::size_t _Idx, typename _Head>
  95. struct _Head_base<_Idx, _Head, false>
  96. {
  97. constexpr _Head_base()
  98. : _M_head_impl() { }
  99. constexpr _Head_base(const _Head& __h)
  100. : _M_head_impl(__h) { }
  101. constexpr _Head_base(const _Head_base&) = default;
  102. constexpr _Head_base(_Head_base&&) = default;
  103. template<typename _UHead>
  104. constexpr _Head_base(_UHead&& __h)
  105. : _M_head_impl(std::forward<_UHead>(__h)) { }
  106. _GLIBCXX20_CONSTEXPR
  107. _Head_base(allocator_arg_t, __uses_alloc0)
  108. : _M_head_impl() { }
  109. template<typename _Alloc>
  110. _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
  111. : _M_head_impl(allocator_arg, *__a._M_a) { }
  112. template<typename _Alloc>
  113. _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
  114. : _M_head_impl(*__a._M_a) { }
  115. template<typename _UHead>
  116. _GLIBCXX20_CONSTEXPR
  117. _Head_base(__uses_alloc0, _UHead&& __uhead)
  118. : _M_head_impl(std::forward<_UHead>(__uhead)) { }
  119. template<typename _Alloc, typename _UHead>
  120. _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
  121. : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
  122. { }
  123. template<typename _Alloc, typename _UHead>
  124. _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
  125. : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
  126. static constexpr _Head&
  127. _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
  128. static constexpr const _Head&
  129. _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
  130. _Head _M_head_impl;
  131. };
  132. /**
  133. * Contains the actual implementation of the @c tuple template, stored
  134. * as a recursive inheritance hierarchy from the first element (most
  135. * derived class) to the last (least derived class). The @c Idx
  136. * parameter gives the 0-based index of the element stored at this
  137. * point in the hierarchy; we use it to implement a constant-time
  138. * get() operation.
  139. */
  140. template<std::size_t _Idx, typename... _Elements>
  141. struct _Tuple_impl;
  142. /**
  143. * Recursive tuple implementation. Here we store the @c Head element
  144. * and derive from a @c Tuple_impl containing the remaining elements
  145. * (which contains the @c Tail).
  146. */
  147. template<std::size_t _Idx, typename _Head, typename... _Tail>
  148. struct _Tuple_impl<_Idx, _Head, _Tail...>
  149. : public _Tuple_impl<_Idx + 1, _Tail...>,
  150. private _Head_base<_Idx, _Head>
  151. {
  152. template<std::size_t, typename...> friend class _Tuple_impl;
  153. typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
  154. typedef _Head_base<_Idx, _Head> _Base;
  155. static constexpr _Head&
  156. _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
  157. static constexpr const _Head&
  158. _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
  159. static constexpr _Inherited&
  160. _M_tail(_Tuple_impl& __t) noexcept { return __t; }
  161. static constexpr const _Inherited&
  162. _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
  163. constexpr _Tuple_impl()
  164. : _Inherited(), _Base() { }
  165. explicit
  166. constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
  167. : _Inherited(__tail...), _Base(__head) { }
  168. template<typename _UHead, typename... _UTail, typename = typename
  169. enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
  170. explicit
  171. constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
  172. : _Inherited(std::forward<_UTail>(__tail)...),
  173. _Base(std::forward<_UHead>(__head)) { }
  174. constexpr _Tuple_impl(const _Tuple_impl&) = default;
  175. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  176. // 2729. Missing SFINAE on std::pair::operator=
  177. _Tuple_impl& operator=(const _Tuple_impl&) = delete;
  178. constexpr
  179. _Tuple_impl(_Tuple_impl&& __in)
  180. noexcept(__and_<is_nothrow_move_constructible<_Head>,
  181. is_nothrow_move_constructible<_Inherited>>::value)
  182. : _Inherited(std::move(_M_tail(__in))),
  183. _Base(std::forward<_Head>(_M_head(__in))) { }
  184. template<typename... _UElements>
  185. constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
  186. : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
  187. _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
  188. template<typename _UHead, typename... _UTails>
  189. constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
  190. : _Inherited(std::move
  191. (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
  192. _Base(std::forward<_UHead>
  193. (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
  194. template<typename _Alloc>
  195. _GLIBCXX20_CONSTEXPR
  196. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
  197. : _Inherited(__tag, __a),
  198. _Base(__tag, __use_alloc<_Head>(__a)) { }
  199. template<typename _Alloc>
  200. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  201. const _Head& __head, const _Tail&... __tail)
  202. : _Inherited(__tag, __a, __tail...),
  203. _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
  204. template<typename _Alloc, typename _UHead, typename... _UTail,
  205. typename = typename enable_if<sizeof...(_Tail)
  206. == sizeof...(_UTail)>::type>
  207. _GLIBCXX20_CONSTEXPR
  208. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  209. _UHead&& __head, _UTail&&... __tail)
  210. : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
  211. _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
  212. std::forward<_UHead>(__head)) { }
  213. template<typename _Alloc>
  214. _GLIBCXX20_CONSTEXPR
  215. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  216. const _Tuple_impl& __in)
  217. : _Inherited(__tag, __a, _M_tail(__in)),
  218. _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
  219. template<typename _Alloc>
  220. _GLIBCXX20_CONSTEXPR
  221. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  222. _Tuple_impl&& __in)
  223. : _Inherited(__tag, __a, std::move(_M_tail(__in))),
  224. _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
  225. std::forward<_Head>(_M_head(__in))) { }
  226. template<typename _Alloc, typename _UHead, typename... _UTails>
  227. _GLIBCXX20_CONSTEXPR
  228. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  229. const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
  230. : _Inherited(__tag, __a,
  231. _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
  232. _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
  233. _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) { }
  234. template<typename _Alloc, typename _UHead, typename... _UTails>
  235. _GLIBCXX20_CONSTEXPR
  236. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  237. _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
  238. : _Inherited(__tag, __a, std::move
  239. (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
  240. _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
  241. std::forward<_UHead>
  242. (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
  243. template<typename... _UElements>
  244. _GLIBCXX20_CONSTEXPR
  245. void
  246. _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
  247. {
  248. _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
  249. _M_tail(*this)._M_assign(
  250. _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
  251. }
  252. template<typename _UHead, typename... _UTails>
  253. _GLIBCXX20_CONSTEXPR
  254. void
  255. _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
  256. {
  257. _M_head(*this) = std::forward<_UHead>
  258. (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
  259. _M_tail(*this)._M_assign(
  260. std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
  261. }
  262. protected:
  263. _GLIBCXX20_CONSTEXPR
  264. void
  265. _M_swap(_Tuple_impl& __in)
  266. {
  267. using std::swap;
  268. swap(_M_head(*this), _M_head(__in));
  269. _Inherited::_M_swap(_M_tail(__in));
  270. }
  271. };
  272. // Basis case of inheritance recursion.
  273. template<std::size_t _Idx, typename _Head>
  274. struct _Tuple_impl<_Idx, _Head>
  275. : private _Head_base<_Idx, _Head>
  276. {
  277. template<std::size_t, typename...> friend class _Tuple_impl;
  278. typedef _Head_base<_Idx, _Head> _Base;
  279. static constexpr _Head&
  280. _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
  281. static constexpr const _Head&
  282. _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
  283. constexpr _Tuple_impl()
  284. : _Base() { }
  285. explicit
  286. constexpr _Tuple_impl(const _Head& __head)
  287. : _Base(__head) { }
  288. template<typename _UHead>
  289. explicit
  290. constexpr _Tuple_impl(_UHead&& __head)
  291. : _Base(std::forward<_UHead>(__head)) { }
  292. constexpr _Tuple_impl(const _Tuple_impl&) = default;
  293. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  294. // 2729. Missing SFINAE on std::pair::operator=
  295. _Tuple_impl& operator=(const _Tuple_impl&) = delete;
  296. constexpr
  297. _Tuple_impl(_Tuple_impl&& __in)
  298. noexcept(is_nothrow_move_constructible<_Head>::value)
  299. : _Base(std::forward<_Head>(_M_head(__in))) { }
  300. template<typename _UHead>
  301. constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
  302. : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
  303. template<typename _UHead>
  304. constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
  305. : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
  306. { }
  307. template<typename _Alloc>
  308. _GLIBCXX20_CONSTEXPR
  309. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
  310. : _Base(__tag, __use_alloc<_Head>(__a)) { }
  311. template<typename _Alloc>
  312. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  313. const _Head& __head)
  314. : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
  315. template<typename _Alloc, typename _UHead>
  316. _GLIBCXX20_CONSTEXPR
  317. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  318. _UHead&& __head)
  319. : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
  320. std::forward<_UHead>(__head)) { }
  321. template<typename _Alloc>
  322. _GLIBCXX20_CONSTEXPR
  323. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  324. const _Tuple_impl& __in)
  325. : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
  326. template<typename _Alloc>
  327. _GLIBCXX20_CONSTEXPR
  328. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  329. _Tuple_impl&& __in)
  330. : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
  331. std::forward<_Head>(_M_head(__in))) { }
  332. template<typename _Alloc, typename _UHead>
  333. _GLIBCXX20_CONSTEXPR
  334. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  335. const _Tuple_impl<_Idx, _UHead>& __in)
  336. : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
  337. _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
  338. template<typename _Alloc, typename _UHead>
  339. _GLIBCXX20_CONSTEXPR
  340. _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
  341. _Tuple_impl<_Idx, _UHead>&& __in)
  342. : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
  343. std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
  344. { }
  345. template<typename _UHead>
  346. _GLIBCXX20_CONSTEXPR
  347. void
  348. _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
  349. {
  350. _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
  351. }
  352. template<typename _UHead>
  353. _GLIBCXX20_CONSTEXPR
  354. void
  355. _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
  356. {
  357. _M_head(*this)
  358. = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
  359. }
  360. protected:
  361. _GLIBCXX20_CONSTEXPR
  362. void
  363. _M_swap(_Tuple_impl& __in)
  364. {
  365. using std::swap;
  366. swap(_M_head(*this), _M_head(__in));
  367. }
  368. };
  369. // Concept utility functions, reused in conditionally-explicit
  370. // constructors.
  371. template<bool, typename... _Types>
  372. struct _TupleConstraints
  373. {
  374. // Constraint for a non-explicit constructor.
  375. // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
  376. // and every Ui is implicitly convertible to Ti.
  377. template<typename... _UTypes>
  378. static constexpr bool __is_implicitly_constructible()
  379. {
  380. return __and_<is_constructible<_Types, _UTypes>...,
  381. is_convertible<_UTypes, _Types>...
  382. >::value;
  383. }
  384. // Constraint for a non-explicit constructor.
  385. // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
  386. // but not every Ui is implicitly convertible to Ti.
  387. template<typename... _UTypes>
  388. static constexpr bool __is_explicitly_constructible()
  389. {
  390. return __and_<is_constructible<_Types, _UTypes>...,
  391. __not_<__and_<is_convertible<_UTypes, _Types>...>>
  392. >::value;
  393. }
  394. static constexpr bool __is_implicitly_default_constructible()
  395. {
  396. return __and_<std::__is_implicitly_default_constructible<_Types>...
  397. >::value;
  398. }
  399. static constexpr bool __is_explicitly_default_constructible()
  400. {
  401. return __and_<is_default_constructible<_Types>...,
  402. __not_<__and_<
  403. std::__is_implicitly_default_constructible<_Types>...>
  404. >>::value;
  405. }
  406. };
  407. // Partial specialization used when a required precondition isn't met,
  408. // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
  409. template<typename... _Types>
  410. struct _TupleConstraints<false, _Types...>
  411. {
  412. template<typename... _UTypes>
  413. static constexpr bool __is_implicitly_constructible()
  414. { return false; }
  415. template<typename... _UTypes>
  416. static constexpr bool __is_explicitly_constructible()
  417. { return false; }
  418. };
  419. /// Primary class template, tuple
  420. template<typename... _Elements>
  421. class tuple : public _Tuple_impl<0, _Elements...>
  422. {
  423. typedef _Tuple_impl<0, _Elements...> _Inherited;
  424. template<bool _Cond>
  425. using _TCC = _TupleConstraints<_Cond, _Elements...>;
  426. // Constraint for non-explicit default constructor
  427. template<bool _Dummy>
  428. using _ImplicitDefaultCtor = __enable_if_t<
  429. _TCC<_Dummy>::__is_implicitly_default_constructible(),
  430. bool>;
  431. // Constraint for explicit default constructor
  432. template<bool _Dummy>
  433. using _ExplicitDefaultCtor = __enable_if_t<
  434. _TCC<_Dummy>::__is_explicitly_default_constructible(),
  435. bool>;
  436. // Constraint for non-explicit constructors
  437. template<bool _Cond, typename... _Args>
  438. using _ImplicitCtor = __enable_if_t<
  439. _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
  440. bool>;
  441. // Constraint for non-explicit constructors
  442. template<bool _Cond, typename... _Args>
  443. using _ExplicitCtor = __enable_if_t<
  444. _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
  445. bool>;
  446. template<typename... _UElements>
  447. static constexpr
  448. __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
  449. __assignable()
  450. { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
  451. // Condition for noexcept-specifier of an assignment operator.
  452. template<typename... _UElements>
  453. static constexpr bool __nothrow_assignable()
  454. {
  455. return
  456. __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
  457. }
  458. // Condition for noexcept-specifier of a constructor.
  459. template<typename... _UElements>
  460. static constexpr bool __nothrow_constructible()
  461. {
  462. return
  463. __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
  464. }
  465. // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
  466. template<typename _Up>
  467. static constexpr bool __valid_args()
  468. {
  469. return sizeof...(_Elements) == 1
  470. && !is_same<tuple, __remove_cvref_t<_Up>>::value;
  471. }
  472. // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
  473. template<typename, typename, typename... _Tail>
  474. static constexpr bool __valid_args()
  475. { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
  476. /* Constraint for constructors with a tuple<UTypes...> parameter ensures
  477. * that the constructor is only viable when it would not interfere with
  478. * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
  479. * Such constructors are only viable if:
  480. * either sizeof...(Types) != 1,
  481. * or (when Types... expands to T and UTypes... expands to U)
  482. * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
  483. * and is_same_v<T, U> are all false.
  484. */
  485. template<typename _Tuple, typename = tuple,
  486. typename = __remove_cvref_t<_Tuple>>
  487. struct _UseOtherCtor
  488. : false_type
  489. { };
  490. // If TUPLE is convertible to the single element in *this,
  491. // then TUPLE should match tuple(UTypes&&...) instead.
  492. template<typename _Tuple, typename _Tp, typename _Up>
  493. struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
  494. : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
  495. { };
  496. // If TUPLE and *this each have a single element of the same type,
  497. // then TUPLE should match a copy/move constructor instead.
  498. template<typename _Tuple, typename _Tp>
  499. struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
  500. : true_type
  501. { };
  502. // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
  503. // and the single element in Types can be initialized from TUPLE,
  504. // or is the same type as tuple_element_t<0, TUPLE>.
  505. template<typename _Tuple>
  506. static constexpr bool __use_other_ctor()
  507. { return _UseOtherCtor<_Tuple>::value; }
  508. public:
  509. template<typename _Dummy = void,
  510. _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
  511. constexpr
  512. tuple()
  513. noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
  514. : _Inherited() { }
  515. template<typename _Dummy = void,
  516. _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
  517. explicit constexpr
  518. tuple()
  519. noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
  520. : _Inherited() { }
  521. template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
  522. _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
  523. constexpr
  524. tuple(const _Elements&... __elements)
  525. noexcept(__nothrow_constructible<const _Elements&...>())
  526. : _Inherited(__elements...) { }
  527. template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
  528. _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
  529. explicit constexpr
  530. tuple(const _Elements&... __elements)
  531. noexcept(__nothrow_constructible<const _Elements&...>())
  532. : _Inherited(__elements...) { }
  533. template<typename... _UElements,
  534. bool _Valid = __valid_args<_UElements...>(),
  535. _ImplicitCtor<_Valid, _UElements...> = true>
  536. constexpr
  537. tuple(_UElements&&... __elements)
  538. noexcept(__nothrow_constructible<_UElements...>())
  539. : _Inherited(std::forward<_UElements>(__elements)...) { }
  540. template<typename... _UElements,
  541. bool _Valid = __valid_args<_UElements...>(),
  542. _ExplicitCtor<_Valid, _UElements...> = false>
  543. explicit constexpr
  544. tuple(_UElements&&... __elements)
  545. noexcept(__nothrow_constructible<_UElements...>())
  546. : _Inherited(std::forward<_UElements>(__elements)...) { }
  547. constexpr tuple(const tuple&) = default;
  548. constexpr tuple(tuple&&) = default;
  549. template<typename... _UElements,
  550. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  551. && !__use_other_ctor<const tuple<_UElements...>&>(),
  552. _ImplicitCtor<_Valid, const _UElements&...> = true>
  553. constexpr
  554. tuple(const tuple<_UElements...>& __in)
  555. noexcept(__nothrow_constructible<const _UElements&...>())
  556. : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  557. { }
  558. template<typename... _UElements,
  559. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  560. && !__use_other_ctor<const tuple<_UElements...>&>(),
  561. _ExplicitCtor<_Valid, const _UElements&...> = false>
  562. explicit constexpr
  563. tuple(const tuple<_UElements...>& __in)
  564. noexcept(__nothrow_constructible<const _UElements&...>())
  565. : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  566. { }
  567. template<typename... _UElements,
  568. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  569. && !__use_other_ctor<tuple<_UElements...>&&>(),
  570. _ImplicitCtor<_Valid, _UElements...> = true>
  571. constexpr
  572. tuple(tuple<_UElements...>&& __in)
  573. noexcept(__nothrow_constructible<_UElements...>())
  574. : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
  575. template<typename... _UElements,
  576. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  577. && !__use_other_ctor<tuple<_UElements...>&&>(),
  578. _ExplicitCtor<_Valid, _UElements...> = false>
  579. explicit constexpr
  580. tuple(tuple<_UElements...>&& __in)
  581. noexcept(__nothrow_constructible<_UElements...>())
  582. : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
  583. // Allocator-extended constructors.
  584. template<typename _Alloc,
  585. _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
  586. _GLIBCXX20_CONSTEXPR
  587. tuple(allocator_arg_t __tag, const _Alloc& __a)
  588. : _Inherited(__tag, __a) { }
  589. template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
  590. _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
  591. _GLIBCXX20_CONSTEXPR
  592. tuple(allocator_arg_t __tag, const _Alloc& __a,
  593. const _Elements&... __elements)
  594. : _Inherited(__tag, __a, __elements...) { }
  595. template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
  596. _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
  597. _GLIBCXX20_CONSTEXPR
  598. explicit
  599. tuple(allocator_arg_t __tag, const _Alloc& __a,
  600. const _Elements&... __elements)
  601. : _Inherited(__tag, __a, __elements...) { }
  602. template<typename _Alloc, typename... _UElements,
  603. bool _Valid = __valid_args<_UElements...>(),
  604. _ImplicitCtor<_Valid, _UElements...> = true>
  605. _GLIBCXX20_CONSTEXPR
  606. tuple(allocator_arg_t __tag, const _Alloc& __a,
  607. _UElements&&... __elements)
  608. : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
  609. { }
  610. template<typename _Alloc, typename... _UElements,
  611. bool _Valid = __valid_args<_UElements...>(),
  612. _ExplicitCtor<_Valid, _UElements...> = false>
  613. _GLIBCXX20_CONSTEXPR
  614. explicit
  615. tuple(allocator_arg_t __tag, const _Alloc& __a,
  616. _UElements&&... __elements)
  617. : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
  618. { }
  619. template<typename _Alloc>
  620. _GLIBCXX20_CONSTEXPR
  621. tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
  622. : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
  623. template<typename _Alloc>
  624. _GLIBCXX20_CONSTEXPR
  625. tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
  626. : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
  627. template<typename _Alloc, typename... _UElements,
  628. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  629. && !__use_other_ctor<const tuple<_UElements...>&>(),
  630. _ImplicitCtor<_Valid, const _UElements&...> = true>
  631. _GLIBCXX20_CONSTEXPR
  632. tuple(allocator_arg_t __tag, const _Alloc& __a,
  633. const tuple<_UElements...>& __in)
  634. : _Inherited(__tag, __a,
  635. static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  636. { }
  637. template<typename _Alloc, typename... _UElements,
  638. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  639. && !__use_other_ctor<const tuple<_UElements...>&>(),
  640. _ExplicitCtor<_Valid, const _UElements&...> = false>
  641. _GLIBCXX20_CONSTEXPR
  642. explicit
  643. tuple(allocator_arg_t __tag, const _Alloc& __a,
  644. const tuple<_UElements...>& __in)
  645. : _Inherited(__tag, __a,
  646. static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  647. { }
  648. template<typename _Alloc, typename... _UElements,
  649. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  650. && !__use_other_ctor<tuple<_UElements...>&&>(),
  651. _ImplicitCtor<_Valid, _UElements...> = true>
  652. _GLIBCXX20_CONSTEXPR
  653. tuple(allocator_arg_t __tag, const _Alloc& __a,
  654. tuple<_UElements...>&& __in)
  655. : _Inherited(__tag, __a,
  656. static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
  657. { }
  658. template<typename _Alloc, typename... _UElements,
  659. bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
  660. && !__use_other_ctor<tuple<_UElements...>&&>(),
  661. _ExplicitCtor<_Valid, _UElements...> = false>
  662. _GLIBCXX20_CONSTEXPR
  663. explicit
  664. tuple(allocator_arg_t __tag, const _Alloc& __a,
  665. tuple<_UElements...>&& __in)
  666. : _Inherited(__tag, __a,
  667. static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
  668. { }
  669. // tuple assignment
  670. _GLIBCXX20_CONSTEXPR
  671. tuple&
  672. operator=(typename conditional<__assignable<const _Elements&...>(),
  673. const tuple&,
  674. const __nonesuch&>::type __in)
  675. noexcept(__nothrow_assignable<const _Elements&...>())
  676. {
  677. this->_M_assign(__in);
  678. return *this;
  679. }
  680. _GLIBCXX20_CONSTEXPR
  681. tuple&
  682. operator=(typename conditional<__assignable<_Elements...>(),
  683. tuple&&,
  684. __nonesuch&&>::type __in)
  685. noexcept(__nothrow_assignable<_Elements...>())
  686. {
  687. this->_M_assign(std::move(__in));
  688. return *this;
  689. }
  690. template<typename... _UElements>
  691. _GLIBCXX20_CONSTEXPR
  692. __enable_if_t<__assignable<const _UElements&...>(), tuple&>
  693. operator=(const tuple<_UElements...>& __in)
  694. noexcept(__nothrow_assignable<const _UElements&...>())
  695. {
  696. this->_M_assign(__in);
  697. return *this;
  698. }
  699. template<typename... _UElements>
  700. _GLIBCXX20_CONSTEXPR
  701. __enable_if_t<__assignable<_UElements...>(), tuple&>
  702. operator=(tuple<_UElements...>&& __in)
  703. noexcept(__nothrow_assignable<_UElements...>())
  704. {
  705. this->_M_assign(std::move(__in));
  706. return *this;
  707. }
  708. // tuple swap
  709. _GLIBCXX20_CONSTEXPR
  710. void
  711. swap(tuple& __in)
  712. noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
  713. { _Inherited::_M_swap(__in); }
  714. };
  715. #if __cpp_deduction_guides >= 201606
  716. template<typename... _UTypes>
  717. tuple(_UTypes...) -> tuple<_UTypes...>;
  718. template<typename _T1, typename _T2>
  719. tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
  720. template<typename _Alloc, typename... _UTypes>
  721. tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
  722. template<typename _Alloc, typename _T1, typename _T2>
  723. tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
  724. template<typename _Alloc, typename... _UTypes>
  725. tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
  726. #endif
  727. // Explicit specialization, zero-element tuple.
  728. template<>
  729. class tuple<>
  730. {
  731. public:
  732. void swap(tuple&) noexcept { /* no-op */ }
  733. // We need the default since we're going to define no-op
  734. // allocator constructors.
  735. tuple() = default;
  736. // No-op allocator constructors.
  737. template<typename _Alloc>
  738. _GLIBCXX20_CONSTEXPR
  739. tuple(allocator_arg_t, const _Alloc&) noexcept { }
  740. template<typename _Alloc>
  741. _GLIBCXX20_CONSTEXPR
  742. tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
  743. };
  744. /// Partial specialization, 2-element tuple.
  745. /// Includes construction and assignment from a pair.
  746. template<typename _T1, typename _T2>
  747. class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
  748. {
  749. typedef _Tuple_impl<0, _T1, _T2> _Inherited;
  750. // Constraint for non-explicit default constructor
  751. template<bool _Dummy, typename _U1, typename _U2>
  752. using _ImplicitDefaultCtor = __enable_if_t<
  753. _TupleConstraints<_Dummy, _U1, _U2>::
  754. __is_implicitly_default_constructible(),
  755. bool>;
  756. // Constraint for explicit default constructor
  757. template<bool _Dummy, typename _U1, typename _U2>
  758. using _ExplicitDefaultCtor = __enable_if_t<
  759. _TupleConstraints<_Dummy, _U1, _U2>::
  760. __is_explicitly_default_constructible(),
  761. bool>;
  762. template<bool _Dummy>
  763. using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
  764. // Constraint for non-explicit constructors
  765. template<bool _Cond, typename _U1, typename _U2>
  766. using _ImplicitCtor = __enable_if_t<
  767. _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
  768. bool>;
  769. // Constraint for non-explicit constructors
  770. template<bool _Cond, typename _U1, typename _U2>
  771. using _ExplicitCtor = __enable_if_t<
  772. _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
  773. bool>;
  774. template<typename _U1, typename _U2>
  775. static constexpr bool __assignable()
  776. {
  777. return __and_<is_assignable<_T1&, _U1>,
  778. is_assignable<_T2&, _U2>>::value;
  779. }
  780. template<typename _U1, typename _U2>
  781. static constexpr bool __nothrow_assignable()
  782. {
  783. return __and_<is_nothrow_assignable<_T1&, _U1>,
  784. is_nothrow_assignable<_T2&, _U2>>::value;
  785. }
  786. template<typename _U1, typename _U2>
  787. static constexpr bool __nothrow_constructible()
  788. {
  789. return __and_<is_nothrow_constructible<_T1, _U1>,
  790. is_nothrow_constructible<_T2, _U2>>::value;
  791. }
  792. static constexpr bool __nothrow_default_constructible()
  793. {
  794. return __and_<is_nothrow_default_constructible<_T1>,
  795. is_nothrow_default_constructible<_T2>>::value;
  796. }
  797. template<typename _U1>
  798. static constexpr bool __is_alloc_arg()
  799. { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
  800. public:
  801. template<bool _Dummy = true,
  802. _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
  803. constexpr
  804. tuple()
  805. noexcept(__nothrow_default_constructible())
  806. : _Inherited() { }
  807. template<bool _Dummy = true,
  808. _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
  809. explicit constexpr
  810. tuple()
  811. noexcept(__nothrow_default_constructible())
  812. : _Inherited() { }
  813. template<bool _Dummy = true,
  814. _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
  815. constexpr
  816. tuple(const _T1& __a1, const _T2& __a2)
  817. noexcept(__nothrow_constructible<const _T1&, const _T2&>())
  818. : _Inherited(__a1, __a2) { }
  819. template<bool _Dummy = true,
  820. _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
  821. explicit constexpr
  822. tuple(const _T1& __a1, const _T2& __a2)
  823. noexcept(__nothrow_constructible<const _T1&, const _T2&>())
  824. : _Inherited(__a1, __a2) { }
  825. template<typename _U1, typename _U2,
  826. _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
  827. constexpr
  828. tuple(_U1&& __a1, _U2&& __a2)
  829. noexcept(__nothrow_constructible<_U1, _U2>())
  830. : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
  831. template<typename _U1, typename _U2,
  832. _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
  833. explicit constexpr
  834. tuple(_U1&& __a1, _U2&& __a2)
  835. noexcept(__nothrow_constructible<_U1, _U2>())
  836. : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
  837. constexpr tuple(const tuple&) = default;
  838. constexpr tuple(tuple&&) = default;
  839. template<typename _U1, typename _U2,
  840. _ImplicitCtor<true, const _U1&, const _U2&> = true>
  841. constexpr
  842. tuple(const tuple<_U1, _U2>& __in)
  843. noexcept(__nothrow_constructible<const _U1&, const _U2&>())
  844. : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
  845. template<typename _U1, typename _U2,
  846. _ExplicitCtor<true, const _U1&, const _U2&> = false>
  847. explicit constexpr
  848. tuple(const tuple<_U1, _U2>& __in)
  849. noexcept(__nothrow_constructible<const _U1&, const _U2&>())
  850. : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
  851. template<typename _U1, typename _U2,
  852. _ImplicitCtor<true, _U1, _U2> = true>
  853. constexpr
  854. tuple(tuple<_U1, _U2>&& __in)
  855. noexcept(__nothrow_constructible<_U1, _U2>())
  856. : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
  857. template<typename _U1, typename _U2,
  858. _ExplicitCtor<true, _U1, _U2> = false>
  859. explicit constexpr
  860. tuple(tuple<_U1, _U2>&& __in)
  861. noexcept(__nothrow_constructible<_U1, _U2>())
  862. : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
  863. template<typename _U1, typename _U2,
  864. _ImplicitCtor<true, const _U1&, const _U2&> = true>
  865. constexpr
  866. tuple(const pair<_U1, _U2>& __in)
  867. noexcept(__nothrow_constructible<const _U1&, const _U2&>())
  868. : _Inherited(__in.first, __in.second) { }
  869. template<typename _U1, typename _U2,
  870. _ExplicitCtor<true, const _U1&, const _U2&> = false>
  871. explicit constexpr
  872. tuple(const pair<_U1, _U2>& __in)
  873. noexcept(__nothrow_constructible<const _U1&, const _U2&>())
  874. : _Inherited(__in.first, __in.second) { }
  875. template<typename _U1, typename _U2,
  876. _ImplicitCtor<true, _U1, _U2> = true>
  877. constexpr
  878. tuple(pair<_U1, _U2>&& __in)
  879. noexcept(__nothrow_constructible<_U1, _U2>())
  880. : _Inherited(std::forward<_U1>(__in.first),
  881. std::forward<_U2>(__in.second)) { }
  882. template<typename _U1, typename _U2,
  883. _ExplicitCtor<true, _U1, _U2> = false>
  884. explicit constexpr
  885. tuple(pair<_U1, _U2>&& __in)
  886. noexcept(__nothrow_constructible<_U1, _U2>())
  887. : _Inherited(std::forward<_U1>(__in.first),
  888. std::forward<_U2>(__in.second)) { }
  889. // Allocator-extended constructors.
  890. template<typename _Alloc,
  891. _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
  892. _GLIBCXX20_CONSTEXPR
  893. tuple(allocator_arg_t __tag, const _Alloc& __a)
  894. : _Inherited(__tag, __a) { }
  895. template<typename _Alloc, bool _Dummy = true,
  896. _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
  897. _GLIBCXX20_CONSTEXPR
  898. tuple(allocator_arg_t __tag, const _Alloc& __a,
  899. const _T1& __a1, const _T2& __a2)
  900. : _Inherited(__tag, __a, __a1, __a2) { }
  901. template<typename _Alloc, bool _Dummy = true,
  902. _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
  903. explicit
  904. _GLIBCXX20_CONSTEXPR
  905. tuple(allocator_arg_t __tag, const _Alloc& __a,
  906. const _T1& __a1, const _T2& __a2)
  907. : _Inherited(__tag, __a, __a1, __a2) { }
  908. template<typename _Alloc, typename _U1, typename _U2,
  909. _ImplicitCtor<true, _U1, _U2> = true>
  910. _GLIBCXX20_CONSTEXPR
  911. tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
  912. : _Inherited(__tag, __a, std::forward<_U1>(__a1),
  913. std::forward<_U2>(__a2)) { }
  914. template<typename _Alloc, typename _U1, typename _U2,
  915. _ExplicitCtor<true, _U1, _U2> = false>
  916. explicit
  917. _GLIBCXX20_CONSTEXPR
  918. tuple(allocator_arg_t __tag, const _Alloc& __a,
  919. _U1&& __a1, _U2&& __a2)
  920. : _Inherited(__tag, __a, std::forward<_U1>(__a1),
  921. std::forward<_U2>(__a2)) { }
  922. template<typename _Alloc>
  923. _GLIBCXX20_CONSTEXPR
  924. tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
  925. : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
  926. template<typename _Alloc>
  927. _GLIBCXX20_CONSTEXPR
  928. tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
  929. : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
  930. template<typename _Alloc, typename _U1, typename _U2,
  931. _ImplicitCtor<true, const _U1&, const _U2&> = true>
  932. _GLIBCXX20_CONSTEXPR
  933. tuple(allocator_arg_t __tag, const _Alloc& __a,
  934. const tuple<_U1, _U2>& __in)
  935. : _Inherited(__tag, __a,
  936. static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
  937. { }
  938. template<typename _Alloc, typename _U1, typename _U2,
  939. _ExplicitCtor<true, const _U1&, const _U2&> = false>
  940. explicit
  941. _GLIBCXX20_CONSTEXPR
  942. tuple(allocator_arg_t __tag, const _Alloc& __a,
  943. const tuple<_U1, _U2>& __in)
  944. : _Inherited(__tag, __a,
  945. static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
  946. { }
  947. template<typename _Alloc, typename _U1, typename _U2,
  948. _ImplicitCtor<true, _U1, _U2> = true>
  949. _GLIBCXX20_CONSTEXPR
  950. tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
  951. : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
  952. { }
  953. template<typename _Alloc, typename _U1, typename _U2,
  954. _ExplicitCtor<true, _U1, _U2> = false>
  955. explicit
  956. _GLIBCXX20_CONSTEXPR
  957. tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
  958. : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
  959. { }
  960. template<typename _Alloc, typename _U1, typename _U2,
  961. _ImplicitCtor<true, const _U1&, const _U2&> = true>
  962. _GLIBCXX20_CONSTEXPR
  963. tuple(allocator_arg_t __tag, const _Alloc& __a,
  964. const pair<_U1, _U2>& __in)
  965. : _Inherited(__tag, __a, __in.first, __in.second) { }
  966. template<typename _Alloc, typename _U1, typename _U2,
  967. _ExplicitCtor<true, const _U1&, const _U2&> = false>
  968. explicit
  969. _GLIBCXX20_CONSTEXPR
  970. tuple(allocator_arg_t __tag, const _Alloc& __a,
  971. const pair<_U1, _U2>& __in)
  972. : _Inherited(__tag, __a, __in.first, __in.second) { }
  973. template<typename _Alloc, typename _U1, typename _U2,
  974. _ImplicitCtor<true, _U1, _U2> = true>
  975. _GLIBCXX20_CONSTEXPR
  976. tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
  977. : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
  978. std::forward<_U2>(__in.second)) { }
  979. template<typename _Alloc, typename _U1, typename _U2,
  980. _ExplicitCtor<true, _U1, _U2> = false>
  981. explicit
  982. _GLIBCXX20_CONSTEXPR
  983. tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
  984. : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
  985. std::forward<_U2>(__in.second)) { }
  986. // Tuple assignment.
  987. _GLIBCXX20_CONSTEXPR
  988. tuple&
  989. operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
  990. const tuple&,
  991. const __nonesuch&>::type __in)
  992. noexcept(__nothrow_assignable<const _T1&, const _T2&>())
  993. {
  994. this->_M_assign(__in);
  995. return *this;
  996. }
  997. _GLIBCXX20_CONSTEXPR
  998. tuple&
  999. operator=(typename conditional<__assignable<_T1, _T2>(),
  1000. tuple&&,
  1001. __nonesuch&&>::type __in)
  1002. noexcept(__nothrow_assignable<_T1, _T2>())
  1003. {
  1004. this->_M_assign(std::move(__in));
  1005. return *this;
  1006. }
  1007. template<typename _U1, typename _U2>
  1008. _GLIBCXX20_CONSTEXPR
  1009. __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
  1010. operator=(const tuple<_U1, _U2>& __in)
  1011. noexcept(__nothrow_assignable<const _U1&, const _U2&>())
  1012. {
  1013. this->_M_assign(__in);
  1014. return *this;
  1015. }
  1016. template<typename _U1, typename _U2>
  1017. _GLIBCXX20_CONSTEXPR
  1018. __enable_if_t<__assignable<_U1, _U2>(), tuple&>
  1019. operator=(tuple<_U1, _U2>&& __in)
  1020. noexcept(__nothrow_assignable<_U1, _U2>())
  1021. {
  1022. this->_M_assign(std::move(__in));
  1023. return *this;
  1024. }
  1025. template<typename _U1, typename _U2>
  1026. _GLIBCXX20_CONSTEXPR
  1027. __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
  1028. operator=(const pair<_U1, _U2>& __in)
  1029. noexcept(__nothrow_assignable<const _U1&, const _U2&>())
  1030. {
  1031. this->_M_head(*this) = __in.first;
  1032. this->_M_tail(*this)._M_head(*this) = __in.second;
  1033. return *this;
  1034. }
  1035. template<typename _U1, typename _U2>
  1036. _GLIBCXX20_CONSTEXPR
  1037. __enable_if_t<__assignable<_U1, _U2>(), tuple&>
  1038. operator=(pair<_U1, _U2>&& __in)
  1039. noexcept(__nothrow_assignable<_U1, _U2>())
  1040. {
  1041. this->_M_head(*this) = std::forward<_U1>(__in.first);
  1042. this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
  1043. return *this;
  1044. }
  1045. _GLIBCXX20_CONSTEXPR
  1046. void
  1047. swap(tuple& __in)
  1048. noexcept(__and_<__is_nothrow_swappable<_T1>,
  1049. __is_nothrow_swappable<_T2>>::value)
  1050. { _Inherited::_M_swap(__in); }
  1051. };
  1052. /// class tuple_size
  1053. template<typename... _Elements>
  1054. struct tuple_size<tuple<_Elements...>>
  1055. : public integral_constant<std::size_t, sizeof...(_Elements)> { };
  1056. #if __cplusplus > 201402L
  1057. template <typename _Tp>
  1058. inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
  1059. #endif
  1060. /**
  1061. * Recursive case for tuple_element: strip off the first element in
  1062. * the tuple and retrieve the (i-1)th element of the remaining tuple.
  1063. */
  1064. template<std::size_t __i, typename _Head, typename... _Tail>
  1065. struct tuple_element<__i, tuple<_Head, _Tail...> >
  1066. : tuple_element<__i - 1, tuple<_Tail...> > { };
  1067. /**
  1068. * Basis case for tuple_element: The first element is the one we're seeking.
  1069. */
  1070. template<typename _Head, typename... _Tail>
  1071. struct tuple_element<0, tuple<_Head, _Tail...> >
  1072. {
  1073. typedef _Head type;
  1074. };
  1075. /**
  1076. * Error case for tuple_element: invalid index.
  1077. */
  1078. template<size_t __i>
  1079. struct tuple_element<__i, tuple<>>
  1080. {
  1081. static_assert(__i < tuple_size<tuple<>>::value,
  1082. "tuple index is in range");
  1083. };
  1084. template<std::size_t __i, typename _Head, typename... _Tail>
  1085. constexpr _Head&
  1086. __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
  1087. { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
  1088. template<std::size_t __i, typename _Head, typename... _Tail>
  1089. constexpr const _Head&
  1090. __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
  1091. { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
  1092. /// Return a reference to the ith element of a tuple.
  1093. template<std::size_t __i, typename... _Elements>
  1094. constexpr __tuple_element_t<__i, tuple<_Elements...>>&
  1095. get(tuple<_Elements...>& __t) noexcept
  1096. { return std::__get_helper<__i>(__t); }
  1097. /// Return a const reference to the ith element of a const tuple.
  1098. template<std::size_t __i, typename... _Elements>
  1099. constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
  1100. get(const tuple<_Elements...>& __t) noexcept
  1101. { return std::__get_helper<__i>(__t); }
  1102. /// Return an rvalue reference to the ith element of a tuple rvalue.
  1103. template<std::size_t __i, typename... _Elements>
  1104. constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
  1105. get(tuple<_Elements...>&& __t) noexcept
  1106. {
  1107. typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
  1108. return std::forward<__element_type&&>(std::get<__i>(__t));
  1109. }
  1110. /// Return a const rvalue reference to the ith element of a const tuple rvalue.
  1111. template<std::size_t __i, typename... _Elements>
  1112. constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
  1113. get(const tuple<_Elements...>&& __t) noexcept
  1114. {
  1115. typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
  1116. return std::forward<const __element_type&&>(std::get<__i>(__t));
  1117. }
  1118. #if __cplusplus >= 201402L
  1119. #define __cpp_lib_tuples_by_type 201304
  1120. template<typename _Head, size_t __i, typename... _Tail>
  1121. constexpr _Head&
  1122. __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
  1123. { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
  1124. template<typename _Head, size_t __i, typename... _Tail>
  1125. constexpr const _Head&
  1126. __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
  1127. { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
  1128. /// Return a reference to the unique element of type _Tp of a tuple.
  1129. template <typename _Tp, typename... _Types>
  1130. constexpr _Tp&
  1131. get(tuple<_Types...>& __t) noexcept
  1132. { return std::__get_helper2<_Tp>(__t); }
  1133. /// Return a reference to the unique element of type _Tp of a tuple rvalue.
  1134. template <typename _Tp, typename... _Types>
  1135. constexpr _Tp&&
  1136. get(tuple<_Types...>&& __t) noexcept
  1137. { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
  1138. /// Return a const reference to the unique element of type _Tp of a tuple.
  1139. template <typename _Tp, typename... _Types>
  1140. constexpr const _Tp&
  1141. get(const tuple<_Types...>& __t) noexcept
  1142. { return std::__get_helper2<_Tp>(__t); }
  1143. /// Return a const reference to the unique element of type _Tp of
  1144. /// a const tuple rvalue.
  1145. template <typename _Tp, typename... _Types>
  1146. constexpr const _Tp&&
  1147. get(const tuple<_Types...>&& __t) noexcept
  1148. { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); }
  1149. #endif
  1150. // This class performs the comparison operations on tuples
  1151. template<typename _Tp, typename _Up, size_t __i, size_t __size>
  1152. struct __tuple_compare
  1153. {
  1154. static constexpr bool
  1155. __eq(const _Tp& __t, const _Up& __u)
  1156. {
  1157. return bool(std::get<__i>(__t) == std::get<__i>(__u))
  1158. && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
  1159. }
  1160. static constexpr bool
  1161. __less(const _Tp& __t, const _Up& __u)
  1162. {
  1163. return bool(std::get<__i>(__t) < std::get<__i>(__u))
  1164. || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
  1165. && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
  1166. }
  1167. };
  1168. template<typename _Tp, typename _Up, size_t __size>
  1169. struct __tuple_compare<_Tp, _Up, __size, __size>
  1170. {
  1171. static constexpr bool
  1172. __eq(const _Tp&, const _Up&) { return true; }
  1173. static constexpr bool
  1174. __less(const _Tp&, const _Up&) { return false; }
  1175. };
  1176. template<typename... _TElements, typename... _UElements>
  1177. constexpr bool
  1178. operator==(const tuple<_TElements...>& __t,
  1179. const tuple<_UElements...>& __u)
  1180. {
  1181. static_assert(sizeof...(_TElements) == sizeof...(_UElements),
  1182. "tuple objects can only be compared if they have equal sizes.");
  1183. using __compare = __tuple_compare<tuple<_TElements...>,
  1184. tuple<_UElements...>,
  1185. 0, sizeof...(_TElements)>;
  1186. return __compare::__eq(__t, __u);
  1187. }
  1188. #if __cpp_lib_three_way_comparison
  1189. template<typename _Cat, typename _Tp, typename _Up>
  1190. constexpr _Cat
  1191. __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
  1192. { return _Cat::equivalent; }
  1193. template<typename _Cat, typename _Tp, typename _Up,
  1194. size_t _Idx0, size_t... _Idxs>
  1195. constexpr _Cat
  1196. __tuple_cmp(const _Tp& __t, const _Up& __u,
  1197. index_sequence<_Idx0, _Idxs...>)
  1198. {
  1199. auto __c
  1200. = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
  1201. if (__c != 0)
  1202. return __c;
  1203. return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
  1204. }
  1205. template<typename... _Tps, typename... _Ups>
  1206. constexpr
  1207. common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
  1208. operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
  1209. {
  1210. using _Cat
  1211. = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
  1212. return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
  1213. }
  1214. #else
  1215. template<typename... _TElements, typename... _UElements>
  1216. constexpr bool
  1217. operator<(const tuple<_TElements...>& __t,
  1218. const tuple<_UElements...>& __u)
  1219. {
  1220. static_assert(sizeof...(_TElements) == sizeof...(_UElements),
  1221. "tuple objects can only be compared if they have equal sizes.");
  1222. using __compare = __tuple_compare<tuple<_TElements...>,
  1223. tuple<_UElements...>,
  1224. 0, sizeof...(_TElements)>;
  1225. return __compare::__less(__t, __u);
  1226. }
  1227. template<typename... _TElements, typename... _UElements>
  1228. constexpr bool
  1229. operator!=(const tuple<_TElements...>& __t,
  1230. const tuple<_UElements...>& __u)
  1231. { return !(__t == __u); }
  1232. template<typename... _TElements, typename... _UElements>
  1233. constexpr bool
  1234. operator>(const tuple<_TElements...>& __t,
  1235. const tuple<_UElements...>& __u)
  1236. { return __u < __t; }
  1237. template<typename... _TElements, typename... _UElements>
  1238. constexpr bool
  1239. operator<=(const tuple<_TElements...>& __t,
  1240. const tuple<_UElements...>& __u)
  1241. { return !(__u < __t); }
  1242. template<typename... _TElements, typename... _UElements>
  1243. constexpr bool
  1244. operator>=(const tuple<_TElements...>& __t,
  1245. const tuple<_UElements...>& __u)
  1246. { return !(__t < __u); }
  1247. #endif // three_way_comparison
  1248. // NB: DR 705.
  1249. template<typename... _Elements>
  1250. constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
  1251. make_tuple(_Elements&&... __args)
  1252. {
  1253. typedef tuple<typename __decay_and_strip<_Elements>::__type...>
  1254. __result_type;
  1255. return __result_type(std::forward<_Elements>(__args)...);
  1256. }
  1257. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1258. // 2275. Why is forward_as_tuple not constexpr?
  1259. /// std::forward_as_tuple
  1260. template<typename... _Elements>
  1261. constexpr tuple<_Elements&&...>
  1262. forward_as_tuple(_Elements&&... __args) noexcept
  1263. { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
  1264. template<size_t, typename, typename, size_t>
  1265. struct __make_tuple_impl;
  1266. template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
  1267. struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
  1268. : __make_tuple_impl<_Idx + 1,
  1269. tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
  1270. _Tuple, _Nm>
  1271. { };
  1272. template<std::size_t _Nm, typename _Tuple, typename... _Tp>
  1273. struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
  1274. {
  1275. typedef tuple<_Tp...> __type;
  1276. };
  1277. template<typename _Tuple>
  1278. struct __do_make_tuple
  1279. : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
  1280. { };
  1281. // Returns the std::tuple equivalent of a tuple-like type.
  1282. template<typename _Tuple>
  1283. struct __make_tuple
  1284. : public __do_make_tuple<__remove_cvref_t<_Tuple>>
  1285. { };
  1286. // Combines several std::tuple's into a single one.
  1287. template<typename...>
  1288. struct __combine_tuples;
  1289. template<>
  1290. struct __combine_tuples<>
  1291. {
  1292. typedef tuple<> __type;
  1293. };
  1294. template<typename... _Ts>
  1295. struct __combine_tuples<tuple<_Ts...>>
  1296. {
  1297. typedef tuple<_Ts...> __type;
  1298. };
  1299. template<typename... _T1s, typename... _T2s, typename... _Rem>
  1300. struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
  1301. {
  1302. typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
  1303. _Rem...>::__type __type;
  1304. };
  1305. // Computes the result type of tuple_cat given a set of tuple-like types.
  1306. template<typename... _Tpls>
  1307. struct __tuple_cat_result
  1308. {
  1309. typedef typename __combine_tuples
  1310. <typename __make_tuple<_Tpls>::__type...>::__type __type;
  1311. };
  1312. // Helper to determine the index set for the first tuple-like
  1313. // type of a given set.
  1314. template<typename...>
  1315. struct __make_1st_indices;
  1316. template<>
  1317. struct __make_1st_indices<>
  1318. {
  1319. typedef std::_Index_tuple<> __type;
  1320. };
  1321. template<typename _Tp, typename... _Tpls>
  1322. struct __make_1st_indices<_Tp, _Tpls...>
  1323. {
  1324. typedef typename std::_Build_index_tuple<std::tuple_size<
  1325. typename std::remove_reference<_Tp>::type>::value>::__type __type;
  1326. };
  1327. // Performs the actual concatenation by step-wise expanding tuple-like
  1328. // objects into the elements, which are finally forwarded into the
  1329. // result tuple.
  1330. template<typename _Ret, typename _Indices, typename... _Tpls>
  1331. struct __tuple_concater;
  1332. template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
  1333. struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
  1334. {
  1335. template<typename... _Us>
  1336. static constexpr _Ret
  1337. _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
  1338. {
  1339. typedef typename __make_1st_indices<_Tpls...>::__type __idx;
  1340. typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
  1341. return __next::_S_do(std::forward<_Tpls>(__tps)...,
  1342. std::forward<_Us>(__us)...,
  1343. std::get<_Is>(std::forward<_Tp>(__tp))...);
  1344. }
  1345. };
  1346. template<typename _Ret>
  1347. struct __tuple_concater<_Ret, std::_Index_tuple<>>
  1348. {
  1349. template<typename... _Us>
  1350. static constexpr _Ret
  1351. _S_do(_Us&&... __us)
  1352. {
  1353. return _Ret(std::forward<_Us>(__us)...);
  1354. }
  1355. };
  1356. /// tuple_cat
  1357. template<typename... _Tpls, typename = typename
  1358. enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
  1359. constexpr auto
  1360. tuple_cat(_Tpls&&... __tpls)
  1361. -> typename __tuple_cat_result<_Tpls...>::__type
  1362. {
  1363. typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
  1364. typedef typename __make_1st_indices<_Tpls...>::__type __idx;
  1365. typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
  1366. return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
  1367. }
  1368. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1369. // 2301. Why is tie not constexpr?
  1370. /// tie
  1371. template<typename... _Elements>
  1372. constexpr tuple<_Elements&...>
  1373. tie(_Elements&... __args) noexcept
  1374. { return tuple<_Elements&...>(__args...); }
  1375. /// swap
  1376. template<typename... _Elements>
  1377. _GLIBCXX20_CONSTEXPR
  1378. inline
  1379. #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
  1380. // Constrained free swap overload, see p0185r1
  1381. typename enable_if<__and_<__is_swappable<_Elements>...>::value
  1382. >::type
  1383. #else
  1384. void
  1385. #endif
  1386. swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
  1387. noexcept(noexcept(__x.swap(__y)))
  1388. { __x.swap(__y); }
  1389. #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
  1390. template<typename... _Elements>
  1391. _GLIBCXX20_CONSTEXPR
  1392. typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
  1393. swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
  1394. #endif
  1395. // A class (and instance) which can be used in 'tie' when an element
  1396. // of a tuple is not required.
  1397. // _GLIBCXX14_CONSTEXPR
  1398. // 2933. PR for LWG 2773 could be clearer
  1399. struct _Swallow_assign
  1400. {
  1401. template<class _Tp>
  1402. _GLIBCXX14_CONSTEXPR const _Swallow_assign&
  1403. operator=(const _Tp&) const
  1404. { return *this; }
  1405. };
  1406. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1407. // 2773. Making std::ignore constexpr
  1408. _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
  1409. /// Partial specialization for tuples
  1410. template<typename... _Types, typename _Alloc>
  1411. struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
  1412. // See stl_pair.h...
  1413. /** "piecewise construction" using a tuple of arguments for each member.
  1414. *
  1415. * @param __first Arguments for the first member of the pair.
  1416. * @param __second Arguments for the second member of the pair.
  1417. *
  1418. * The elements of each tuple will be used as the constructor arguments
  1419. * for the data members of the pair.
  1420. */
  1421. template<class _T1, class _T2>
  1422. template<typename... _Args1, typename... _Args2>
  1423. _GLIBCXX20_CONSTEXPR
  1424. inline
  1425. pair<_T1, _T2>::
  1426. pair(piecewise_construct_t,
  1427. tuple<_Args1...> __first, tuple<_Args2...> __second)
  1428. : pair(__first, __second,
  1429. typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
  1430. typename _Build_index_tuple<sizeof...(_Args2)>::__type())
  1431. { }
  1432. template<class _T1, class _T2>
  1433. template<typename... _Args1, std::size_t... _Indexes1,
  1434. typename... _Args2, std::size_t... _Indexes2>
  1435. _GLIBCXX20_CONSTEXPR inline
  1436. pair<_T1, _T2>::
  1437. pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
  1438. _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
  1439. : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
  1440. second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
  1441. { }
  1442. #if __cplusplus >= 201703L
  1443. // Unpack a std::tuple into a type trait and use its value.
  1444. // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
  1445. // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
  1446. // Otherwise the result is false (because we don't know if std::get throws).
  1447. template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
  1448. inline constexpr bool __unpack_std_tuple = false;
  1449. template<template<typename...> class _Trait, typename _Tp, typename... _Up>
  1450. inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
  1451. = _Trait<_Tp, _Up...>::value;
  1452. template<template<typename...> class _Trait, typename _Tp, typename... _Up>
  1453. inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
  1454. = _Trait<_Tp, _Up&...>::value;
  1455. template<template<typename...> class _Trait, typename _Tp, typename... _Up>
  1456. inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
  1457. = _Trait<_Tp, const _Up...>::value;
  1458. template<template<typename...> class _Trait, typename _Tp, typename... _Up>
  1459. inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
  1460. = _Trait<_Tp, const _Up&...>::value;
  1461. # define __cpp_lib_apply 201603
  1462. template <typename _Fn, typename _Tuple, size_t... _Idx>
  1463. constexpr decltype(auto)
  1464. __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
  1465. {
  1466. return std::__invoke(std::forward<_Fn>(__f),
  1467. std::get<_Idx>(std::forward<_Tuple>(__t))...);
  1468. }
  1469. template <typename _Fn, typename _Tuple>
  1470. constexpr decltype(auto)
  1471. apply(_Fn&& __f, _Tuple&& __t)
  1472. noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
  1473. {
  1474. using _Indices
  1475. = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
  1476. return std::__apply_impl(std::forward<_Fn>(__f),
  1477. std::forward<_Tuple>(__t),
  1478. _Indices{});
  1479. }
  1480. #define __cpp_lib_make_from_tuple 201606
  1481. template <typename _Tp, typename _Tuple, size_t... _Idx>
  1482. constexpr _Tp
  1483. __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
  1484. { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
  1485. template <typename _Tp, typename _Tuple>
  1486. constexpr _Tp
  1487. make_from_tuple(_Tuple&& __t)
  1488. noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
  1489. {
  1490. return __make_from_tuple_impl<_Tp>(
  1491. std::forward<_Tuple>(__t),
  1492. make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
  1493. }
  1494. #endif // C++17
  1495. /// @}
  1496. _GLIBCXX_END_NAMESPACE_VERSION
  1497. } // namespace std
  1498. #endif // C++11
  1499. #endif // _GLIBCXX_TUPLE