master
  1//===----------------------------------------------------------------------===//
  2//
  3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4// See https://llvm.org/LICENSE.txt for license information.
  5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6//
  7//===----------------------------------------------------------------------===//
  8
  9#ifndef _LIBCPP___UTILITY_PAIR_H
 10#define _LIBCPP___UTILITY_PAIR_H
 11
 12#include <__compare/common_comparison_category.h>
 13#include <__compare/synth_three_way.h>
 14#include <__concepts/boolean_testable.h>
 15#include <__concepts/different_from.h>
 16#include <__config>
 17#include <__cstddef/size_t.h>
 18#include <__fwd/array.h>
 19#include <__fwd/pair.h>
 20#include <__fwd/tuple.h>
 21#include <__tuple/tuple_indices.h>
 22#include <__tuple/tuple_like_no_subrange.h>
 23#include <__tuple/tuple_size.h>
 24#include <__type_traits/common_reference.h>
 25#include <__type_traits/common_type.h>
 26#include <__type_traits/conditional.h>
 27#include <__type_traits/enable_if.h>
 28#include <__type_traits/integral_constant.h>
 29#include <__type_traits/is_assignable.h>
 30#include <__type_traits/is_constructible.h>
 31#include <__type_traits/is_convertible.h>
 32#include <__type_traits/is_implicitly_default_constructible.h>
 33#include <__type_traits/is_nothrow_assignable.h>
 34#include <__type_traits/is_nothrow_constructible.h>
 35#include <__type_traits/is_replaceable.h>
 36#include <__type_traits/is_same.h>
 37#include <__type_traits/is_swappable.h>
 38#include <__type_traits/is_trivially_relocatable.h>
 39#include <__type_traits/nat.h>
 40#include <__type_traits/unwrap_ref.h>
 41#include <__utility/declval.h>
 42#include <__utility/forward.h>
 43#include <__utility/move.h>
 44#include <__utility/piecewise_construct.h>
 45
 46#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 47#  pragma GCC system_header
 48#endif
 49
 50_LIBCPP_PUSH_MACROS
 51#include <__undef_macros>
 52
 53_LIBCPP_BEGIN_NAMESPACE_STD
 54
 55#ifndef _LIBCPP_CXX03_LANG
 56
 57template <class _T1, class _T2>
 58struct __check_pair_construction {
 59  template <int&...>
 60  static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
 61    return __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value;
 62  }
 63
 64  template <int&...>
 65  static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_default() {
 66    return is_default_constructible<_T1>::value && is_default_constructible<_T2>::value;
 67  }
 68
 69  template <class _U1, class _U2>
 70  static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
 71    return is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value;
 72  }
 73
 74  template <class _U1, class _U2>
 75  static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
 76    return is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value;
 77  }
 78};
 79
 80#endif
 81
 82template <class, class>
 83struct __non_trivially_copyable_base {
 84  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {}
 85  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
 86  __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
 87};
 88
 89template <class _T1, class _T2>
 90struct pair
 91#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
 92    : private __non_trivially_copyable_base<_T1, _T2>
 93#endif
 94{
 95  using first_type  = _T1;
 96  using second_type = _T2;
 97
 98  _T1 first;
 99  _T2 second;
100
101  using __trivially_relocatable _LIBCPP_NODEBUG =
102      __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
103                      pair,
104                      void>;
105  using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_T1> && __is_replaceable_v<_T2>, pair, void>;
106
107  _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
108  _LIBCPP_HIDE_FROM_ABI pair(pair&&)      = default;
109
110#ifdef _LIBCPP_CXX03_LANG
111  _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {}
112
113  _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
114
115  template <class _U1, class _U2>
116  _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
117
118  _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) {
119    first  = __p.first;
120    second = __p.second;
121    return *this;
122  }
123
124  // Extension: This is provided in C++03 because it allows properly handling the
125  //            assignment to a pair containing references, which would be a hard
126  //            error otherwise.
127  template <
128      class _U1,
129      class _U2,
130      __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value,
131                    int> = 0>
132  _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) {
133    first  = __p.first;
134    second = __p.second;
135    return *this;
136  }
137#else
138  template <class _CheckArgsDep                                   = __check_pair_construction<_T1, _T2>,
139            __enable_if_t<_CheckArgsDep::__enable_default(), int> = 0>
140  explicit(!_CheckArgsDep::__enable_implicit_default()) _LIBCPP_HIDE_FROM_ABI constexpr pair() noexcept(
141      is_nothrow_default_constructible<first_type>::value && is_nothrow_default_constructible<second_type>::value)
142      : first(), second() {}
143
144  template <class _CheckArgsDep = __check_pair_construction<_T1, _T2>,
145            __enable_if_t<_CheckArgsDep::template __is_pair_constructible<_T1 const&, _T2 const&>(), int> = 0>
146  _LIBCPP_HIDE_FROM_ABI
147  _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgsDep::template __is_implicit<_T1 const&, _T2 const&>())
148      pair(_T1 const& __t1, _T2 const& __t2) noexcept(is_nothrow_copy_constructible<first_type>::value &&
149                                                      is_nothrow_copy_constructible<second_type>::value)
150      : first(__t1), second(__t2) {}
151
152  template <
153#  if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
154      class _U1 = _T1,
155      class _U2 = _T2,
156#  else
157      class _U1,
158      class _U2,
159#  endif
160      __enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1, _U2>(), int> = 0 >
161  _LIBCPP_HIDE_FROM_ABI
162  _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1, _U2>())
163      pair(_U1&& __u1, _U2&& __u2) noexcept(is_nothrow_constructible<first_type, _U1>::value &&
164                                            is_nothrow_constructible<second_type, _U2>::value)
165      : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
166  }
167
168#  if _LIBCPP_STD_VER >= 23
169  template <class _U1,
170            class _U2,
171            __enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1&, _U2&>(), int> = 0>
172  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&, _U2&>())
173      pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
174                                          is_nothrow_constructible<second_type, _U2&>::value))
175      : first(__p.first), second(__p.second) {}
176#  endif
177
178  template <
179      class _U1,
180      class _U2,
181      __enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1 const&, _U2 const&>(),
182                    int> = 0>
183  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(
184      !__check_pair_construction<_T1, _T2>::template __is_implicit<_U1 const&, _U2 const&>())
185      pair(pair<_U1, _U2> const& __p) noexcept(is_nothrow_constructible<first_type, _U1 const&>::value &&
186                                               is_nothrow_constructible<second_type, _U2 const&>::value)
187      : first(__p.first), second(__p.second) {}
188
189  template <class _U1,
190            class _U2,
191            __enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1, _U2>(), int> = 0>
192  _LIBCPP_HIDE_FROM_ABI
193  _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1, _U2>())
194      pair(pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, _U1&&>::value &&
195                                          is_nothrow_constructible<second_type, _U2&&>::value)
196      : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
197
198#  if _LIBCPP_STD_VER >= 23
199  template <
200      class _U1,
201      class _U2,
202      __enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<const _U1&&, const _U2&&>(),
203                    int> = 0>
204  _LIBCPP_HIDE_FROM_ABI constexpr explicit(
205      !__check_pair_construction<_T1, _T2>::template __is_implicit<const _U1&&, const _U2&&>())
206      pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
207                                                is_nothrow_constructible<second_type, const _U2&&>::value)
208      : first(std::move(__p.first)), second(std::move(__p.second)) {}
209#  endif
210
211#  if _LIBCPP_STD_VER >= 23
212  template <__pair_like_no_subrange _PairLike>
213    requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
214             is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>)
215  _LIBCPP_HIDE_FROM_ABI constexpr explicit(
216      !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
217      !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>) pair(_PairLike&& __p)
218      : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
219#  endif
220
221  template <class... _Args1, class... _Args2>
222  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
223  pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept(
224      is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value)
225      : pair(__pc,
226             __first_args,
227             __second_args,
228             typename __make_tuple_indices<sizeof...(_Args1)>::type(),
229             typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
230
231  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
232  operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
233                            pair,
234                            __nat> const& __p) noexcept(is_nothrow_copy_assignable<first_type>::value &&
235                                                        is_nothrow_copy_assignable<second_type>::value) {
236    first  = __p.first;
237    second = __p.second;
238    return *this;
239  }
240
241  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(
242      __conditional_t<is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
243          __p) noexcept(is_nothrow_move_assignable<first_type>::value &&
244                        is_nothrow_move_assignable<second_type>::value) {
245    first  = std::forward<first_type>(__p.first);
246    second = std::forward<second_type>(__p.second);
247    return *this;
248  }
249
250  template <
251      class _U1,
252      class _U2,
253      __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value,
254                    int> = 0>
255  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) {
256    first  = __p.first;
257    second = __p.second;
258    return *this;
259  }
260
261  template <class _U1,
262            class _U2,
263            __enable_if_t<is_assignable<first_type&, _U1>::value && is_assignable<second_type&, _U2>::value, int> = 0>
264  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) {
265    first  = std::forward<_U1>(__p.first);
266    second = std::forward<_U2>(__p.second);
267    return *this;
268  }
269
270#  if _LIBCPP_STD_VER >= 23
271  template <class = void>
272  _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const
273      noexcept(is_nothrow_copy_assignable_v<const first_type> && is_nothrow_copy_assignable_v<const second_type>)
274    requires(is_copy_assignable_v<const first_type> && is_copy_assignable_v<const second_type>)
275  {
276    first  = __p.first;
277    second = __p.second;
278    return *this;
279  }
280
281  template <class = void>
282  _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const
283      noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
284               is_nothrow_assignable_v<const second_type&, second_type>)
285    requires(is_assignable_v<const first_type&, first_type> && is_assignable_v<const second_type&, second_type>)
286  {
287    first  = std::forward<first_type>(__p.first);
288    second = std::forward<second_type>(__p.second);
289    return *this;
290  }
291
292  template <class _U1, class _U2>
293  _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const
294    requires(is_assignable_v<const first_type&, const _U1&> && is_assignable_v<const second_type&, const _U2&>)
295  {
296    first  = __p.first;
297    second = __p.second;
298    return *this;
299  }
300
301  template <class _U1, class _U2>
302  _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const
303    requires(is_assignable_v<const first_type&, _U1> && is_assignable_v<const second_type&, _U2>)
304  {
305    first  = std::forward<_U1>(__p.first);
306    second = std::forward<_U2>(__p.second);
307    return *this;
308  }
309
310  template <__pair_like_no_subrange _PairLike>
311    requires(__different_from<_PairLike, pair> &&
312             is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
313             is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
314  _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
315    first  = std::get<0>(std::forward<_PairLike>(__p));
316    second = std::get<1>(std::forward<_PairLike>(__p));
317    return *this;
318  }
319
320  template <__pair_like_no_subrange _PairLike>
321    requires(__different_from<_PairLike, pair> &&
322             is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
323             is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
324  _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
325    first  = std::get<0>(std::forward<_PairLike>(__p));
326    second = std::get<1>(std::forward<_PairLike>(__p));
327    return *this;
328  }
329#  endif // _LIBCPP_STD_VER >= 23
330
331  // Prior to C++23, we provide an approximation of constructors and assignment operators from
332  // pair-like types. This was historically provided as an extension.
333#  if _LIBCPP_STD_VER < 23
334  // from std::tuple
335  template <class _U1,
336            class _U2,
337            __enable_if_t<is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value, int> = 0>
338  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2> const& __p)
339      : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
340
341  template < class _U1,
342             class _U2,
343             __enable_if_t<is_constructible<_T1, _U1 const&>::value && is_constructible<_T2, _U2 const&>::value &&
344                               !(is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value),
345                           int> = 0>
346  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2> const& __p)
347      : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
348
349  template <class _U1,
350            class _U2,
351            __enable_if_t<is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value, int> = 0>
352  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2>&& __p)
353      : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
354
355  template <class _U1,
356            class _U2,
357            __enable_if_t<is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value &&
358                          !(is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value) > = 0>
359  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2>&& __p)
360      : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
361
362  template <class _U1,
363            class _U2,
364            __enable_if_t<is_assignable<_T1&, _U1 const&>::value && is_assignable<_T2&, _U2 const&>::value, int> = 0>
365  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) {
366    first  = std::get<0>(__p);
367    second = std::get<1>(__p);
368    return *this;
369  }
370
371  template <class _U1,
372            class _U2,
373            __enable_if_t<is_assignable<_T1&, _U1&&>::value && is_assignable<_T2&, _U2&&>::value, int> = 0>
374  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) {
375    first  = std::get<0>(std::move(__p));
376    second = std::get<1>(std::move(__p));
377    return *this;
378  }
379
380  // from std::array
381  template <class _Up,
382            __enable_if_t<is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value, int> = 0>
383  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2> const& __p) : first(__p[0]), second(__p[1]) {}
384
385  template <class _Up,
386            __enable_if_t<is_constructible<_T1, _Up const&>::value && is_constructible<_T2, _Up const&>::value &&
387                              !(is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value),
388                          int> = 0>
389  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2> const& __p)
390      : first(__p[0]), second(__p[1]) {}
391
392  template <class _Up, __enable_if_t< is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value, int> = 0>
393  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2>&& __p)
394      : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
395
396  template <class _Up,
397            __enable_if_t<is_constructible<_T1, _Up>::value && is_constructible<_T2, _Up>::value &&
398                              !(is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value),
399                          int> = 0>
400  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2>&& __p)
401      : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
402
403  template <class _Up,
404            __enable_if_t<is_assignable<_T1&, _Up const&>::value && is_assignable<_T2&, _Up const&>::value, int> = 0>
405  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) {
406    first  = std::get<0>(__p);
407    second = std::get<1>(__p);
408    return *this;
409  }
410
411  template <class _Up, __enable_if_t<is_assignable<_T1&, _Up>::value && is_assignable<_T2&, _Up>::value, int> = 0>
412  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) {
413    first  = std::get<0>(std::move(__p));
414    second = std::get<1>(std::move(__p));
415    return *this;
416  }
417#  endif // _LIBCPP_STD_VER < 23
418#endif   // _LIBCPP_CXX03_LANG
419
420  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair& __p)
421      _NOEXCEPT_(__is_nothrow_swappable_v<first_type>&& __is_nothrow_swappable_v<second_type>) {
422    using std::swap;
423    swap(first, __p.first);
424    swap(second, __p.second);
425  }
426
427#if _LIBCPP_STD_VER >= 23
428  _LIBCPP_HIDE_FROM_ABI constexpr void swap(const pair& __p) const
429      noexcept(__is_nothrow_swappable_v<const first_type> && __is_nothrow_swappable_v<const second_type>) {
430    using std::swap;
431    swap(first, __p.first);
432    swap(second, __p.second);
433  }
434#endif
435
436private:
437#ifndef _LIBCPP_CXX03_LANG
438  template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
439  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
440  pair(piecewise_construct_t,
441       tuple<_Args1...>& __first_args,
442       tuple<_Args2...>& __second_args,
443       __tuple_indices<_I1...>,
444       __tuple_indices<_I2...>)
445      : first(std::forward<_Args1>(std::get<_I1>(__first_args))...),
446        second(std::forward<_Args2>(std::get<_I2>(__second_args))...) {}
447#endif
448};
449
450#if _LIBCPP_STD_VER >= 17
451template <class _T1, class _T2>
452pair(_T1, _T2) -> pair<_T1, _T2>;
453#endif
454
455// [pairs.spec], specialized algorithms
456
457template <class _T1, class _T2, class _U1, class _U2>
458inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
459operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
460#if _LIBCPP_STD_VER >= 26
461  requires requires {
462    { __x.first == __y.first } -> __boolean_testable;
463    { __x.second == __y.second } -> __boolean_testable;
464  }
465#endif
466{
467  return __x.first == __y.first && __x.second == __y.second;
468}
469
470#if _LIBCPP_STD_VER >= 20
471
472template <class _T1, class _T2, class _U1, class _U2>
473_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t< __synth_three_way_result<_T1, _U1>,
474                                                              __synth_three_way_result<_T2, _U2> >
475operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
476  if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
477    return __c;
478  }
479  return std::__synth_three_way(__x.second, __y.second);
480}
481
482#else // _LIBCPP_STD_VER >= 20
483
484template <class _T1, class _T2, class _U1, class _U2>
485inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
486operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
487  return !(__x == __y);
488}
489
490template <class _T1, class _T2, class _U1, class _U2>
491inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
492operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
493  return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
494}
495
496template <class _T1, class _T2, class _U1, class _U2>
497inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
498operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
499  return __y < __x;
500}
501
502template <class _T1, class _T2, class _U1, class _U2>
503inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
504operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
505  return !(__x < __y);
506}
507
508template <class _T1, class _T2, class _U1, class _U2>
509inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
510operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
511  return !(__y < __x);
512}
513
514#endif // _LIBCPP_STD_VER >= 20
515
516#if _LIBCPP_STD_VER >= 23
517template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual>
518  requires requires {
519    typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
520  }
521struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
522  using type _LIBCPP_NODEBUG =
523      pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
524};
525
526template <class _T1, class _T2, class _U1, class _U2>
527  requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
528struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
529  using type _LIBCPP_NODEBUG = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
530};
531#endif // _LIBCPP_STD_VER >= 23
532
533template <class _T1, class _T2, __enable_if_t<__is_swappable_v<_T1> && __is_swappable_v<_T2>, int> = 0>
534inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
535    _NOEXCEPT_(__is_nothrow_swappable_v<_T1>&& __is_nothrow_swappable_v<_T2>) {
536  __x.swap(__y);
537}
538
539#if _LIBCPP_STD_VER >= 23
540template <class _T1, class _T2>
541  requires(__is_swappable_v<const _T1> && __is_swappable_v<const _T2>)
542_LIBCPP_HIDE_FROM_ABI constexpr void
543swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) {
544  __x.swap(__y);
545}
546#endif
547
548template <class _T1, class _T2>
549inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >
550make_pair(_T1&& __t1, _T2&& __t2) {
551  return pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >(std::forward<_T1>(__t1), std::forward<_T2>(__t2));
552}
553
554template <class _T1, class _T2>
555struct tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {};
556
557template <size_t _Ip, class _T1, class _T2>
558struct tuple_element<_Ip, pair<_T1, _T2> > {
559  static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
560};
561
562template <class _T1, class _T2>
563struct tuple_element<0, pair<_T1, _T2> > {
564  using type _LIBCPP_NODEBUG = _T1;
565};
566
567template <class _T1, class _T2>
568struct tuple_element<1, pair<_T1, _T2> > {
569  using type _LIBCPP_NODEBUG = _T2;
570};
571
572template <size_t _Ip>
573struct __get_pair;
574
575template <>
576struct __get_pair<0> {
577  template <class _T1, class _T2>
578  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
579    return __p.first;
580  }
581
582  template <class _T1, class _T2>
583  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
584    return __p.first;
585  }
586
587  template <class _T1, class _T2>
588  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
589    return std::forward<_T1>(__p.first);
590  }
591
592  template <class _T1, class _T2>
593  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
594    return std::forward<const _T1>(__p.first);
595  }
596};
597
598template <>
599struct __get_pair<1> {
600  template <class _T1, class _T2>
601  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
602    return __p.second;
603  }
604
605  template <class _T1, class _T2>
606  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
607    return __p.second;
608  }
609
610  template <class _T1, class _T2>
611  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
612    return std::forward<_T2>(__p.second);
613  }
614
615  template <class _T1, class _T2>
616  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
617    return std::forward<const _T2>(__p.second);
618  }
619};
620
621template <size_t _Ip, class _T1, class _T2>
622inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
623get(pair<_T1, _T2>& __p) _NOEXCEPT {
624  return __get_pair<_Ip>::get(__p);
625}
626
627template <size_t _Ip, class _T1, class _T2>
628inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
629get(const pair<_T1, _T2>& __p) _NOEXCEPT {
630  return __get_pair<_Ip>::get(__p);
631}
632
633template <size_t _Ip, class _T1, class _T2>
634inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
635get(pair<_T1, _T2>&& __p) _NOEXCEPT {
636  return __get_pair<_Ip>::get(std::move(__p));
637}
638
639template <size_t _Ip, class _T1, class _T2>
640inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
641get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
642  return __get_pair<_Ip>::get(std::move(__p));
643}
644
645#if _LIBCPP_STD_VER >= 14
646template <class _T1, class _T2>
647inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
648  return __p.first;
649}
650
651template <class _T1, class _T2>
652inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
653  return __p.first;
654}
655
656template <class _T1, class _T2>
657inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
658  return std::forward<_T1&&>(__p.first);
659}
660
661template <class _T1, class _T2>
662inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
663  return std::forward<_T1 const&&>(__p.first);
664}
665
666template <class _T2, class _T1>
667inline _LIBCPP_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
668  return __p.second;
669}
670
671template <class _T2, class _T1>
672inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
673  return __p.second;
674}
675
676template <class _T2, class _T1>
677inline _LIBCPP_HIDE_FROM_ABI constexpr _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
678  return std::forward<_T2&&>(__p.second);
679}
680
681template <class _T2, class _T1>
682inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
683  return std::forward<_T2 const&&>(__p.second);
684}
685
686#endif // _LIBCPP_STD_VER >= 14
687
688_LIBCPP_END_NAMESPACE_STD
689
690_LIBCPP_POP_MACROS
691
692#endif // _LIBCPP___UTILITY_PAIR_H