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