xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
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 
_GLIBCXX_VISIBILITY(default)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