138fd1498Szrj // Pair implementation -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj /* 2638fd1498Szrj * 2738fd1498Szrj * Copyright (c) 1994 2838fd1498Szrj * Hewlett-Packard Company 2938fd1498Szrj * 3038fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 3138fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 3238fd1498Szrj * provided that the above copyright notice appear in all copies and 3338fd1498Szrj * that both that copyright notice and this permission notice appear 3438fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no 3538fd1498Szrj * representations about the suitability of this software for any 3638fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 3738fd1498Szrj * 3838fd1498Szrj * 3938fd1498Szrj * Copyright (c) 1996,1997 4038fd1498Szrj * Silicon Graphics Computer Systems, Inc. 4138fd1498Szrj * 4238fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 4338fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 4438fd1498Szrj * provided that the above copyright notice appear in all copies and 4538fd1498Szrj * that both that copyright notice and this permission notice appear 4638fd1498Szrj * in supporting documentation. Silicon Graphics makes no 4738fd1498Szrj * representations about the suitability of this software for any 4838fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 4938fd1498Szrj */ 5038fd1498Szrj 5138fd1498Szrj /** @file bits/stl_pair.h 5238fd1498Szrj * This is an internal header file, included by other library headers. 5338fd1498Szrj * Do not attempt to use it directly. @headername{utility} 5438fd1498Szrj */ 5538fd1498Szrj 5638fd1498Szrj #ifndef _STL_PAIR_H 5738fd1498Szrj #define _STL_PAIR_H 1 5838fd1498Szrj 5938fd1498Szrj #include <bits/move.h> // for std::move / std::forward, and std::swap 6038fd1498Szrj 6138fd1498Szrj #if __cplusplus >= 201103L 6238fd1498Szrj #include <type_traits> // for std::__decay_and_strip too 6338fd1498Szrj #endif 6438fd1498Szrj 6538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 6638fd1498Szrj { 6738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 6838fd1498Szrj 6938fd1498Szrj /** 7038fd1498Szrj * @addtogroup utilities 7138fd1498Szrj * @{ 7238fd1498Szrj */ 7338fd1498Szrj 7438fd1498Szrj #if __cplusplus >= 201103L 7538fd1498Szrj /// piecewise_construct_t 7638fd1498Szrj struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; 7738fd1498Szrj 7838fd1498Szrj /// piecewise_construct 7938fd1498Szrj _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct = 8038fd1498Szrj piecewise_construct_t(); 8138fd1498Szrj 8238fd1498Szrj // Forward declarations. 8338fd1498Szrj template<typename...> 8438fd1498Szrj class tuple; 8538fd1498Szrj 8638fd1498Szrj template<std::size_t...> 8738fd1498Szrj struct _Index_tuple; 8838fd1498Szrj 8938fd1498Szrj // Concept utility functions, reused in conditionally-explicit 9038fd1498Szrj // constructors. 9138fd1498Szrj // See PR 70437, don't look at is_constructible or 9238fd1498Szrj // is_convertible if the types are the same to 9338fd1498Szrj // avoid querying those properties for incomplete types. 9438fd1498Szrj template <bool, typename _T1, typename _T2> 9538fd1498Szrj struct _PCC 9638fd1498Szrj { 9738fd1498Szrj template <typename _U1, typename _U2> 9838fd1498Szrj static constexpr bool _ConstructiblePair() 9938fd1498Szrj { 10038fd1498Szrj return __and_<is_constructible<_T1, const _U1&>, 10138fd1498Szrj is_constructible<_T2, const _U2&>>::value; 10238fd1498Szrj } 10338fd1498Szrj 10438fd1498Szrj template <typename _U1, typename _U2> 10538fd1498Szrj static constexpr bool _ImplicitlyConvertiblePair() 10638fd1498Szrj { 10738fd1498Szrj return __and_<is_convertible<const _U1&, _T1>, 10838fd1498Szrj is_convertible<const _U2&, _T2>>::value; 10938fd1498Szrj } 11038fd1498Szrj 11138fd1498Szrj template <typename _U1, typename _U2> 11238fd1498Szrj static constexpr bool _MoveConstructiblePair() 11338fd1498Szrj { 11438fd1498Szrj return __and_<is_constructible<_T1, _U1&&>, 11538fd1498Szrj is_constructible<_T2, _U2&&>>::value; 11638fd1498Szrj } 11738fd1498Szrj 11838fd1498Szrj template <typename _U1, typename _U2> 11938fd1498Szrj static constexpr bool _ImplicitlyMoveConvertiblePair() 12038fd1498Szrj { 12138fd1498Szrj return __and_<is_convertible<_U1&&, _T1>, 12238fd1498Szrj is_convertible<_U2&&, _T2>>::value; 12338fd1498Szrj } 12438fd1498Szrj 12538fd1498Szrj template <bool __implicit, typename _U1, typename _U2> 12638fd1498Szrj static constexpr bool _CopyMovePair() 12738fd1498Szrj { 12838fd1498Szrj using __do_converts = __and_<is_convertible<const _U1&, _T1>, 12938fd1498Szrj is_convertible<_U2&&, _T2>>; 13038fd1498Szrj using __converts = typename conditional<__implicit, 13138fd1498Szrj __do_converts, 13238fd1498Szrj __not_<__do_converts>>::type; 13338fd1498Szrj return __and_<is_constructible<_T1, const _U1&>, 13438fd1498Szrj is_constructible<_T2, _U2&&>, 13538fd1498Szrj __converts 13638fd1498Szrj >::value; 13738fd1498Szrj } 13838fd1498Szrj 13938fd1498Szrj template <bool __implicit, typename _U1, typename _U2> 14038fd1498Szrj static constexpr bool _MoveCopyPair() 14138fd1498Szrj { 14238fd1498Szrj using __do_converts = __and_<is_convertible<_U1&&, _T1>, 14338fd1498Szrj is_convertible<const _U2&, _T2>>; 14438fd1498Szrj using __converts = typename conditional<__implicit, 14538fd1498Szrj __do_converts, 14638fd1498Szrj __not_<__do_converts>>::type; 14738fd1498Szrj return __and_<is_constructible<_T1, _U1&&>, 14838fd1498Szrj is_constructible<_T2, const _U2&&>, 14938fd1498Szrj __converts 15038fd1498Szrj >::value; 15138fd1498Szrj } 15238fd1498Szrj }; 15338fd1498Szrj 15438fd1498Szrj template <typename _T1, typename _T2> 15538fd1498Szrj struct _PCC<false, _T1, _T2> 15638fd1498Szrj { 15738fd1498Szrj template <typename _U1, typename _U2> 15838fd1498Szrj static constexpr bool _ConstructiblePair() 15938fd1498Szrj { 16038fd1498Szrj return false; 16138fd1498Szrj } 16238fd1498Szrj 16338fd1498Szrj template <typename _U1, typename _U2> 16438fd1498Szrj static constexpr bool _ImplicitlyConvertiblePair() 16538fd1498Szrj { 16638fd1498Szrj return false; 16738fd1498Szrj } 16838fd1498Szrj 16938fd1498Szrj template <typename _U1, typename _U2> 17038fd1498Szrj static constexpr bool _MoveConstructiblePair() 17138fd1498Szrj { 17238fd1498Szrj return false; 17338fd1498Szrj } 17438fd1498Szrj 17538fd1498Szrj template <typename _U1, typename _U2> 17638fd1498Szrj static constexpr bool _ImplicitlyMoveConvertiblePair() 17738fd1498Szrj { 17838fd1498Szrj return false; 17938fd1498Szrj } 18038fd1498Szrj }; 18138fd1498Szrj 18238fd1498Szrj // PR libstdc++/79141, a utility type for preventing 18338fd1498Szrj // initialization of an argument of a disabled assignment 18438fd1498Szrj // operator from a pair of empty braces. 18538fd1498Szrj struct __nonesuch_no_braces : std::__nonesuch { 18638fd1498Szrj explicit __nonesuch_no_braces(const __nonesuch&) = delete; 18738fd1498Szrj }; 188*58e805e6Szrj #endif // C++11 18938fd1498Szrj 190*58e805e6Szrj template<typename _U1, typename _U2> class __pair_base 191*58e805e6Szrj { 192*58e805e6Szrj #if __cplusplus >= 201103L 193*58e805e6Szrj template<typename _T1, typename _T2> friend struct pair; 194*58e805e6Szrj __pair_base() = default; 195*58e805e6Szrj ~__pair_base() = default; 196*58e805e6Szrj __pair_base(const __pair_base&) = default; 197*58e805e6Szrj __pair_base& operator=(const __pair_base&) = delete; 198*58e805e6Szrj #endif // C++11 199*58e805e6Szrj }; 20038fd1498Szrj 20138fd1498Szrj /** 20238fd1498Szrj * @brief Struct holding two objects of arbitrary type. 20338fd1498Szrj * 20438fd1498Szrj * @tparam _T1 Type of first object. 20538fd1498Szrj * @tparam _T2 Type of second object. 20638fd1498Szrj */ 20738fd1498Szrj template<typename _T1, typename _T2> 20838fd1498Szrj struct pair 209*58e805e6Szrj : private __pair_base<_T1, _T2> 21038fd1498Szrj { 21138fd1498Szrj typedef _T1 first_type; /// @c first_type is the first bound type 21238fd1498Szrj typedef _T2 second_type; /// @c second_type is the second bound type 21338fd1498Szrj 21438fd1498Szrj _T1 first; /// @c first is a copy of the first object 21538fd1498Szrj _T2 second; /// @c second is a copy of the second object 21638fd1498Szrj 21738fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 21838fd1498Szrj // 265. std::pair::pair() effects overly restrictive 21938fd1498Szrj /** The default constructor creates @c first and @c second using their 22038fd1498Szrj * respective default constructors. */ 22138fd1498Szrj #if __cplusplus >= 201103L 22238fd1498Szrj template <typename _U1 = _T1, 22338fd1498Szrj typename _U2 = _T2, 22438fd1498Szrj typename enable_if<__and_< 22538fd1498Szrj __is_implicitly_default_constructible<_U1>, 22638fd1498Szrj __is_implicitly_default_constructible<_U2>> 22738fd1498Szrj ::value, bool>::type = true> 22838fd1498Szrj #endif 22938fd1498Szrj _GLIBCXX_CONSTEXPR pair() 23038fd1498Szrj : first(), second() { } 23138fd1498Szrj 23238fd1498Szrj #if __cplusplus >= 201103L 23338fd1498Szrj template <typename _U1 = _T1, 23438fd1498Szrj typename _U2 = _T2, 23538fd1498Szrj typename enable_if<__and_< 23638fd1498Szrj is_default_constructible<_U1>, 23738fd1498Szrj is_default_constructible<_U2>, 23838fd1498Szrj __not_< 23938fd1498Szrj __and_<__is_implicitly_default_constructible<_U1>, 24038fd1498Szrj __is_implicitly_default_constructible<_U2>>>> 24138fd1498Szrj ::value, bool>::type = false> 24238fd1498Szrj explicit constexpr pair() 24338fd1498Szrj : first(), second() { } 24438fd1498Szrj #endif 24538fd1498Szrj 24638fd1498Szrj /** Two objects may be passed to a @c pair constructor to be copied. */ 24738fd1498Szrj #if __cplusplus < 201103L 24838fd1498Szrj pair(const _T1& __a, const _T2& __b) 24938fd1498Szrj : first(__a), second(__b) { } 25038fd1498Szrj #else 25138fd1498Szrj // Shortcut for constraining the templates that don't take pairs. 25238fd1498Szrj using _PCCP = _PCC<true, _T1, _T2>; 25338fd1498Szrj 25438fd1498Szrj template<typename _U1 = _T1, typename _U2=_T2, typename 25538fd1498Szrj enable_if<_PCCP::template 25638fd1498Szrj _ConstructiblePair<_U1, _U2>() 25738fd1498Szrj && _PCCP::template 25838fd1498Szrj _ImplicitlyConvertiblePair<_U1, _U2>(), 25938fd1498Szrj bool>::type=true> 26038fd1498Szrj constexpr pair(const _T1& __a, const _T2& __b) 26138fd1498Szrj : first(__a), second(__b) { } 26238fd1498Szrj 26338fd1498Szrj template<typename _U1 = _T1, typename _U2=_T2, typename 26438fd1498Szrj enable_if<_PCCP::template 26538fd1498Szrj _ConstructiblePair<_U1, _U2>() 26638fd1498Szrj && !_PCCP::template 26738fd1498Szrj _ImplicitlyConvertiblePair<_U1, _U2>(), 26838fd1498Szrj bool>::type=false> 26938fd1498Szrj explicit constexpr pair(const _T1& __a, const _T2& __b) 27038fd1498Szrj : first(__a), second(__b) { } 27138fd1498Szrj #endif 27238fd1498Szrj 27338fd1498Szrj /** There is also a templated copy ctor for the @c pair class itself. */ 27438fd1498Szrj #if __cplusplus < 201103L 27538fd1498Szrj template<typename _U1, typename _U2> 27638fd1498Szrj pair(const pair<_U1, _U2>& __p) 27738fd1498Szrj : first(__p.first), second(__p.second) { } 27838fd1498Szrj #else 27938fd1498Szrj // Shortcut for constraining the templates that take pairs. 28038fd1498Szrj template <typename _U1, typename _U2> 28138fd1498Szrj using _PCCFP = _PCC<!is_same<_T1, _U1>::value 28238fd1498Szrj || !is_same<_T2, _U2>::value, 28338fd1498Szrj _T1, _T2>; 28438fd1498Szrj 28538fd1498Szrj template<typename _U1, typename _U2, typename 28638fd1498Szrj enable_if<_PCCFP<_U1, _U2>::template 28738fd1498Szrj _ConstructiblePair<_U1, _U2>() 28838fd1498Szrj && _PCCFP<_U1, _U2>::template 28938fd1498Szrj _ImplicitlyConvertiblePair<_U1, _U2>(), 29038fd1498Szrj bool>::type=true> 29138fd1498Szrj constexpr pair(const pair<_U1, _U2>& __p) 29238fd1498Szrj : first(__p.first), second(__p.second) { } 29338fd1498Szrj 29438fd1498Szrj template<typename _U1, typename _U2, typename 29538fd1498Szrj enable_if<_PCCFP<_U1, _U2>::template 29638fd1498Szrj _ConstructiblePair<_U1, _U2>() 29738fd1498Szrj && !_PCCFP<_U1, _U2>::template 29838fd1498Szrj _ImplicitlyConvertiblePair<_U1, _U2>(), 29938fd1498Szrj bool>::type=false> 30038fd1498Szrj explicit constexpr pair(const pair<_U1, _U2>& __p) 30138fd1498Szrj : first(__p.first), second(__p.second) { } 30238fd1498Szrj 30338fd1498Szrj constexpr pair(const pair&) = default; 30438fd1498Szrj constexpr pair(pair&&) = default; 30538fd1498Szrj 30638fd1498Szrj // DR 811. 30738fd1498Szrj template<typename _U1, typename 30838fd1498Szrj enable_if<_PCCP::template 30938fd1498Szrj _MoveCopyPair<true, _U1, _T2>(), 31038fd1498Szrj bool>::type=true> 31138fd1498Szrj constexpr pair(_U1&& __x, const _T2& __y) 31238fd1498Szrj : first(std::forward<_U1>(__x)), second(__y) { } 31338fd1498Szrj 31438fd1498Szrj template<typename _U1, typename 31538fd1498Szrj enable_if<_PCCP::template 31638fd1498Szrj _MoveCopyPair<false, _U1, _T2>(), 31738fd1498Szrj bool>::type=false> 31838fd1498Szrj explicit constexpr pair(_U1&& __x, const _T2& __y) 31938fd1498Szrj : first(std::forward<_U1>(__x)), second(__y) { } 32038fd1498Szrj 32138fd1498Szrj template<typename _U2, typename 32238fd1498Szrj enable_if<_PCCP::template 32338fd1498Szrj _CopyMovePair<true, _T1, _U2>(), 32438fd1498Szrj bool>::type=true> 32538fd1498Szrj constexpr pair(const _T1& __x, _U2&& __y) 32638fd1498Szrj : first(__x), second(std::forward<_U2>(__y)) { } 32738fd1498Szrj 32838fd1498Szrj template<typename _U2, typename 32938fd1498Szrj enable_if<_PCCP::template 33038fd1498Szrj _CopyMovePair<false, _T1, _U2>(), 33138fd1498Szrj bool>::type=false> 33238fd1498Szrj explicit pair(const _T1& __x, _U2&& __y) 33338fd1498Szrj : first(__x), second(std::forward<_U2>(__y)) { } 33438fd1498Szrj 33538fd1498Szrj template<typename _U1, typename _U2, typename 33638fd1498Szrj enable_if<_PCCP::template 33738fd1498Szrj _MoveConstructiblePair<_U1, _U2>() 33838fd1498Szrj && _PCCP::template 33938fd1498Szrj _ImplicitlyMoveConvertiblePair<_U1, _U2>(), 34038fd1498Szrj bool>::type=true> 34138fd1498Szrj constexpr pair(_U1&& __x, _U2&& __y) 34238fd1498Szrj : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } 34338fd1498Szrj 34438fd1498Szrj template<typename _U1, typename _U2, typename 34538fd1498Szrj enable_if<_PCCP::template 34638fd1498Szrj _MoveConstructiblePair<_U1, _U2>() 34738fd1498Szrj && !_PCCP::template 34838fd1498Szrj _ImplicitlyMoveConvertiblePair<_U1, _U2>(), 34938fd1498Szrj bool>::type=false> 35038fd1498Szrj explicit constexpr pair(_U1&& __x, _U2&& __y) 35138fd1498Szrj : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } 35238fd1498Szrj 35338fd1498Szrj 35438fd1498Szrj template<typename _U1, typename _U2, typename 35538fd1498Szrj enable_if<_PCCFP<_U1, _U2>::template 35638fd1498Szrj _MoveConstructiblePair<_U1, _U2>() 35738fd1498Szrj && _PCCFP<_U1, _U2>::template 35838fd1498Szrj _ImplicitlyMoveConvertiblePair<_U1, _U2>(), 35938fd1498Szrj bool>::type=true> 36038fd1498Szrj constexpr pair(pair<_U1, _U2>&& __p) 36138fd1498Szrj : first(std::forward<_U1>(__p.first)), 36238fd1498Szrj second(std::forward<_U2>(__p.second)) { } 36338fd1498Szrj 36438fd1498Szrj template<typename _U1, typename _U2, typename 36538fd1498Szrj enable_if<_PCCFP<_U1, _U2>::template 36638fd1498Szrj _MoveConstructiblePair<_U1, _U2>() 36738fd1498Szrj && !_PCCFP<_U1, _U2>::template 36838fd1498Szrj _ImplicitlyMoveConvertiblePair<_U1, _U2>(), 36938fd1498Szrj bool>::type=false> 37038fd1498Szrj explicit constexpr pair(pair<_U1, _U2>&& __p) 37138fd1498Szrj : first(std::forward<_U1>(__p.first)), 37238fd1498Szrj second(std::forward<_U2>(__p.second)) { } 37338fd1498Szrj 37438fd1498Szrj template<typename... _Args1, typename... _Args2> 37538fd1498Szrj pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>); 37638fd1498Szrj 37738fd1498Szrj pair& 37838fd1498Szrj operator=(typename conditional< 37938fd1498Szrj __and_<is_copy_assignable<_T1>, 38038fd1498Szrj is_copy_assignable<_T2>>::value, 38138fd1498Szrj const pair&, const __nonesuch_no_braces&>::type __p) 38238fd1498Szrj { 38338fd1498Szrj first = __p.first; 38438fd1498Szrj second = __p.second; 38538fd1498Szrj return *this; 38638fd1498Szrj } 38738fd1498Szrj 38838fd1498Szrj pair& 38938fd1498Szrj operator=(typename conditional< 39038fd1498Szrj __and_<is_move_assignable<_T1>, 39138fd1498Szrj is_move_assignable<_T2>>::value, 39238fd1498Szrj pair&&, __nonesuch_no_braces&&>::type __p) 39338fd1498Szrj noexcept(__and_<is_nothrow_move_assignable<_T1>, 39438fd1498Szrj is_nothrow_move_assignable<_T2>>::value) 39538fd1498Szrj { 39638fd1498Szrj first = std::forward<first_type>(__p.first); 39738fd1498Szrj second = std::forward<second_type>(__p.second); 39838fd1498Szrj return *this; 39938fd1498Szrj } 40038fd1498Szrj 40138fd1498Szrj template<typename _U1, typename _U2> 40238fd1498Szrj typename enable_if<__and_<is_assignable<_T1&, const _U1&>, 40338fd1498Szrj is_assignable<_T2&, const _U2&>>::value, 40438fd1498Szrj pair&>::type 40538fd1498Szrj operator=(const pair<_U1, _U2>& __p) 40638fd1498Szrj { 40738fd1498Szrj first = __p.first; 40838fd1498Szrj second = __p.second; 40938fd1498Szrj return *this; 41038fd1498Szrj } 41138fd1498Szrj 41238fd1498Szrj template<typename _U1, typename _U2> 41338fd1498Szrj typename enable_if<__and_<is_assignable<_T1&, _U1&&>, 41438fd1498Szrj is_assignable<_T2&, _U2&&>>::value, 41538fd1498Szrj pair&>::type 41638fd1498Szrj operator=(pair<_U1, _U2>&& __p) 41738fd1498Szrj { 41838fd1498Szrj first = std::forward<_U1>(__p.first); 41938fd1498Szrj second = std::forward<_U2>(__p.second); 42038fd1498Szrj return *this; 42138fd1498Szrj } 42238fd1498Szrj 42338fd1498Szrj void 42438fd1498Szrj swap(pair& __p) 42538fd1498Szrj noexcept(__and_<__is_nothrow_swappable<_T1>, 42638fd1498Szrj __is_nothrow_swappable<_T2>>::value) 42738fd1498Szrj { 42838fd1498Szrj using std::swap; 42938fd1498Szrj swap(first, __p.first); 43038fd1498Szrj swap(second, __p.second); 43138fd1498Szrj } 43238fd1498Szrj 43338fd1498Szrj private: 43438fd1498Szrj template<typename... _Args1, std::size_t... _Indexes1, 43538fd1498Szrj typename... _Args2, std::size_t... _Indexes2> 43638fd1498Szrj pair(tuple<_Args1...>&, tuple<_Args2...>&, 43738fd1498Szrj _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>); 43838fd1498Szrj #endif 43938fd1498Szrj }; 44038fd1498Szrj 44138fd1498Szrj #if __cpp_deduction_guides >= 201606 44238fd1498Szrj template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>; 44338fd1498Szrj #endif 44438fd1498Szrj 44538fd1498Szrj /// Two pairs of the same type are equal iff their members are equal. 44638fd1498Szrj template<typename _T1, typename _T2> 44738fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 44838fd1498Szrj operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 44938fd1498Szrj { return __x.first == __y.first && __x.second == __y.second; } 45038fd1498Szrj 45138fd1498Szrj /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html> 45238fd1498Szrj template<typename _T1, typename _T2> 45338fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 45438fd1498Szrj operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 45538fd1498Szrj { return __x.first < __y.first 45638fd1498Szrj || (!(__y.first < __x.first) && __x.second < __y.second); } 45738fd1498Szrj 45838fd1498Szrj /// Uses @c operator== to find the result. 45938fd1498Szrj template<typename _T1, typename _T2> 46038fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 46138fd1498Szrj operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 46238fd1498Szrj { return !(__x == __y); } 46338fd1498Szrj 46438fd1498Szrj /// Uses @c operator< to find the result. 46538fd1498Szrj template<typename _T1, typename _T2> 46638fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 46738fd1498Szrj operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 46838fd1498Szrj { return __y < __x; } 46938fd1498Szrj 47038fd1498Szrj /// Uses @c operator< to find the result. 47138fd1498Szrj template<typename _T1, typename _T2> 47238fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 47338fd1498Szrj operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 47438fd1498Szrj { return !(__y < __x); } 47538fd1498Szrj 47638fd1498Szrj /// Uses @c operator< to find the result. 47738fd1498Szrj template<typename _T1, typename _T2> 47838fd1498Szrj inline _GLIBCXX_CONSTEXPR bool 47938fd1498Szrj operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 48038fd1498Szrj { return !(__x < __y); } 48138fd1498Szrj 48238fd1498Szrj #if __cplusplus >= 201103L 48338fd1498Szrj /// See std::pair::swap(). 48438fd1498Szrj // Note: no std::swap overloads in C++03 mode, this has performance 48538fd1498Szrj // implications, see, eg, libstdc++/38466. 48638fd1498Szrj template<typename _T1, typename _T2> 48738fd1498Szrj inline 48838fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 48938fd1498Szrj // Constrained free swap overload, see p0185r1 49038fd1498Szrj typename enable_if<__and_<__is_swappable<_T1>, 49138fd1498Szrj __is_swappable<_T2>>::value>::type 49238fd1498Szrj #else 49338fd1498Szrj void 49438fd1498Szrj #endif 49538fd1498Szrj swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 49638fd1498Szrj noexcept(noexcept(__x.swap(__y))) 49738fd1498Szrj { __x.swap(__y); } 49838fd1498Szrj 49938fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 50038fd1498Szrj template<typename _T1, typename _T2> 50138fd1498Szrj typename enable_if<!__and_<__is_swappable<_T1>, 50238fd1498Szrj __is_swappable<_T2>>::value>::type 50338fd1498Szrj swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete; 50438fd1498Szrj #endif 50538fd1498Szrj #endif // __cplusplus >= 201103L 50638fd1498Szrj 50738fd1498Szrj /** 50838fd1498Szrj * @brief A convenience wrapper for creating a pair from two objects. 50938fd1498Szrj * @param __x The first object. 51038fd1498Szrj * @param __y The second object. 51138fd1498Szrj * @return A newly-constructed pair<> object of the appropriate type. 51238fd1498Szrj * 51338fd1498Szrj * The standard requires that the objects be passed by reference-to-const, 51438fd1498Szrj * but LWG issue #181 says they should be passed by const value. We follow 51538fd1498Szrj * the LWG by default. 51638fd1498Szrj */ 51738fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 51838fd1498Szrj // 181. make_pair() unintended behavior 51938fd1498Szrj #if __cplusplus >= 201103L 52038fd1498Szrj // NB: DR 706. 52138fd1498Szrj template<typename _T1, typename _T2> 52238fd1498Szrj constexpr pair<typename __decay_and_strip<_T1>::__type, 52338fd1498Szrj typename __decay_and_strip<_T2>::__type> 52438fd1498Szrj make_pair(_T1&& __x, _T2&& __y) 52538fd1498Szrj { 52638fd1498Szrj typedef typename __decay_and_strip<_T1>::__type __ds_type1; 52738fd1498Szrj typedef typename __decay_and_strip<_T2>::__type __ds_type2; 52838fd1498Szrj typedef pair<__ds_type1, __ds_type2> __pair_type; 52938fd1498Szrj return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y)); 53038fd1498Szrj } 53138fd1498Szrj #else 53238fd1498Szrj template<typename _T1, typename _T2> 53338fd1498Szrj inline pair<_T1, _T2> 53438fd1498Szrj make_pair(_T1 __x, _T2 __y) 53538fd1498Szrj { return pair<_T1, _T2>(__x, __y); } 53638fd1498Szrj #endif 53738fd1498Szrj 53838fd1498Szrj /// @} 53938fd1498Szrj 54038fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 54138fd1498Szrj } // namespace std 54238fd1498Szrj 54338fd1498Szrj #endif /* _STL_PAIR_H */ 544