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