xref: /freebsd/contrib/llvm-project/libcxx/include/__utility/pair.h (revision 4f5890a0fb086324a657f3cd7ba1abc57274e0db)
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 <__config>
15 #include <__functional/unwrap_ref.h>
16 #include <__tuple>
17 #include <__utility/forward.h>
18 #include <__utility/move.h>
19 #include <__utility/piecewise_construct.h>
20 #include <cstddef>
21 #include <type_traits>
22 
23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24 #pragma GCC system_header
25 #endif
26 
27 _LIBCPP_BEGIN_NAMESPACE_STD
28 
29 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
30 template <class, class>
31 struct __non_trivially_copyable_base {
32   _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
33   __non_trivially_copyable_base() _NOEXCEPT {}
34   _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
35   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
36 };
37 #endif
38 
39 template <class _T1, class _T2>
40 struct _LIBCPP_TEMPLATE_VIS pair
41 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
42 : private __non_trivially_copyable_base<_T1, _T2>
43 #endif
44 {
45     typedef _T1 first_type;
46     typedef _T2 second_type;
47 
48     _T1 first;
49     _T2 second;
50 
51 #if !defined(_LIBCPP_CXX03_LANG)
52     pair(pair const&) = default;
53     pair(pair&&) = default;
54 #else
55   // Use the implicitly declared copy constructor in C++03
56 #endif
57 
58 #ifdef _LIBCPP_CXX03_LANG
59     _LIBCPP_INLINE_VISIBILITY
60     pair() : first(), second() {}
61 
62     _LIBCPP_INLINE_VISIBILITY
63     pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
64 
65     template <class _U1, class _U2>
66     _LIBCPP_INLINE_VISIBILITY
67     pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
68 
69     _LIBCPP_INLINE_VISIBILITY
70     pair& operator=(pair const& __p) {
71         first = __p.first;
72         second = __p.second;
73         return *this;
74     }
75 #else
76     struct _CheckArgs {
77       template <int&...>
78       static constexpr bool __enable_explicit_default() {
79           return is_default_constructible<_T1>::value
80               && is_default_constructible<_T2>::value
81               && !__enable_implicit_default<>();
82       }
83 
84       template <int&...>
85       static constexpr bool __enable_implicit_default() {
86           return __is_implicitly_default_constructible<_T1>::value
87               && __is_implicitly_default_constructible<_T2>::value;
88       }
89 
90       template <class _U1, class _U2>
91       static constexpr bool __enable_explicit() {
92           return is_constructible<first_type, _U1>::value
93               && is_constructible<second_type, _U2>::value
94               && (!is_convertible<_U1, first_type>::value
95                   || !is_convertible<_U2, second_type>::value);
96       }
97 
98       template <class _U1, class _U2>
99       static constexpr bool __enable_implicit() {
100           return is_constructible<first_type, _U1>::value
101               && is_constructible<second_type, _U2>::value
102               && is_convertible<_U1, first_type>::value
103               && is_convertible<_U2, second_type>::value;
104       }
105     };
106 
107     template <bool _MaybeEnable>
108     using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
109       _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
110 
111     struct _CheckTupleLikeConstructor {
112         template <class _Tuple>
113         static constexpr bool __enable_implicit() {
114             return __tuple_convertible<_Tuple, pair>::value;
115         }
116 
117         template <class _Tuple>
118         static constexpr bool __enable_explicit() {
119             return __tuple_constructible<_Tuple, pair>::value
120                && !__tuple_convertible<_Tuple, pair>::value;
121         }
122 
123         template <class _Tuple>
124         static constexpr bool __enable_assign() {
125             return __tuple_assignable<_Tuple, pair>::value;
126         }
127     };
128 
129     template <class _Tuple>
130     using _CheckTLC _LIBCPP_NODEBUG = typename conditional<
131         __tuple_like_with_size<_Tuple, 2>::value
132             && !is_same<typename decay<_Tuple>::type, pair>::value,
133         _CheckTupleLikeConstructor,
134         __check_tuple_constructor_fail
135     >::type;
136 
137     template<bool _Dummy = true, typename enable_if<
138             _CheckArgsDep<_Dummy>::__enable_explicit_default()
139     >::type* = nullptr>
140     explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
141     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
142                       is_nothrow_default_constructible<second_type>::value)
143         : first(), second() {}
144 
145     template<bool _Dummy = true, typename enable_if<
146             _CheckArgsDep<_Dummy>::__enable_implicit_default()
147     >::type* = nullptr>
148     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
149     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
150                       is_nothrow_default_constructible<second_type>::value)
151         : first(), second() {}
152 
153     template <bool _Dummy = true, typename enable_if<
154              _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
155     >::type* = nullptr>
156     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
157     explicit pair(_T1 const& __t1, _T2 const& __t2)
158         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
159                    is_nothrow_copy_constructible<second_type>::value)
160         : first(__t1), second(__t2) {}
161 
162     template<bool _Dummy = true, typename enable_if<
163             _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
164     >::type* = nullptr>
165     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
166     pair(_T1 const& __t1, _T2 const& __t2)
167         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
168                    is_nothrow_copy_constructible<second_type>::value)
169         : first(__t1), second(__t2) {}
170 
171     template <
172 #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
173         class _U1 = _T1, class _U2 = _T2,
174 #else
175         class _U1, class _U2,
176 #endif
177         typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr
178     >
179     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
180     explicit pair(_U1&& __u1, _U2&& __u2)
181         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
182                     is_nothrow_constructible<second_type, _U2>::value))
183         : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
184 
185     template <
186 #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951
187         class _U1 = _T1, class _U2 = _T2,
188 #else
189         class _U1, class _U2,
190 #endif
191         typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr
192     >
193     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
194     pair(_U1&& __u1, _U2&& __u2)
195         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
196                     is_nothrow_constructible<second_type, _U2>::value))
197         : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
198 
199     template<class _U1, class _U2, typename enable_if<
200             _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
201     >::type* = nullptr>
202     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
203     explicit pair(pair<_U1, _U2> const& __p)
204         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
205                     is_nothrow_constructible<second_type, _U2 const&>::value))
206         : first(__p.first), second(__p.second) {}
207 
208     template<class _U1, class _U2, typename enable_if<
209             _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
210     >::type* = nullptr>
211     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
212     pair(pair<_U1, _U2> const& __p)
213         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
214                     is_nothrow_constructible<second_type, _U2 const&>::value))
215         : first(__p.first), second(__p.second) {}
216 
217     template<class _U1, class _U2, typename enable_if<
218             _CheckArgs::template __enable_explicit<_U1, _U2>()
219     >::type* = nullptr>
220     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
221     explicit pair(pair<_U1, _U2>&&__p)
222         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
223                     is_nothrow_constructible<second_type, _U2&&>::value))
224         : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
225 
226     template<class _U1, class _U2, typename enable_if<
227             _CheckArgs::template __enable_implicit<_U1, _U2>()
228     >::type* = nullptr>
229     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
230     pair(pair<_U1, _U2>&& __p)
231         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
232                     is_nothrow_constructible<second_type, _U2&&>::value))
233         : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
234 
235     template<class _Tuple, typename enable_if<
236             _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
237     >::type* = nullptr>
238     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
239     explicit pair(_Tuple&& __p)
240         : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
241           second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
242 
243     template<class _Tuple, typename enable_if<
244             _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
245     >::type* = nullptr>
246     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
247     pair(_Tuple&& __p)
248         : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
249           second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
250 
251     template <class... _Args1, class... _Args2>
252     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
253     pair(piecewise_construct_t __pc,
254          tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
255         _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
256                     is_nothrow_constructible<second_type, _Args2...>::value))
257         : pair(__pc, __first_args, __second_args,
258                 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
259                 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
260 
261     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
262     pair& operator=(typename conditional<
263                         is_copy_assignable<first_type>::value &&
264                         is_copy_assignable<second_type>::value,
265                     pair, __nat>::type const& __p)
266         _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
267                    is_nothrow_copy_assignable<second_type>::value)
268     {
269         first = __p.first;
270         second = __p.second;
271         return *this;
272     }
273 
274     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
275     pair& operator=(typename conditional<
276                         is_move_assignable<first_type>::value &&
277                         is_move_assignable<second_type>::value,
278                     pair, __nat>::type&& __p)
279         _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
280                    is_nothrow_move_assignable<second_type>::value)
281     {
282         first = _VSTD::forward<first_type>(__p.first);
283         second = _VSTD::forward<second_type>(__p.second);
284         return *this;
285     }
286 
287     template <class _Tuple, typename enable_if<
288             _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
289      >::type* = nullptr>
290     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
291     pair& operator=(_Tuple&& __p) {
292         first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
293         second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
294         return *this;
295     }
296 #endif
297 
298     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
299     void
300     swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
301                                __is_nothrow_swappable<second_type>::value)
302     {
303         using _VSTD::swap;
304         swap(first,  __p.first);
305         swap(second, __p.second);
306     }
307 private:
308 
309 #ifndef _LIBCPP_CXX03_LANG
310     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
311     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
312     pair(piecewise_construct_t,
313          tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
314          __tuple_indices<_I1...>, __tuple_indices<_I2...>);
315 #endif
316 };
317 
318 #if _LIBCPP_STD_VER >= 17
319 template<class _T1, class _T2>
320 pair(_T1, _T2) -> pair<_T1, _T2>;
321 #endif
322 
323 // [pairs.spec], specialized algorithms
324 
325 template <class _T1, class _T2>
326 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
327 bool
328 operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
329 {
330     return __x.first == __y.first && __x.second == __y.second;
331 }
332 
333 #if !defined(_LIBCPP_HAS_NO_CONCEPTS)
334 
335 template <class _T1, class _T2>
336 _LIBCPP_HIDE_FROM_ABI constexpr
337 common_comparison_category_t<
338         __synth_three_way_result<_T1>,
339         __synth_three_way_result<_T2> >
340 operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
341 {
342     if (auto __c = _VSTD::__synth_three_way(__x.first, __y.first); __c != 0) {
343       return __c;
344     }
345     return _VSTD::__synth_three_way(__x.second, __y.second);
346 }
347 
348 #else // !defined(_LIBCPP_HAS_NO_CONCEPTS)
349 
350 template <class _T1, class _T2>
351 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
352 bool
353 operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
354 {
355     return !(__x == __y);
356 }
357 
358 template <class _T1, class _T2>
359 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
360 bool
361 operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
362 {
363     return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
364 }
365 
366 template <class _T1, class _T2>
367 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
368 bool
369 operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
370 {
371     return __y < __x;
372 }
373 
374 template <class _T1, class _T2>
375 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
376 bool
377 operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
378 {
379     return !(__x < __y);
380 }
381 
382 template <class _T1, class _T2>
383 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
384 bool
385 operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
386 {
387     return !(__y < __x);
388 }
389 
390 #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
391 
392 template <class _T1, class _T2>
393 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
394 typename enable_if
395 <
396     __is_swappable<_T1>::value &&
397     __is_swappable<_T2>::value,
398     void
399 >::type
400 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
401                      _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
402                                  __is_nothrow_swappable<_T2>::value))
403 {
404     __x.swap(__y);
405 }
406 
407 #ifndef _LIBCPP_CXX03_LANG
408 
409 template <class _T1, class _T2>
410 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
411 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
412 make_pair(_T1&& __t1, _T2&& __t2)
413 {
414     return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
415                (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
416 }
417 
418 #else  // _LIBCPP_CXX03_LANG
419 
420 template <class _T1, class _T2>
421 inline _LIBCPP_INLINE_VISIBILITY
422 pair<_T1,_T2>
423 make_pair(_T1 __x, _T2 __y)
424 {
425     return pair<_T1, _T2>(__x, __y);
426 }
427 
428 #endif // _LIBCPP_CXX03_LANG
429 
430 template <class _T1, class _T2>
431   struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
432     : public integral_constant<size_t, 2> {};
433 
434 template <size_t _Ip, class _T1, class _T2>
435 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
436 {
437     static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
438 };
439 
440 template <class _T1, class _T2>
441 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
442 {
443     typedef _LIBCPP_NODEBUG _T1 type;
444 };
445 
446 template <class _T1, class _T2>
447 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
448 {
449     typedef _LIBCPP_NODEBUG _T2 type;
450 };
451 
452 template <size_t _Ip> struct __get_pair;
453 
454 template <>
455 struct __get_pair<0>
456 {
457     template <class _T1, class _T2>
458     static
459     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
460     _T1&
461     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
462 
463     template <class _T1, class _T2>
464     static
465     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
466     const _T1&
467     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
468 
469 #ifndef _LIBCPP_CXX03_LANG
470     template <class _T1, class _T2>
471     static
472     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
473     _T1&&
474     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
475 
476     template <class _T1, class _T2>
477     static
478     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
479     const _T1&&
480     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
481 #endif // _LIBCPP_CXX03_LANG
482 };
483 
484 template <>
485 struct __get_pair<1>
486 {
487     template <class _T1, class _T2>
488     static
489     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
490     _T2&
491     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
492 
493     template <class _T1, class _T2>
494     static
495     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
496     const _T2&
497     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
498 
499 #ifndef _LIBCPP_CXX03_LANG
500     template <class _T1, class _T2>
501     static
502     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
503     _T2&&
504     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
505 
506     template <class _T1, class _T2>
507     static
508     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
509     const _T2&&
510     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
511 #endif // _LIBCPP_CXX03_LANG
512 };
513 
514 template <size_t _Ip, class _T1, class _T2>
515 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
516 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
517 get(pair<_T1, _T2>& __p) _NOEXCEPT
518 {
519     return __get_pair<_Ip>::get(__p);
520 }
521 
522 template <size_t _Ip, class _T1, class _T2>
523 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
524 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
525 get(const pair<_T1, _T2>& __p) _NOEXCEPT
526 {
527     return __get_pair<_Ip>::get(__p);
528 }
529 
530 #ifndef _LIBCPP_CXX03_LANG
531 template <size_t _Ip, class _T1, class _T2>
532 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
533 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
534 get(pair<_T1, _T2>&& __p) _NOEXCEPT
535 {
536     return __get_pair<_Ip>::get(_VSTD::move(__p));
537 }
538 
539 template <size_t _Ip, class _T1, class _T2>
540 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
541 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
542 get(const pair<_T1, _T2>&& __p) _NOEXCEPT
543 {
544     return __get_pair<_Ip>::get(_VSTD::move(__p));
545 }
546 #endif // _LIBCPP_CXX03_LANG
547 
548 #if _LIBCPP_STD_VER > 11
549 template <class _T1, class _T2>
550 inline _LIBCPP_INLINE_VISIBILITY
551 constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
552 {
553     return __get_pair<0>::get(__p);
554 }
555 
556 template <class _T1, class _T2>
557 inline _LIBCPP_INLINE_VISIBILITY
558 constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
559 {
560     return __get_pair<0>::get(__p);
561 }
562 
563 template <class _T1, class _T2>
564 inline _LIBCPP_INLINE_VISIBILITY
565 constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
566 {
567     return __get_pair<0>::get(_VSTD::move(__p));
568 }
569 
570 template <class _T1, class _T2>
571 inline _LIBCPP_INLINE_VISIBILITY
572 constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
573 {
574     return __get_pair<0>::get(_VSTD::move(__p));
575 }
576 
577 template <class _T1, class _T2>
578 inline _LIBCPP_INLINE_VISIBILITY
579 constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
580 {
581     return __get_pair<1>::get(__p);
582 }
583 
584 template <class _T1, class _T2>
585 inline _LIBCPP_INLINE_VISIBILITY
586 constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
587 {
588     return __get_pair<1>::get(__p);
589 }
590 
591 template <class _T1, class _T2>
592 inline _LIBCPP_INLINE_VISIBILITY
593 constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
594 {
595     return __get_pair<1>::get(_VSTD::move(__p));
596 }
597 
598 template <class _T1, class _T2>
599 inline _LIBCPP_INLINE_VISIBILITY
600 constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
601 {
602     return __get_pair<1>::get(_VSTD::move(__p));
603 }
604 
605 #endif
606 
607 _LIBCPP_END_NAMESPACE_STD
608 
609 #endif // _LIBCPP___UTILITY_PAIR_H
610