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 12349cc55cSDimitry Andric #include <__compare/common_comparison_category.h> 13349cc55cSDimitry 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> 108349cc55cSDimitry 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> 130349cc55cSDimitry 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 137349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 138fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::__enable_explicit_default() 139349cc55cSDimitry 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 145349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 146fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::__enable_implicit_default() 147349cc55cSDimitry 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 153349cc55cSDimitry Andric template <bool _Dummy = true, typename enable_if< 154fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>() 155349cc55cSDimitry 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 162349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 163fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>() 164349cc55cSDimitry 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 171349cc55cSDimitry Andric template < 172349cc55cSDimitry Andric #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951 173349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 174349cc55cSDimitry Andric #else 175349cc55cSDimitry Andric class _U1, class _U2, 176349cc55cSDimitry Andric #endif 177349cc55cSDimitry Andric typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr 178349cc55cSDimitry 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 185349cc55cSDimitry Andric template < 186349cc55cSDimitry Andric #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951 187349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 188349cc55cSDimitry Andric #else 189349cc55cSDimitry Andric class _U1, class _U2, 190349cc55cSDimitry Andric #endif 191349cc55cSDimitry Andric typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr 192349cc55cSDimitry 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 199349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 200fe6060f1SDimitry Andric _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>() 201349cc55cSDimitry 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 208349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 209fe6060f1SDimitry Andric _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>() 210349cc55cSDimitry 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 217349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 218fe6060f1SDimitry Andric _CheckArgs::template __enable_explicit<_U1, _U2>() 219349cc55cSDimitry 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 226349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 227fe6060f1SDimitry Andric _CheckArgs::template __enable_implicit<_U1, _U2>() 228349cc55cSDimitry 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 235349cc55cSDimitry Andric template<class _Tuple, typename enable_if< 236fe6060f1SDimitry Andric _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>() 237349cc55cSDimitry 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 243349cc55cSDimitry Andric template<class _Tuple, typename enable_if< 244fe6060f1SDimitry Andric _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>() 245349cc55cSDimitry 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 287349cc55cSDimitry Andric template <class _Tuple, typename enable_if< 288fe6060f1SDimitry Andric _CheckTLC<_Tuple>::template __enable_assign<_Tuple>() 289349cc55cSDimitry 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*81ad6265SDimitry Andric #if _LIBCPP_STD_VER > 14 319fe6060f1SDimitry Andric template<class _T1, class _T2> 320fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>; 321349cc55cSDimitry Andric #endif 322349cc55cSDimitry Andric 323349cc55cSDimitry 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*81ad6265SDimitry Andric #if _LIBCPP_STD_VER > 17 334349cc55cSDimitry Andric 335349cc55cSDimitry Andric template <class _T1, class _T2> 336349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 337349cc55cSDimitry Andric common_comparison_category_t< 338349cc55cSDimitry Andric __synth_three_way_result<_T1>, 339349cc55cSDimitry Andric __synth_three_way_result<_T2> > 340349cc55cSDimitry Andric operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 341349cc55cSDimitry Andric { 342349cc55cSDimitry Andric if (auto __c = _VSTD::__synth_three_way(__x.first, __y.first); __c != 0) { 343349cc55cSDimitry Andric return __c; 344349cc55cSDimitry Andric } 345349cc55cSDimitry Andric return _VSTD::__synth_three_way(__x.second, __y.second); 346349cc55cSDimitry Andric } 347349cc55cSDimitry Andric 348*81ad6265SDimitry Andric #else // _LIBCPP_STD_VER > 17 349349cc55cSDimitry 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*81ad6265SDimitry Andric #endif // _LIBCPP_STD_VER > 17 391*81ad6265SDimitry Andric 392*81ad6265SDimitry Andric #if _LIBCPP_STD_VER > 20 393*81ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual> 394*81ad6265SDimitry Andric requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 395*81ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; } 396*81ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> { 397*81ad6265SDimitry Andric using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 398*81ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 399*81ad6265SDimitry Andric }; 400*81ad6265SDimitry Andric 401*81ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 402*81ad6265SDimitry Andric requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; } 403*81ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { 404*81ad6265SDimitry Andric using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; 405*81ad6265SDimitry Andric }; 406*81ad6265SDimitry Andric #endif // _LIBCPP_STD_VER > 20 407349cc55cSDimitry Andric 408fe6060f1SDimitry Andric template <class _T1, class _T2> 409fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 410fe6060f1SDimitry Andric typename enable_if 411fe6060f1SDimitry Andric < 412fe6060f1SDimitry Andric __is_swappable<_T1>::value && 413fe6060f1SDimitry Andric __is_swappable<_T2>::value, 414fe6060f1SDimitry Andric void 415fe6060f1SDimitry Andric >::type 416fe6060f1SDimitry Andric swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 417fe6060f1SDimitry Andric _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && 418fe6060f1SDimitry Andric __is_nothrow_swappable<_T2>::value)) 419fe6060f1SDimitry Andric { 420fe6060f1SDimitry Andric __x.swap(__y); 421fe6060f1SDimitry Andric } 422fe6060f1SDimitry Andric 423fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 424fe6060f1SDimitry Andric 425fe6060f1SDimitry Andric template <class _T1, class _T2> 426fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 427fe6060f1SDimitry Andric pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 428fe6060f1SDimitry Andric make_pair(_T1&& __t1, _T2&& __t2) 429fe6060f1SDimitry Andric { 430fe6060f1SDimitry Andric return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 431fe6060f1SDimitry Andric (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); 432fe6060f1SDimitry Andric } 433fe6060f1SDimitry Andric 434fe6060f1SDimitry Andric #else // _LIBCPP_CXX03_LANG 435fe6060f1SDimitry Andric 436fe6060f1SDimitry Andric template <class _T1, class _T2> 437fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 438fe6060f1SDimitry Andric pair<_T1,_T2> 439fe6060f1SDimitry Andric make_pair(_T1 __x, _T2 __y) 440fe6060f1SDimitry Andric { 441fe6060f1SDimitry Andric return pair<_T1, _T2>(__x, __y); 442fe6060f1SDimitry Andric } 443fe6060f1SDimitry Andric 444fe6060f1SDimitry Andric #endif // _LIBCPP_CXX03_LANG 445fe6060f1SDimitry Andric 446fe6060f1SDimitry Andric template <class _T1, class _T2> 447fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > 448fe6060f1SDimitry Andric : public integral_constant<size_t, 2> {}; 449fe6060f1SDimitry Andric 450fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 451fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > 452fe6060f1SDimitry Andric { 453fe6060f1SDimitry Andric static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"); 454fe6060f1SDimitry Andric }; 455fe6060f1SDimitry Andric 456fe6060f1SDimitry Andric template <class _T1, class _T2> 457fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > 458fe6060f1SDimitry Andric { 459349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _T1 type; 460fe6060f1SDimitry Andric }; 461fe6060f1SDimitry Andric 462fe6060f1SDimitry Andric template <class _T1, class _T2> 463fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > 464fe6060f1SDimitry Andric { 465349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _T2 type; 466fe6060f1SDimitry Andric }; 467fe6060f1SDimitry Andric 468fe6060f1SDimitry Andric template <size_t _Ip> struct __get_pair; 469fe6060f1SDimitry Andric 470fe6060f1SDimitry Andric template <> 471fe6060f1SDimitry Andric struct __get_pair<0> 472fe6060f1SDimitry Andric { 473fe6060f1SDimitry Andric template <class _T1, class _T2> 474fe6060f1SDimitry Andric static 475fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 476fe6060f1SDimitry Andric _T1& 477fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 478fe6060f1SDimitry Andric 479fe6060f1SDimitry Andric template <class _T1, class _T2> 480fe6060f1SDimitry Andric static 481fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 482fe6060f1SDimitry Andric const _T1& 483fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 484fe6060f1SDimitry Andric 485fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 486fe6060f1SDimitry Andric template <class _T1, class _T2> 487fe6060f1SDimitry Andric static 488fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 489fe6060f1SDimitry Andric _T1&& 490fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);} 491fe6060f1SDimitry Andric 492fe6060f1SDimitry Andric template <class _T1, class _T2> 493fe6060f1SDimitry Andric static 494fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 495fe6060f1SDimitry Andric const _T1&& 496fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);} 497fe6060f1SDimitry Andric #endif // _LIBCPP_CXX03_LANG 498fe6060f1SDimitry Andric }; 499fe6060f1SDimitry Andric 500fe6060f1SDimitry Andric template <> 501fe6060f1SDimitry Andric struct __get_pair<1> 502fe6060f1SDimitry Andric { 503fe6060f1SDimitry Andric template <class _T1, class _T2> 504fe6060f1SDimitry Andric static 505fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 506fe6060f1SDimitry Andric _T2& 507fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 508fe6060f1SDimitry Andric 509fe6060f1SDimitry Andric template <class _T1, class _T2> 510fe6060f1SDimitry Andric static 511fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 512fe6060f1SDimitry Andric const _T2& 513fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 514fe6060f1SDimitry Andric 515fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 516fe6060f1SDimitry Andric template <class _T1, class _T2> 517fe6060f1SDimitry Andric static 518fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 519fe6060f1SDimitry Andric _T2&& 520fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);} 521fe6060f1SDimitry Andric 522fe6060f1SDimitry Andric template <class _T1, class _T2> 523fe6060f1SDimitry Andric static 524fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 525fe6060f1SDimitry Andric const _T2&& 526fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);} 527fe6060f1SDimitry Andric #endif // _LIBCPP_CXX03_LANG 528fe6060f1SDimitry Andric }; 529fe6060f1SDimitry Andric 530fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 531fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 532fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type& 533fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT 534fe6060f1SDimitry Andric { 535fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 536fe6060f1SDimitry Andric } 537fe6060f1SDimitry Andric 538fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 539fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 540fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 541fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT 542fe6060f1SDimitry Andric { 543fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 544fe6060f1SDimitry Andric } 545fe6060f1SDimitry Andric 546fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 547fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 548fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 549fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 550fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT 551fe6060f1SDimitry Andric { 552fe6060f1SDimitry Andric return __get_pair<_Ip>::get(_VSTD::move(__p)); 553fe6060f1SDimitry Andric } 554fe6060f1SDimitry Andric 555fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 556fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 557fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 558fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT 559fe6060f1SDimitry Andric { 560fe6060f1SDimitry Andric return __get_pair<_Ip>::get(_VSTD::move(__p)); 561fe6060f1SDimitry Andric } 562fe6060f1SDimitry Andric #endif // _LIBCPP_CXX03_LANG 563fe6060f1SDimitry Andric 564fe6060f1SDimitry Andric #if _LIBCPP_STD_VER > 11 565fe6060f1SDimitry Andric template <class _T1, class _T2> 566fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 567fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT 568fe6060f1SDimitry Andric { 569fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 570fe6060f1SDimitry Andric } 571fe6060f1SDimitry Andric 572fe6060f1SDimitry Andric template <class _T1, class _T2> 573fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 574fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT 575fe6060f1SDimitry Andric { 576fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 577fe6060f1SDimitry Andric } 578fe6060f1SDimitry Andric 579fe6060f1SDimitry Andric template <class _T1, class _T2> 580fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 581fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT 582fe6060f1SDimitry Andric { 583fe6060f1SDimitry Andric return __get_pair<0>::get(_VSTD::move(__p)); 584fe6060f1SDimitry Andric } 585fe6060f1SDimitry Andric 586fe6060f1SDimitry Andric template <class _T1, class _T2> 587fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 588fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT 589fe6060f1SDimitry Andric { 590fe6060f1SDimitry Andric return __get_pair<0>::get(_VSTD::move(__p)); 591fe6060f1SDimitry Andric } 592fe6060f1SDimitry Andric 593fe6060f1SDimitry Andric template <class _T1, class _T2> 594fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 595fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT 596fe6060f1SDimitry Andric { 597fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 598fe6060f1SDimitry Andric } 599fe6060f1SDimitry Andric 600fe6060f1SDimitry Andric template <class _T1, class _T2> 601fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 602fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT 603fe6060f1SDimitry Andric { 604fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 605fe6060f1SDimitry Andric } 606fe6060f1SDimitry Andric 607fe6060f1SDimitry Andric template <class _T1, class _T2> 608fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 609fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT 610fe6060f1SDimitry Andric { 611fe6060f1SDimitry Andric return __get_pair<1>::get(_VSTD::move(__p)); 612fe6060f1SDimitry Andric } 613fe6060f1SDimitry Andric 614fe6060f1SDimitry Andric template <class _T1, class _T2> 615fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 616fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT 617fe6060f1SDimitry Andric { 618fe6060f1SDimitry Andric return __get_pair<1>::get(_VSTD::move(__p)); 619fe6060f1SDimitry Andric } 620fe6060f1SDimitry Andric 621fe6060f1SDimitry Andric #endif 622fe6060f1SDimitry Andric 623fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 624fe6060f1SDimitry Andric 625fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 626