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