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