libstdc++
stl_pair.h
Go to the documentation of this file.
1 // Pair implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2025 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
51 /** @file bits/stl_pair.h
52  * This is an internal header file, included by other library headers.
53  * Do not attempt to use it directly. @headername{utility}
54  */
55 
56 #ifndef _STL_PAIR_H
57 #define _STL_PAIR_H 1
58 
59 #if __cplusplus >= 201103L
60 # include <type_traits> // for std::__decay_and_strip
61 # include <bits/move.h> // for std::move / std::forward, and std::swap
62 # include <bits/utility.h> // for std::tuple_element, std::tuple_size
63 #endif
64 #if __cplusplus >= 202002L
65 # include <compare>
66 #endif
67 
68 namespace std _GLIBCXX_VISIBILITY(default)
69 {
70 _GLIBCXX_BEGIN_NAMESPACE_VERSION
71 
72  /**
73  * @addtogroup utilities
74  * @{
75  */
76 
77 #if __cplusplus >= 201103L
78  /// Tag type for piecewise construction of std::pair objects.
79  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
80 
81  /// Tag for piecewise construction of std::pair objects.
82  _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
84 
85  /// @cond undocumented
86 
87  // Forward declarations.
88  template<typename _T1, typename _T2>
89  struct pair;
90 
91  template<typename...>
92  class tuple;
93 
94  // Declarations of std::array and its std::get overloads, so that
95  // std::tuple_cat can use them if <tuple> is included before <array>.
96  // We also declare the other std::get overloads here so that they're
97  // visible to the P2165R4 tuple-like constructors of pair and tuple.
98  template<typename _Tp, size_t _Nm>
99  struct array;
100 
101  template<size_t...>
102  struct _Index_tuple;
103 
104  template<typename _Tp>
105  class complex;
106 
107  template<size_t _Int, class _Tp1, class _Tp2>
108  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
109  get(pair<_Tp1, _Tp2>& __in) noexcept;
110 
111  template<size_t _Int, class _Tp1, class _Tp2>
112  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
113  get(pair<_Tp1, _Tp2>&& __in) noexcept;
114 
115  template<size_t _Int, class _Tp1, class _Tp2>
116  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
117  get(const pair<_Tp1, _Tp2>& __in) noexcept;
118 
119  template<size_t _Int, class _Tp1, class _Tp2>
120  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
121  get(const pair<_Tp1, _Tp2>&& __in) noexcept;
122 
123  template<size_t __i, typename... _Elements>
124  constexpr __tuple_element_t<__i, tuple<_Elements...>>&
125  get(tuple<_Elements...>& __t) noexcept;
126 
127  template<size_t __i, typename... _Elements>
128  constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
129  get(const tuple<_Elements...>& __t) noexcept;
130 
131  template<size_t __i, typename... _Elements>
132  constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
133  get(tuple<_Elements...>&& __t) noexcept;
134 
135  template<size_t __i, typename... _Elements>
136  constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
137  get(const tuple<_Elements...>&& __t) noexcept;
138 
139  template<size_t _Int, typename _Tp, size_t _Nm>
140  constexpr _Tp&
141  get(array<_Tp, _Nm>&) noexcept;
142 
143  template<size_t _Int, typename _Tp, size_t _Nm>
144  constexpr _Tp&&
145  get(array<_Tp, _Nm>&&) noexcept;
146 
147  template<size_t _Int, typename _Tp, size_t _Nm>
148  constexpr const _Tp&
149  get(const array<_Tp, _Nm>&) noexcept;
150 
151  template<size_t _Int, typename _Tp, size_t _Nm>
152  constexpr const _Tp&&
153  get(const array<_Tp, _Nm>&&) noexcept;
154 
155 #if __glibcxx_tuple_like >= 202311 // >= C++26
156  template<size_t _Int, typename _Tp>
157  constexpr _Tp&
158  get(complex<_Tp>&) noexcept;
159  template<size_t _Int, typename _Tp>
160  constexpr _Tp&&
161  get(complex<_Tp>&&) noexcept;
162  template<size_t _Int, typename _Tp>
163  constexpr const _Tp&
164  get(const complex<_Tp>&) noexcept;
165  template<size_t _Int, typename _Tp>
166  constexpr const _Tp&&
167  get(const complex<_Tp>&&) noexcept;
168 #endif
169 
170 #if ! __cpp_lib_concepts
171  // Concept utility functions, reused in conditionally-explicit
172  // constructors.
173  // See PR 70437, don't look at is_constructible or
174  // is_convertible if the types are the same to
175  // avoid querying those properties for incomplete types.
176  template <bool, typename _T1, typename _T2>
177  struct _PCC
178  {
179  template <typename _U1, typename _U2>
180  static constexpr bool _ConstructiblePair()
181  {
182  return __and_<is_constructible<_T1, const _U1&>,
184  }
185 
186  template <typename _U1, typename _U2>
187  static constexpr bool _ImplicitlyConvertiblePair()
188  {
189  return __and_<is_convertible<const _U1&, _T1>,
190  is_convertible<const _U2&, _T2>>::value;
191  }
192 
193  template <typename _U1, typename _U2>
194  static constexpr bool _MoveConstructiblePair()
195  {
196  return __and_<is_constructible<_T1, _U1&&>,
197  is_constructible<_T2, _U2&&>>::value;
198  }
199 
200  template <typename _U1, typename _U2>
201  static constexpr bool _ImplicitlyMoveConvertiblePair()
202  {
203  return __and_<is_convertible<_U1&&, _T1>,
204  is_convertible<_U2&&, _T2>>::value;
205  }
206  };
207 
208  template <typename _T1, typename _T2>
209  struct _PCC<false, _T1, _T2>
210  {
211  template <typename _U1, typename _U2>
212  static constexpr bool _ConstructiblePair()
213  {
214  return false;
215  }
216 
217  template <typename _U1, typename _U2>
218  static constexpr bool _ImplicitlyConvertiblePair()
219  {
220  return false;
221  }
222 
223  template <typename _U1, typename _U2>
224  static constexpr bool _MoveConstructiblePair()
225  {
226  return false;
227  }
228 
229  template <typename _U1, typename _U2>
230  static constexpr bool _ImplicitlyMoveConvertiblePair()
231  {
232  return false;
233  }
234  };
235 #endif // lib concepts
236 #endif // C++11
237 
238 #if __glibcxx_tuple_like // >= C++23
239  template<typename _Tp>
240  inline constexpr bool __is_tuple_v = false;
241 
242  template<typename... _Ts>
243  inline constexpr bool __is_tuple_v<tuple<_Ts...>> = true;
244 
245  // TODO: Reuse __is_tuple_like from <type_traits>?
246  template<typename _Tp>
247  inline constexpr bool __is_tuple_like_v = false;
248 
249  template<typename... _Elements>
250  inline constexpr bool __is_tuple_like_v<tuple<_Elements...>> = true;
251 
252  template<typename _T1, typename _T2>
253  inline constexpr bool __is_tuple_like_v<pair<_T1, _T2>> = true;
254 
255  template<typename _Tp, size_t _Nm>
256  inline constexpr bool __is_tuple_like_v<array<_Tp, _Nm>> = true;
257 
258  // __is_tuple_like_v<subrange> is defined in <bits/ranges_util.h>.
259 
260  template<typename _Tp>
261  concept __tuple_like = __is_tuple_like_v<remove_cvref_t<_Tp>>;
262 
263  template<typename _Tp>
264  concept __pair_like = __tuple_like<_Tp> && tuple_size_v<remove_cvref_t<_Tp>> == 2;
265 
266  template<typename _Tp, typename _Tuple>
267  concept __eligible_tuple_like
268  = __detail::__different_from<_Tp, _Tuple> && __tuple_like<_Tp>
269  && (tuple_size_v<remove_cvref_t<_Tp>> == tuple_size_v<_Tuple>)
270  && !ranges::__detail::__is_subrange<remove_cvref_t<_Tp>>;
271 
272  template<typename _Tp, typename _Pair>
273  concept __eligible_pair_like
274  = __detail::__different_from<_Tp, _Pair> && __pair_like<_Tp>
275  && !ranges::__detail::__is_subrange<remove_cvref_t<_Tp>>;
276 #endif // C++23
277 
278  template<typename _U1, typename _U2> class __pair_base
279  {
280 #if __cplusplus >= 201103L && ! __cpp_lib_concepts
281  template<typename _T1, typename _T2> friend struct pair;
282  __pair_base() = default;
283  ~__pair_base() = default;
284  __pair_base(const __pair_base&) = default;
285  __pair_base& operator=(const __pair_base&) = delete;
286 #endif // C++11
287  };
288 
289  /// @endcond
290 
291  /**
292  * @brief Struct holding two objects of arbitrary type.
293  *
294  * @tparam _T1 Type of first object.
295  * @tparam _T2 Type of second object.
296  *
297  * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
298  *
299  * @headerfile utility
300  */
301  template<typename _T1, typename _T2>
302  struct pair
303  : public __pair_base<_T1, _T2>
304  {
305  typedef _T1 first_type; ///< The type of the `first` member
306  typedef _T2 second_type; ///< The type of the `second` member
307 
308  _T1 first; ///< The first member
309  _T2 second; ///< The second member
310 
311 #if __cplusplus >= 201103L
312  constexpr pair(const pair&) = default; ///< Copy constructor
313  constexpr pair(pair&&) = default; ///< Move constructor
314 
315  template<typename... _Args1, typename... _Args2>
316  _GLIBCXX20_CONSTEXPR
318 
319  /// Swap the first members and then the second members.
320  _GLIBCXX20_CONSTEXPR void
321  swap(pair& __p)
322  noexcept(__and_<__is_nothrow_swappable<_T1>,
323  __is_nothrow_swappable<_T2>>::value)
324  {
325  using std::swap;
326  swap(first, __p.first);
327  swap(second, __p.second);
328  }
329 
330 #if __glibcxx_ranges_zip // >= C++23
331  // As an extension, we constrain the const swap member function in order
332  // to continue accepting explicit instantiation of pairs whose elements
333  // are not all const swappable. Without this constraint, such an
334  // explicit instantiation would also instantiate the ill-formed body of
335  // this function and yield a hard error. This constraint shouldn't
336  // affect the behavior of valid programs.
337  constexpr void
338  swap(const pair& __p) const
339  noexcept(__and_v<__is_nothrow_swappable<const _T1>,
340  __is_nothrow_swappable<const _T2>>)
341  requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
342  {
343  using std::swap;
344  swap(first, __p.first);
345  swap(second, __p.second);
346  }
347 #endif // C++23
348 
349  private:
350  template<typename... _Args1, size_t... _Indexes1,
351  typename... _Args2, size_t... _Indexes2>
352  _GLIBCXX20_CONSTEXPR
353  pair(tuple<_Args1...>&, tuple<_Args2...>&,
354  _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
355  public:
356 
357 #if __cpp_lib_concepts
358  // C++20 implementation using concepts, explicit(bool), fully constexpr.
359 
360  /// Default constructor
361  constexpr
362  explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
363  __is_implicitly_default_constructible<_T2>>>())
364  pair()
365  noexcept(is_nothrow_default_constructible_v<_T1>
366  && is_nothrow_default_constructible_v<_T2>)
367  requires is_default_constructible_v<_T1>
368  && is_default_constructible_v<_T2>
369  : first(), second()
370  { }
371 
372  private:
373 
374  /// @cond undocumented
375  template<typename _U1, typename _U2>
376  static constexpr bool
377  _S_constructible()
378  {
379  if constexpr (is_constructible_v<_T1, _U1>)
380  return is_constructible_v<_T2, _U2>;
381  return false;
382  }
383 
384  template<typename _U1, typename _U2>
385  static constexpr bool
386  _S_nothrow_constructible()
387  {
388  if constexpr (is_nothrow_constructible_v<_T1, _U1>)
389  return is_nothrow_constructible_v<_T2, _U2>;
390  return false;
391  }
392 
393  template<typename _U1, typename _U2>
394  static constexpr bool
395  _S_convertible()
396  {
397  if constexpr (is_convertible_v<_U1, _T1>)
398  return is_convertible_v<_U2, _T2>;
399  return false;
400  }
401 
402  // True if construction from _U1 and _U2 would create a dangling ref.
403  template<typename _U1, typename _U2>
404  static constexpr bool
405  _S_dangles()
406  {
407 #if __has_builtin(__reference_constructs_from_temporary)
408  if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
409  return true;
410  else
411  return __reference_constructs_from_temporary(_T2, _U2&&);
412 #else
413  return false;
414 #endif
415  }
416 
417 #if __glibcxx_tuple_like // >= C++23
418  template<typename _UPair>
419  static constexpr bool
420  _S_constructible_from_pair_like()
421  {
422  return _S_constructible<decltype(std::get<0>(std::declval<_UPair>())),
423  decltype(std::get<1>(std::declval<_UPair>()))>();
424  }
425 
426  template<typename _UPair>
427  static constexpr bool
428  _S_convertible_from_pair_like()
429  {
430  return _S_convertible<decltype(std::get<0>(std::declval<_UPair>())),
431  decltype(std::get<1>(std::declval<_UPair>()))>();
432  }
433 
434  template<typename _UPair>
435  static constexpr bool
436  _S_dangles_from_pair_like()
437  {
438  return _S_dangles<decltype(std::get<0>(std::declval<_UPair>())),
439  decltype(std::get<1>(std::declval<_UPair>()))>();
440  }
441 #endif // C++23
442  /// @endcond
443 
444  public:
445 
446  /// Constructor accepting lvalues of `first_type` and `second_type`
447  constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
448  pair(const _T1& __x, const _T2& __y)
449  noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
450  requires (_S_constructible<const _T1&, const _T2&>())
451  : first(__x), second(__y)
452  { }
453 
454  /// Constructor accepting two values of arbitrary types
455 #if __cplusplus > 202002L
456  template<typename _U1 = _T1, typename _U2 = _T2>
457 #else
458  template<typename _U1, typename _U2>
459 #endif
460  requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
461  constexpr explicit(!_S_convertible<_U1, _U2>())
462  pair(_U1&& __x, _U2&& __y)
463  noexcept(_S_nothrow_constructible<_U1, _U2>())
464  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
465  { }
466 
467 #if __cplusplus > 202002L
468  template<typename _U1 = _T1, typename _U2 = _T2>
469 #else
470  template<typename _U1, typename _U2>
471 #endif
472  requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
473  constexpr explicit(!_S_convertible<_U1, _U2>())
474  pair(_U1&&, _U2&&) = delete;
475 
476  /// Converting constructor from a const `pair<U1, U2>` lvalue
477  template<typename _U1, typename _U2>
478  requires (_S_constructible<const _U1&, const _U2&>())
479  && (!_S_dangles<_U1, _U2>())
480  constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
481  pair(const pair<_U1, _U2>& __p)
482  noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
483  : first(__p.first), second(__p.second)
484  { }
485 
486  template<typename _U1, typename _U2>
487  requires (_S_constructible<const _U1&, const _U2&>())
488  && (_S_dangles<const _U1&, const _U2&>())
489  constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
490  pair(const pair<_U1, _U2>&) = delete;
491 
492  /// Converting constructor from a non-const `pair<U1, U2>` rvalue
493  template<typename _U1, typename _U2>
494  requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
495  constexpr explicit(!_S_convertible<_U1, _U2>())
496  pair(pair<_U1, _U2>&& __p)
497  noexcept(_S_nothrow_constructible<_U1, _U2>())
498  : first(std::forward<_U1>(__p.first)),
499  second(std::forward<_U2>(__p.second))
500  { }
501 
502  template<typename _U1, typename _U2>
503  requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
504  constexpr explicit(!_S_convertible<_U1, _U2>())
505  pair(pair<_U1, _U2>&&) = delete;
506 
507 #if __glibcxx_ranges_zip // >= C++23
508  /// Converting constructor from a non-const `pair<U1, U2>` lvalue
509  template<typename _U1, typename _U2>
510  requires (_S_constructible<_U1&, _U2&>()) && (!_S_dangles<_U1&, _U2&>())
511  constexpr explicit(!_S_convertible<_U1&, _U2&>())
512  pair(pair<_U1, _U2>& __p)
513  noexcept(_S_nothrow_constructible<_U1&, _U2&>())
514  : first(__p.first), second(__p.second)
515  { }
516 
517  template<typename _U1, typename _U2>
518  requires (_S_constructible<_U1&, _U2&>()) && (_S_dangles<_U1&, _U2&>())
519  constexpr explicit(!_S_convertible<_U1&, _U2&>())
520  pair(pair<_U1, _U2>&) = delete;
521 
522  /// Converting constructor from a const `pair<U1, U2>` rvalue
523  template<typename _U1, typename _U2>
524  requires (_S_constructible<const _U1, const _U2>())
525  && (!_S_dangles<const _U1, const _U2>())
526  constexpr explicit(!_S_convertible<const _U1, const _U2>())
527  pair(const pair<_U1, _U2>&& __p)
528  noexcept(_S_nothrow_constructible<const _U1, const _U2>())
529  : first(std::forward<const _U1>(__p.first)),
530  second(std::forward<const _U2>(__p.second))
531  { }
532 
533  template<typename _U1, typename _U2>
534  requires (_S_constructible<const _U1, const _U2>())
535  && (_S_dangles<const _U1, const _U2>())
536  constexpr explicit(!_S_convertible<const _U1, const _U2>())
537  pair(const pair<_U1, _U2>&&) = delete;
538 #endif // C++23
539 
540 #if __glibcxx_tuple_like // >= C++23
541  template<__eligible_pair_like<pair> _UPair>
542  requires (_S_constructible_from_pair_like<_UPair>())
543  && (!_S_dangles_from_pair_like<_UPair>())
544  constexpr explicit(!_S_convertible_from_pair_like<_UPair>())
545  pair(_UPair&& __p)
546  : first(std::get<0>(std::forward<_UPair>(__p))),
547  second(std::get<1>(std::forward<_UPair>(__p)))
548  { }
549 
550  template<__eligible_pair_like<pair> _UPair>
551  requires (_S_constructible_from_pair_like<_UPair>())
552  && (_S_dangles_from_pair_like<_UPair>())
553  constexpr explicit(!_S_convertible_from_pair_like<_UPair>())
554  pair(_UPair&&) = delete;
555 #endif // C++23
556 
557  private:
558  /// @cond undocumented
559  template<typename _U1, typename _U2>
560  static constexpr bool
561  _S_assignable()
562  {
563  if constexpr (is_assignable_v<_T1&, _U1>)
564  return is_assignable_v<_T2&, _U2>;
565  return false;
566  }
567 
568  template<typename _U1, typename _U2>
569  static constexpr bool
570  _S_const_assignable()
571  {
572  if constexpr (is_assignable_v<const _T1&, _U1>)
573  return is_assignable_v<const _T2&, _U2>;
574  return false;
575  }
576 
577  template<typename _U1, typename _U2>
578  static constexpr bool
579  _S_nothrow_assignable()
580  {
581  if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
582  return is_nothrow_assignable_v<_T2&, _U2>;
583  return false;
584  }
585 
586 #if __glibcxx_tuple_like // >= C++23
587  template<typename _UPair>
588  static constexpr bool
589  _S_assignable_from_tuple_like()
590  {
591  return _S_assignable<decltype(std::get<0>(std::declval<_UPair>())),
592  decltype(std::get<1>(std::declval<_UPair>()))>();
593  }
594 
595  template<typename _UPair>
596  static constexpr bool
597  _S_const_assignable_from_tuple_like()
598  {
599  return _S_const_assignable<decltype(std::get<0>(std::declval<_UPair>())),
600  decltype(std::get<1>(std::declval<_UPair>()))>();
601  }
602 #endif // C++23
603  /// @endcond
604 
605  public:
606 
607  pair& operator=(const pair&) = delete;
608 
609  /// Copy assignment operator
610  constexpr pair&
611  operator=(const pair& __p)
612  noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
613  requires (_S_assignable<const _T1&, const _T2&>())
614  {
615  first = __p.first;
616  second = __p.second;
617  return *this;
618  }
619 
620  /// Move assignment operator
621  constexpr pair&
622  operator=(pair&& __p)
623  noexcept(_S_nothrow_assignable<_T1, _T2>())
624  requires (_S_assignable<_T1, _T2>())
625  {
626  first = std::forward<first_type>(__p.first);
627  second = std::forward<second_type>(__p.second);
628  return *this;
629  }
630 
631  /// Converting assignment from a const `pair<U1, U2>` lvalue
632  template<typename _U1, typename _U2>
633  constexpr pair&
634  operator=(const pair<_U1, _U2>& __p)
635  noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
636  requires (_S_assignable<const _U1&, const _U2&>())
637  {
638  first = __p.first;
639  second = __p.second;
640  return *this;
641  }
642 
643  /// Converting assignment from a non-const `pair<U1, U2>` rvalue
644  template<typename _U1, typename _U2>
645  constexpr pair&
646  operator=(pair<_U1, _U2>&& __p)
647  noexcept(_S_nothrow_assignable<_U1, _U2>())
648  requires (_S_assignable<_U1, _U2>())
649  {
650  first = std::forward<_U1>(__p.first);
651  second = std::forward<_U2>(__p.second);
652  return *this;
653  }
654 
655 #if __glibcxx_ranges_zip // >= C++23
656  /// Copy assignment operator (const)
657  constexpr const pair&
658  operator=(const pair& __p) const
659  requires (_S_const_assignable<const first_type&, const second_type&>())
660  {
661  first = __p.first;
662  second = __p.second;
663  return *this;
664  }
665 
666  /// Move assignment operator (const)
667  constexpr const pair&
668  operator=(pair&& __p) const
669  requires (_S_const_assignable<first_type, second_type>())
670  {
671  first = std::forward<first_type>(__p.first);
672  second = std::forward<second_type>(__p.second);
673  return *this;
674  }
675 
676  /// Converting assignment from a const `pair<U1, U2>` lvalue
677  template<typename _U1, typename _U2>
678  constexpr const pair&
679  operator=(const pair<_U1, _U2>& __p) const
680  requires (_S_const_assignable<const _U1&, const _U2&>())
681  {
682  first = __p.first;
683  second = __p.second;
684  return *this;
685  }
686 
687  /// Converting assignment from a non-const `pair<U1, U2>` rvalue
688  template<typename _U1, typename _U2>
689  constexpr const pair&
690  operator=(pair<_U1, _U2>&& __p) const
691  requires (_S_const_assignable<_U1, _U2>())
692  {
693  first = std::forward<_U1>(__p.first);
694  second = std::forward<_U2>(__p.second);
695  return *this;
696  }
697 #endif // C++23
698 
699 #if __glibcxx_tuple_like // >= C++23
700  template<__eligible_pair_like<pair> _UPair>
701  requires (_S_assignable_from_tuple_like<_UPair>())
702  constexpr pair&
703  operator=(_UPair&& __p)
704  {
705  first = std::get<0>(std::forward<_UPair>(__p));
706  second = std::get<1>(std::forward<_UPair>(__p));
707  return *this;
708  }
709 
710  template<__eligible_pair_like<pair> _UPair>
711  requires (_S_const_assignable_from_tuple_like<_UPair>())
712  constexpr const pair&
713  operator=(_UPair&& __p) const
714  {
715  first = std::get<0>(std::forward<_UPair>(__p));
716  second = std::get<1>(std::forward<_UPair>(__p));
717  return *this;
718  }
719 #endif // C++23
720 
721 #else // !__cpp_lib_concepts
722  // C++11/14/17 implementation using enable_if, partially constexpr.
723 
724  /// @cond undocumented
725  // Error if construction from _U1 and _U2 would create a dangling ref.
726 #if __has_builtin(__reference_constructs_from_temporary) \
727  && defined _GLIBCXX_DEBUG
728 # define __glibcxx_no_dangling_refs(_U1, _U2) \
729  static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
730  && !__reference_constructs_from_temporary(_T2, _U2), \
731  "std::pair constructor creates a dangling reference")
732 #else
733 # define __glibcxx_no_dangling_refs(_U1, _U2)
734 #endif
735  /// @endcond
736 
737  /** The default constructor creates @c first and @c second using their
738  * respective default constructors. */
739  template <typename _U1 = _T1,
740  typename _U2 = _T2,
741  typename enable_if<__and_<
742  __is_implicitly_default_constructible<_U1>,
743  __is_implicitly_default_constructible<_U2>>
744  ::value, bool>::type = true>
745  constexpr pair()
746  : first(), second() { }
747 
748  template <typename _U1 = _T1,
749  typename _U2 = _T2,
750  typename enable_if<__and_<
753  __not_<
754  __and_<__is_implicitly_default_constructible<_U1>,
755  __is_implicitly_default_constructible<_U2>>>>
756  ::value, bool>::type = false>
757  explicit constexpr pair()
758  : first(), second() { }
759 
760  // Shortcut for constraining the templates that don't take pairs.
761  /// @cond undocumented
762  using _PCCP = _PCC<true, _T1, _T2>;
763  /// @endcond
764 
765  /// Construct from two const lvalues, allowing implicit conversions.
766  template<typename _U1 = _T1, typename _U2=_T2, typename
767  enable_if<_PCCP::template
768  _ConstructiblePair<_U1, _U2>()
769  && _PCCP::template
770  _ImplicitlyConvertiblePair<_U1, _U2>(),
771  bool>::type=true>
772  constexpr pair(const _T1& __a, const _T2& __b)
773  : first(__a), second(__b) { }
774 
775  /// Construct from two const lvalues, disallowing implicit conversions.
776  template<typename _U1 = _T1, typename _U2=_T2, typename
777  enable_if<_PCCP::template
778  _ConstructiblePair<_U1, _U2>()
779  && !_PCCP::template
780  _ImplicitlyConvertiblePair<_U1, _U2>(),
781  bool>::type=false>
782  explicit constexpr pair(const _T1& __a, const _T2& __b)
783  : first(__a), second(__b) { }
784 
785  // Shortcut for constraining the templates that take pairs.
786  /// @cond undocumented
787  template <typename _U1, typename _U2>
788  using _PCCFP = _PCC<!is_same<_T1, _U1>::value
790  _T1, _T2>;
791  /// @endcond
792 
793  template<typename _U1, typename _U2, typename
795  _ConstructiblePair<_U1, _U2>()
796  && _PCCFP<_U1, _U2>::template
797  _ImplicitlyConvertiblePair<_U1, _U2>(),
798  bool>::type=true>
799  constexpr pair(const pair<_U1, _U2>& __p)
800  : first(__p.first), second(__p.second)
801  { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
802 
803  template<typename _U1, typename _U2, typename
804  enable_if<_PCCFP<_U1, _U2>::template
805  _ConstructiblePair<_U1, _U2>()
806  && !_PCCFP<_U1, _U2>::template
807  _ImplicitlyConvertiblePair<_U1, _U2>(),
808  bool>::type=false>
809  explicit constexpr pair(const pair<_U1, _U2>& __p)
810  : first(__p.first), second(__p.second)
811  { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
812 
813 #if _GLIBCXX_USE_DEPRECATED
814 #if defined(__DEPRECATED)
815 # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
816  __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
817  "initialize std::pair of move-only " \
818  "type and pointer")))
819 #else
820 # define _GLIBCXX_DEPRECATED_PAIR_CTOR
821 #endif
822 
823  private:
824  /// @cond undocumented
825 
826  // A type which can be constructed from literal zero, but not nullptr
827  struct __zero_as_null_pointer_constant
828  {
829  __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
830  { }
831  template<typename _Tp,
832  typename = __enable_if_t<is_null_pointer<_Tp>::value>>
833  __zero_as_null_pointer_constant(_Tp) = delete;
834  };
835  /// @endcond
836  public:
837 
838  // Deprecated extensions to DR 811.
839  // These allow construction from an rvalue and a literal zero,
840  // in cases where the standard says the zero should be deduced as int
841  template<typename _U1,
842  __enable_if_t<__and_<__not_<is_reference<_U1>>,
843  is_pointer<_T2>,
844  is_constructible<_T1, _U1>,
845  __not_<is_constructible<_T1, const _U1&>>,
846  is_convertible<_U1, _T1>>::value,
847  bool> = true>
848  _GLIBCXX_DEPRECATED_PAIR_CTOR
849  constexpr
850  pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
851  : first(std::forward<_U1>(__x)), second(nullptr)
852  { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
853 
854  template<typename _U1,
855  __enable_if_t<__and_<__not_<is_reference<_U1>>,
856  is_pointer<_T2>,
857  is_constructible<_T1, _U1>,
858  __not_<is_constructible<_T1, const _U1&>>,
859  __not_<is_convertible<_U1, _T1>>>::value,
860  bool> = false>
861  _GLIBCXX_DEPRECATED_PAIR_CTOR
862  explicit constexpr
863  pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
864  : first(std::forward<_U1>(__x)), second(nullptr)
865  { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
866 
867  template<typename _U2,
868  __enable_if_t<__and_<is_pointer<_T1>,
869  __not_<is_reference<_U2>>,
870  is_constructible<_T2, _U2>,
871  __not_<is_constructible<_T2, const _U2&>>,
872  is_convertible<_U2, _T2>>::value,
873  bool> = true>
874  _GLIBCXX_DEPRECATED_PAIR_CTOR
875  constexpr
876  pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
877  : first(nullptr), second(std::forward<_U2>(__y))
878  { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
879 
880  template<typename _U2,
881  __enable_if_t<__and_<is_pointer<_T1>,
882  __not_<is_reference<_U2>>,
883  is_constructible<_T2, _U2>,
884  __not_<is_constructible<_T2, const _U2&>>,
885  __not_<is_convertible<_U2, _T2>>>::value,
886  bool> = false>
887  _GLIBCXX_DEPRECATED_PAIR_CTOR
888  explicit constexpr
889  pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
890  : first(nullptr), second(std::forward<_U2>(__y))
891  { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
892 #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
893 #endif
894 
895  template<typename _U1, typename _U2, typename
896  enable_if<_PCCP::template
897  _MoveConstructiblePair<_U1, _U2>()
898  && _PCCP::template
899  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
900  bool>::type=true>
901  constexpr pair(_U1&& __x, _U2&& __y)
902  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
903  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
904 
905  template<typename _U1, typename _U2, typename
906  enable_if<_PCCP::template
907  _MoveConstructiblePair<_U1, _U2>()
908  && !_PCCP::template
909  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
910  bool>::type=false>
911  explicit constexpr pair(_U1&& __x, _U2&& __y)
912  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
913  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
914 
915 
916  template<typename _U1, typename _U2, typename
917  enable_if<_PCCFP<_U1, _U2>::template
918  _MoveConstructiblePair<_U1, _U2>()
919  && _PCCFP<_U1, _U2>::template
920  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
921  bool>::type=true>
922  constexpr pair(pair<_U1, _U2>&& __p)
923  : first(std::forward<_U1>(__p.first)),
924  second(std::forward<_U2>(__p.second))
925  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
926 
927  template<typename _U1, typename _U2, typename
928  enable_if<_PCCFP<_U1, _U2>::template
929  _MoveConstructiblePair<_U1, _U2>()
930  && !_PCCFP<_U1, _U2>::template
931  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
932  bool>::type=false>
933  explicit constexpr pair(pair<_U1, _U2>&& __p)
934  : first(std::forward<_U1>(__p.first)),
935  second(std::forward<_U2>(__p.second))
936  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
937 
938 #undef __glibcxx_no_dangling_refs
939 
940  pair&
941  operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
942  is_copy_assignable<_T2>>::value,
943  const pair&, const __nonesuch&> __p)
944  {
945  first = __p.first;
946  second = __p.second;
947  return *this;
948  }
949 
950  pair&
951  operator=(__conditional_t<__and_<is_move_assignable<_T1>,
952  is_move_assignable<_T2>>::value,
953  pair&&, __nonesuch&&> __p)
954  noexcept(__and_<is_nothrow_move_assignable<_T1>,
955  is_nothrow_move_assignable<_T2>>::value)
956  {
957  first = std::forward<first_type>(__p.first);
958  second = std::forward<second_type>(__p.second);
959  return *this;
960  }
961 
962  template<typename _U1, typename _U2>
963  typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
964  is_assignable<_T2&, const _U2&>>::value,
965  pair&>::type
966  operator=(const pair<_U1, _U2>& __p)
967  {
968  first = __p.first;
969  second = __p.second;
970  return *this;
971  }
972 
973  template<typename _U1, typename _U2>
974  typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
975  is_assignable<_T2&, _U2&&>>::value,
976  pair&>::type
977  operator=(pair<_U1, _U2>&& __p)
978  {
979  first = std::forward<_U1>(__p.first);
980  second = std::forward<_U2>(__p.second);
981  return *this;
982  }
983 #endif // lib concepts
984 #else
985  // C++03 implementation
986 
987  // _GLIBCXX_RESOLVE_LIB_DEFECTS
988  // 265. std::pair::pair() effects overly restrictive
989  /** The default constructor creates @c first and @c second using their
990  * respective default constructors. */
991  pair() : first(), second() { }
992 
993  /// Two objects may be passed to a `pair` constructor to be copied.
994  pair(const _T1& __a, const _T2& __b)
995  : first(__a), second(__b) { }
996 
997  /// Templated constructor to convert from other pairs.
998  template<typename _U1, typename _U2>
999  pair(const pair<_U1, _U2>& __p)
1000  : first(__p.first), second(__p.second)
1001  {
1002 #if __has_builtin(__reference_constructs_from_temporary)
1003 #pragma GCC diagnostic push
1004 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
1005  typedef int _DanglingCheck1[
1006  __reference_constructs_from_temporary(_T1, const _U1&) ? -1 : 1
1007  ];
1008  typedef int _DanglingCheck2[
1009  __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
1010  ];
1011 #pragma GCC diagnostic pop
1012 #endif
1013  }
1014 #endif // C++11
1015  };
1016 
1017  /// @relates pair @{
1018 
1019 #if __cpp_deduction_guides >= 201606
1020  template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
1021 #endif
1022 
1023 #if __cpp_lib_three_way_comparison
1024  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1025  // 3865. Sorting a range of pairs
1026 
1027  /// Two pairs are equal iff their members are equal.
1028  template<typename _T1, typename _T2, typename _U1, typename _U2>
1029  [[nodiscard]]
1030  constexpr bool
1031  operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
1032  requires requires {
1033  { __x.first == __y.first } -> __detail::__boolean_testable;
1034  { __x.second == __y.second } -> __detail::__boolean_testable;
1035  }
1036  { return __x.first == __y.first && __x.second == __y.second; }
1037 
1038  /** Defines a lexicographical order for pairs.
1039  *
1040  * For two pairs of comparable types, `P` is ordered before `Q` if
1041  * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
1042  * are equivalent (neither is less than the other) and `P.second` is
1043  * less than `Q.second`.
1044  */
1045  template<typename _T1, typename _T2, typename _U1, typename _U2>
1046  [[nodiscard]]
1047  constexpr common_comparison_category_t<__detail::__synth3way_t<_T1, _U1>,
1048  __detail::__synth3way_t<_T2, _U2>>
1049  operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
1050  {
1051  if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
1052  return __c;
1053  return __detail::__synth3way(__x.second, __y.second);
1054  }
1055 #else
1056  /// Two pairs of the same type are equal iff their members are equal.
1057  template<typename _T1, typename _T2>
1058  _GLIBCXX_NODISCARD
1059  inline _GLIBCXX_CONSTEXPR bool
1060  operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1061  { return __x.first == __y.first && __x.second == __y.second; }
1062 
1063  /** Defines a lexicographical order for pairs.
1064  *
1065  * For two pairs of the same type, `P` is ordered before `Q` if
1066  * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
1067  * are equivalent (neither is less than the other) and `P.second` is less
1068  * than `Q.second`.
1069  */
1070  template<typename _T1, typename _T2>
1071  _GLIBCXX_NODISCARD
1072  inline _GLIBCXX_CONSTEXPR bool
1073  operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1074  { return __x.first < __y.first
1075  || (!(__y.first < __x.first) && __x.second < __y.second); }
1076 
1077  /// Uses @c operator== to find the result.
1078  template<typename _T1, typename _T2>
1079  _GLIBCXX_NODISCARD
1080  inline _GLIBCXX_CONSTEXPR bool
1081  operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1082  { return !(__x == __y); }
1083 
1084  /// Uses @c operator< to find the result.
1085  template<typename _T1, typename _T2>
1086  _GLIBCXX_NODISCARD
1087  inline _GLIBCXX_CONSTEXPR bool
1088  operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1089  { return __y < __x; }
1090 
1091  /// Uses @c operator< to find the result.
1092  template<typename _T1, typename _T2>
1093  _GLIBCXX_NODISCARD
1094  inline _GLIBCXX_CONSTEXPR bool
1095  operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1096  { return !(__y < __x); }
1097 
1098  /// Uses @c operator< to find the result.
1099  template<typename _T1, typename _T2>
1100  _GLIBCXX_NODISCARD
1101  inline _GLIBCXX_CONSTEXPR bool
1102  operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1103  { return !(__x < __y); }
1104 #endif // !(three_way_comparison && concepts)
1105 
1106 #if __cplusplus >= 201103L
1107  /** Swap overload for pairs. Calls std::pair::swap().
1108  *
1109  * @note This std::swap overload is not declared in C++03 mode,
1110  * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
1111  */
1112  template<typename _T1, typename _T2>
1113  _GLIBCXX20_CONSTEXPR inline
1114 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1115  // Constrained free swap overload, see p0185r1
1116  typename enable_if<__and_<__is_swappable<_T1>,
1117  __is_swappable<_T2>>::value>::type
1118 #else
1119  void
1120 #endif
1122  noexcept(noexcept(__x.swap(__y)))
1123  { __x.swap(__y); }
1124 
1125 #if __glibcxx_ranges_zip // >= C++23
1126  template<typename _T1, typename _T2>
1127  requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
1128  constexpr void
1129  swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
1130  noexcept(noexcept(__x.swap(__y)))
1131  { __x.swap(__y); }
1132 #endif // C++23
1133 
1134 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1135  template<typename _T1, typename _T2>
1136  typename enable_if<!__and_<__is_swappable<_T1>,
1137  __is_swappable<_T2>>::value>::type
1138  swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
1139 #endif
1140 #endif // __cplusplus >= 201103L
1141 
1142  /// @} relates pair
1143 
1144  /**
1145  * @brief A convenience wrapper for creating a pair from two objects.
1146  * @param __x The first object.
1147  * @param __y The second object.
1148  * @return A newly-constructed pair<> object of the appropriate type.
1149  *
1150  * The C++98 standard says the objects are passed by reference-to-const,
1151  * but C++03 says they are passed by value (this was LWG issue #181).
1152  *
1153  * Since C++11 they have been passed by forwarding reference and then
1154  * forwarded to the new members of the pair. To create a pair with a
1155  * member of reference type, pass a `reference_wrapper` to this function.
1156  */
1157  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1158  // 181. make_pair() unintended behavior
1159 #if __cplusplus >= 201103L
1160  // NB: DR 706.
1161  template<typename _T1, typename _T2>
1162  constexpr pair<typename __decay_and_strip<_T1>::__type,
1163  typename __decay_and_strip<_T2>::__type>
1164  make_pair(_T1&& __x, _T2&& __y)
1165  {
1166  typedef typename __decay_and_strip<_T1>::__type __ds_type1;
1167  typedef typename __decay_and_strip<_T2>::__type __ds_type2;
1168  typedef pair<__ds_type1, __ds_type2> __pair_type;
1169  return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
1170  }
1171 #else
1172  template<typename _T1, typename _T2>
1173  inline pair<_T1, _T2>
1174  make_pair(_T1 __x, _T2 __y)
1175  { return pair<_T1, _T2>(__x, __y); }
1176 #endif
1177 
1178  /// @}
1179 
1180 #if __cplusplus >= 201103L
1181  // Various functions which give std::pair a tuple-like interface.
1182 
1183  /// @cond undocumented
1184  template<typename _T1, typename _T2>
1185  struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
1186  { };
1187  /// @endcond
1188 
1189  /// Partial specialization for std::pair
1190  template<class _Tp1, class _Tp2>
1191  struct tuple_size<pair<_Tp1, _Tp2>>
1192  : public integral_constant<size_t, 2> { };
1193 
1194  /// Partial specialization for std::pair
1195  template<class _Tp1, class _Tp2>
1196  struct tuple_element<0, pair<_Tp1, _Tp2>>
1197  { typedef _Tp1 type; };
1198 
1199  /// Partial specialization for std::pair
1200  template<class _Tp1, class _Tp2>
1201  struct tuple_element<1, pair<_Tp1, _Tp2>>
1202  { typedef _Tp2 type; };
1203 
1204 #if __cplusplus >= 201703L
1205  template<typename _Tp1, typename _Tp2>
1206  inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
1207 
1208  template<typename _Tp1, typename _Tp2>
1209  inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
1210 #endif
1211 
1212 #if __cplusplus >= 201103L
1213 #pragma GCC diagnostic push
1214 #pragma GCC diagnostic ignored "-Wc++14-extensions" // variable templates
1215 #pragma GCC diagnostic ignored "-Wc++17-extensions" // inline variables
1216  template<typename _Tp>
1217  inline constexpr bool __is_pair = false;
1218 
1219  template<typename _Tp, typename _Up>
1220  inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
1221 #pragma GCC diagnostic pop
1222 #endif
1223 
1224  /// @cond undocumented
1225  template<size_t _Int>
1226  struct __pair_get;
1227 
1228  template<>
1229  struct __pair_get<0>
1230  {
1231  template<typename _Tp1, typename _Tp2>
1232  static constexpr _Tp1&
1233  __get(pair<_Tp1, _Tp2>& __pair) noexcept
1234  { return __pair.first; }
1235 
1236  template<typename _Tp1, typename _Tp2>
1237  static constexpr _Tp1&&
1238  __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
1239  { return std::forward<_Tp1>(__pair.first); }
1240 
1241  template<typename _Tp1, typename _Tp2>
1242  static constexpr const _Tp1&
1243  __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1244  { return __pair.first; }
1245 
1246  template<typename _Tp1, typename _Tp2>
1247  static constexpr const _Tp1&&
1248  __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1249  { return std::forward<const _Tp1>(__pair.first); }
1250  };
1251 
1252  template<>
1253  struct __pair_get<1>
1254  {
1255  template<typename _Tp1, typename _Tp2>
1256  static constexpr _Tp2&
1257  __get(pair<_Tp1, _Tp2>& __pair) noexcept
1258  { return __pair.second; }
1259 
1260  template<typename _Tp1, typename _Tp2>
1261  static constexpr _Tp2&&
1262  __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
1263  { return std::forward<_Tp2>(__pair.second); }
1264 
1265  template<typename _Tp1, typename _Tp2>
1266  static constexpr const _Tp2&
1267  __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1268  { return __pair.second; }
1269 
1270  template<typename _Tp1, typename _Tp2>
1271  static constexpr const _Tp2&&
1272  __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1273  { return std::forward<const _Tp2>(__pair.second); }
1274  };
1275  /// @endcond
1276 
1277  /** @{
1278  * std::get overloads for accessing members of std::pair
1279  */
1280 
1281  template<size_t _Int, class _Tp1, class _Tp2>
1282  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1283  get(pair<_Tp1, _Tp2>& __in) noexcept
1284  { return __pair_get<_Int>::__get(__in); }
1285 
1286  template<size_t _Int, class _Tp1, class _Tp2>
1287  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1288  get(pair<_Tp1, _Tp2>&& __in) noexcept
1289  { return __pair_get<_Int>::__move_get(std::move(__in)); }
1290 
1291  template<size_t _Int, class _Tp1, class _Tp2>
1292  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1293  get(const pair<_Tp1, _Tp2>& __in) noexcept
1294  { return __pair_get<_Int>::__const_get(__in); }
1295 
1296  template<size_t _Int, class _Tp1, class _Tp2>
1297  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1298  get(const pair<_Tp1, _Tp2>&& __in) noexcept
1299  { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
1300 
1301 
1302 #ifdef __glibcxx_tuples_by_type // C++ >= 14
1303  template <typename _Tp, typename _Up>
1304  constexpr _Tp&
1305  get(pair<_Tp, _Up>& __p) noexcept
1306  { return __p.first; }
1307 
1308  template <typename _Tp, typename _Up>
1309  constexpr const _Tp&
1310  get(const pair<_Tp, _Up>& __p) noexcept
1311  { return __p.first; }
1312 
1313  template <typename _Tp, typename _Up>
1314  constexpr _Tp&&
1315  get(pair<_Tp, _Up>&& __p) noexcept
1316  { return std::move(__p.first); }
1317 
1318  template <typename _Tp, typename _Up>
1319  constexpr const _Tp&&
1320  get(const pair<_Tp, _Up>&& __p) noexcept
1321  { return std::move(__p.first); }
1322 
1323  template <typename _Tp, typename _Up>
1324  constexpr _Tp&
1325  get(pair<_Up, _Tp>& __p) noexcept
1326  { return __p.second; }
1327 
1328  template <typename _Tp, typename _Up>
1329  constexpr const _Tp&
1330  get(const pair<_Up, _Tp>& __p) noexcept
1331  { return __p.second; }
1332 
1333  template <typename _Tp, typename _Up>
1334  constexpr _Tp&&
1335  get(pair<_Up, _Tp>&& __p) noexcept
1336  { return std::move(__p.second); }
1337 
1338  template <typename _Tp, typename _Up>
1339  constexpr const _Tp&&
1340  get(const pair<_Up, _Tp>&& __p) noexcept
1341  { return std::move(__p.second); }
1342 #endif // __glibcxx_tuples_by_type
1343 
1344 
1345 #if __glibcxx_ranges_zip // >= C++23
1346  template<typename _T1, typename _T2, typename _U1, typename _U2,
1347  template<typename> class _TQual, template<typename> class _UQual>
1348  requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1349  common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
1350  struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
1351  {
1352  using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1353  common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
1354  };
1355 
1356  template<typename _T1, typename _T2, typename _U1, typename _U2>
1357  requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
1358  struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
1359  { using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; };
1360 #endif // C++23
1361 
1362  /// @}
1363 #endif // C++11
1364 
1365 _GLIBCXX_END_NAMESPACE_VERSION
1366 } // namespace std
1367 
1368 #endif /* _STL_PAIR_H */
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:866
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:116
pair(_T1, _T2) -> pair< _T1, _T2 >
Two pairs are equal iff their members are equal.
constexpr enable_if< __and_< __is_swappable< _T1 >, __is_swappable< _T2 > >::value >::type swap(pair< _T1, _T2 > &__x, pair< _T1, _T2 > &__y) noexcept(noexcept(__x.swap(__y)))
Definition: stl_pair.h:1121
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
Definition: stl_pair.h:82
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Definition: stl_pair.h:1164
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:72
constexpr common_comparison_category_t< __detail::__synth3way_t< _T1, _U1 >, __detail::__synth3way_t< _T2, _U2 > > operator(const pair< _T1, _T2 > &__x, const pair< _U1, _U2 > &__y)
Definition: stl_pair.h:1049
ISO C++ entities toplevel namespace is std.
constexpr const _Tp && get(const pair< _Up, _Tp > &&__p) noexcept
Definition: stl_pair.h:1340
A standard container for storing a fixed size sequence of elements.
Definition: array:103
Primary class template, tuple.
Definition: tuple:834
integral_constant
Definition: type_traits:93
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:134
is_same
Definition: type_traits:1540
is_constructible
Definition: type_traits:1158
is_default_constructible
Definition: type_traits:1167
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:304
constexpr pair(const _T1 &__a, const _T2 &__b)
Construct from two const lvalues, allowing implicit conversions.
Definition: stl_pair.h:772
_T1 first
The first member.
Definition: stl_pair.h:308
_T1 first_type
The type of the first member.
Definition: stl_pair.h:305
constexpr void swap(pair &__p) noexcept(__and_< __is_nothrow_swappable< _T1 >, __is_nothrow_swappable< _T2 >>::value)
Swap the first members and then the second members.
Definition: stl_pair.h:321
constexpr pair(const pair &)=default
Copy constructor.
constexpr pair()
Definition: stl_pair.h:745
_T2 second_type
The type of the second member.
Definition: stl_pair.h:306
constexpr pair(pair &&)=default
Move constructor.
_T2 second
The second member.
Definition: stl_pair.h:309
Tag type for piecewise construction of std::pair objects.
Definition: stl_pair.h:79
Finds the size of a given tuple type.
Definition: utility.h:51
Gives the type of the ith element of a given tuple type.
Definition: utility.h:82