1 // Pair implementation -*- C++ -*-
3 // Copyright (C) 2001-2021 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
28 * Hewlett-Packard Company
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
51 /** @file bits/stl_pair.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{utility}
59 #if __cplusplus >= 201103L
60 # include <type_traits> // for std::__decay_and_strip
61 # include <bits/move.h> // for std::move / std::forward, and std::swap
62 # include <bits/utility.h> // for std::tuple_element, std::tuple_size
64 #if __cplusplus >= 202002L
66 # define __cpp_lib_constexpr_utility 201811L
69 namespace std
_GLIBCXX_VISIBILITY(default)
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
74 * @addtogroup utilities
78 #if __cplusplus >= 201103L
79 /// Tag type for piecewise construction of std::pair objects.
80 struct piecewise_construct_t
{ explicit piecewise_construct_t() = default; };
82 /// Tag for piecewise construction of std::pair objects.
83 _GLIBCXX17_INLINE
constexpr piecewise_construct_t piecewise_construct
=
84 piecewise_construct_t();
86 /// @cond undocumented
88 // Forward declarations.
95 #if ! __cpp_lib_concepts
96 // Concept utility functions, reused in conditionally-explicit
98 // See PR 70437, don't look at is_constructible or
99 // is_convertible if the types are the same to
100 // avoid querying those properties for incomplete types.
101 template <bool, typename _T1
, typename _T2
>
104 template <typename _U1
, typename _U2
>
105 static constexpr bool _ConstructiblePair()
107 return __and_
<is_constructible
<_T1
, const _U1
&>,
108 is_constructible
<_T2
, const _U2
&>>::value
;
111 template <typename _U1
, typename _U2
>
112 static constexpr bool _ImplicitlyConvertiblePair()
114 return __and_
<is_convertible
<const _U1
&, _T1
>,
115 is_convertible
<const _U2
&, _T2
>>::value
;
118 template <typename _U1
, typename _U2
>
119 static constexpr bool _MoveConstructiblePair()
121 return __and_
<is_constructible
<_T1
, _U1
&&>,
122 is_constructible
<_T2
, _U2
&&>>::value
;
125 template <typename _U1
, typename _U2
>
126 static constexpr bool _ImplicitlyMoveConvertiblePair()
128 return __and_
<is_convertible
<_U1
&&, _T1
>,
129 is_convertible
<_U2
&&, _T2
>>::value
;
133 template <bool __implicit
, typename _U1
, typename _U2
>
134 static constexpr bool _DeprConsPair()
136 using __do_converts
= __and_
<is_convertible
<_U1
&&, _T1
>,
137 is_convertible
<_U2
&&, _T2
>>;
138 using __converts
= typename conditional
<__implicit
,
140 __not_
<__do_converts
>>::type
;
141 return __and_
<is_constructible
<_T1
, _U1
&&>,
142 is_constructible
<_T2
, _U2
&&>,
148 template <typename _T1
, typename _T2
>
149 struct _PCC
<false, _T1
, _T2
>
151 template <typename _U1
, typename _U2
>
152 static constexpr bool _ConstructiblePair()
157 template <typename _U1
, typename _U2
>
158 static constexpr bool _ImplicitlyConvertiblePair()
163 template <typename _U1
, typename _U2
>
164 static constexpr bool _MoveConstructiblePair()
169 template <typename _U1
, typename _U2
>
170 static constexpr bool _ImplicitlyMoveConvertiblePair()
175 #endif // lib concepts
178 template<typename _U1
, typename _U2
> class __pair_base
180 #if __cplusplus >= 201103L && ! __cpp_lib_concepts
181 template<typename _T1
, typename _T2
> friend struct pair
;
182 __pair_base() = default;
183 ~__pair_base() = default;
184 __pair_base(const __pair_base
&) = default;
185 __pair_base
& operator=(const __pair_base
&) = delete;
192 * @brief Struct holding two objects of arbitrary type.
194 * @tparam _T1 Type of first object.
195 * @tparam _T2 Type of second object.
197 * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
199 template<typename _T1
, typename _T2
>
201 : public __pair_base
<_T1
, _T2
>
203 typedef _T1 first_type
; ///< The type of the `first` member
204 typedef _T2 second_type
; ///< The type of the `second` member
206 _T1 first
; ///< The first member
207 _T2 second
; ///< The second member
209 #if __cplusplus >= 201103L
210 constexpr pair(const pair
&) = default; ///< Copy constructor
211 constexpr pair(pair
&&) = default; ///< Move constructor
213 template<typename
... _Args1
, typename
... _Args2
>
215 pair(piecewise_construct_t
, tuple
<_Args1
...>, tuple
<_Args2
...>);
217 /// Swap the first members and then the second members.
218 _GLIBCXX20_CONSTEXPR
void
220 noexcept(__and_
<__is_nothrow_swappable
<_T1
>,
221 __is_nothrow_swappable
<_T2
>>::value
)
224 swap(first
, __p
.first
);
225 swap(second
, __p
.second
);
229 template<typename
... _Args1
, size_t... _Indexes1
,
230 typename
... _Args2
, size_t... _Indexes2
>
232 pair(tuple
<_Args1
...>&, tuple
<_Args2
...>&,
233 _Index_tuple
<_Indexes1
...>, _Index_tuple
<_Indexes2
...>);
236 #if __cpp_lib_concepts
237 // C++20 implementation using concepts, explicit(bool), fully constexpr.
239 /// Default constructor
241 explicit(__not_
<__and_
<__is_implicitly_default_constructible
<_T1
>,
242 __is_implicitly_default_constructible
<_T2
>>>())
244 requires is_default_constructible_v
<_T1
>
245 && is_default_constructible_v
<_T2
>
251 /// @cond undocumented
252 template<typename _U1
, typename _U2
>
253 static constexpr bool
256 if constexpr (is_constructible_v
<_T1
, _U1
>)
257 return is_constructible_v
<_T2
, _U2
>;
261 template<typename _U1
, typename _U2
>
262 static constexpr bool
263 _S_nothrow_constructible()
265 if constexpr (is_nothrow_constructible_v
<_T1
, _U1
>)
266 return is_nothrow_constructible_v
<_T2
, _U2
>;
270 template<typename _U1
, typename _U2
>
271 static constexpr bool
274 if constexpr (is_convertible_v
<_U1
, _T1
>)
275 return is_convertible_v
<_U2
, _T2
>;
282 /// Constructor accepting lvalues of `first_type` and `second_type`
283 constexpr explicit(!_S_convertible
<const _T1
&, const _T2
&>())
284 pair(const _T1
& __x
, const _T2
& __y
)
285 noexcept(_S_nothrow_constructible
<const _T1
&, const _T2
&>())
286 requires (_S_constructible
<const _T1
&, const _T2
&>())
287 : first(__x
), second(__y
)
290 /// Constructor accepting two values of arbitrary types
291 template<typename _U1
, typename _U2
>
292 requires (_S_constructible
<_U1
, _U2
>())
293 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
294 pair(_U1
&& __x
, _U2
&& __y
)
295 noexcept(_S_nothrow_constructible
<_U1
, _U2
>())
296 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
))
299 /// Converting constructor from a `pair<U1, U2>` lvalue
300 template<typename _U1
, typename _U2
>
301 requires (_S_constructible
<const _U1
&, const _U2
&>())
302 constexpr explicit(!_S_convertible
<const _U1
&, const _U2
&>())
303 pair(const pair
<_U1
, _U2
>& __p
)
304 noexcept(_S_nothrow_constructible
<const _U1
&, const _U2
&>())
305 : first(__p
.first
), second(__p
.second
)
308 /// Converting constructor from a `pair<U1, U2>` rvalue
309 template<typename _U1
, typename _U2
>
310 requires (_S_constructible
<_U1
, _U2
>())
311 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
312 pair(pair
<_U1
, _U2
>&& __p
)
313 noexcept(_S_nothrow_constructible
<_U1
, _U2
>())
314 : first(std::forward
<_U1
>(__p
.first
)),
315 second(std::forward
<_U2
>(__p
.second
))
319 /// @cond undocumented
320 template<typename _U1
, typename _U2
>
321 static constexpr bool
324 if constexpr (is_assignable_v
<_T1
&, _U1
>)
325 return is_assignable_v
<_T2
&, _U2
>;
329 template<typename _U1
, typename _U2
>
330 static constexpr bool
331 _S_nothrow_assignable()
333 if constexpr (is_nothrow_assignable_v
<_T1
&, _U1
>)
334 return is_nothrow_assignable_v
<_T2
&, _U2
>;
341 pair
& operator=(const pair
&) = delete;
343 /// Copy assignment operator
345 operator=(const pair
& __p
)
346 noexcept(_S_nothrow_assignable
<const _T1
&, const _T2
&>())
347 requires (_S_assignable
<const _T1
&, const _T2
&>())
354 /// Move assignment operator
356 operator=(pair
&& __p
)
357 noexcept(_S_nothrow_assignable
<_T1
, _T2
>())
358 requires (_S_assignable
<_T1
, _T2
>())
360 first
= std::forward
<first_type
>(__p
.first
);
361 second
= std::forward
<second_type
>(__p
.second
);
365 /// Converting assignment from a `pair<U1, U2>` lvalue
366 template<typename _U1
, typename _U2
>
368 operator=(const pair
<_U1
, _U2
>& __p
)
369 noexcept(_S_nothrow_assignable
<const _U1
&, const _U2
&>())
370 requires (_S_assignable
<const _U1
&, const _U2
&>())
377 /// Converting assignment from a `pair<U1, U2>` rvalue
378 template<typename _U1
, typename _U2
>
380 operator=(pair
<_U1
, _U2
>&& __p
)
381 noexcept(_S_nothrow_assignable
<_U1
, _U2
>())
382 requires (_S_assignable
<_U1
, _U2
>())
384 first
= std::forward
<_U1
>(__p
.first
);
385 second
= std::forward
<_U2
>(__p
.second
);
389 // C++11/14/17 implementation using enable_if, partially constexpr.
391 /** The default constructor creates @c first and @c second using their
392 * respective default constructors. */
393 template <typename _U1
= _T1
,
395 typename enable_if
<__and_
<
396 __is_implicitly_default_constructible
<_U1
>,
397 __is_implicitly_default_constructible
<_U2
>>
398 ::value
, bool>::type
= true>
400 : first(), second() { }
402 template <typename _U1
= _T1
,
404 typename enable_if
<__and_
<
405 is_default_constructible
<_U1
>,
406 is_default_constructible
<_U2
>,
408 __and_
<__is_implicitly_default_constructible
<_U1
>,
409 __is_implicitly_default_constructible
<_U2
>>>>
410 ::value
, bool>::type
= false>
411 explicit constexpr pair()
412 : first(), second() { }
414 // Shortcut for constraining the templates that don't take pairs.
415 /// @cond undocumented
416 using _PCCP
= _PCC
<true, _T1
, _T2
>;
419 /// Construct from two const lvalues, allowing implicit conversions.
420 template<typename _U1
= _T1
, typename _U2
=_T2
, typename
421 enable_if
<_PCCP::template
422 _ConstructiblePair
<_U1
, _U2
>()
424 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
426 constexpr pair(const _T1
& __a
, const _T2
& __b
)
427 : first(__a
), second(__b
) { }
429 /// Construct from two const lvalues, disallowing implicit conversions.
430 template<typename _U1
= _T1
, typename _U2
=_T2
, typename
431 enable_if
<_PCCP::template
432 _ConstructiblePair
<_U1
, _U2
>()
434 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
436 explicit constexpr pair(const _T1
& __a
, const _T2
& __b
)
437 : first(__a
), second(__b
) { }
439 // Shortcut for constraining the templates that take pairs.
440 /// @cond undocumented
441 template <typename _U1
, typename _U2
>
442 using _PCCFP
= _PCC
<!is_same
<_T1
, _U1
>::value
443 || !is_same
<_T2
, _U2
>::value
,
447 template<typename _U1
, typename _U2
, typename
448 enable_if
<_PCCFP
<_U1
, _U2
>::template
449 _ConstructiblePair
<_U1
, _U2
>()
450 && _PCCFP
<_U1
, _U2
>::template
451 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
453 constexpr pair(const pair
<_U1
, _U2
>& __p
)
454 : first(__p
.first
), second(__p
.second
) { }
456 template<typename _U1
, typename _U2
, typename
457 enable_if
<_PCCFP
<_U1
, _U2
>::template
458 _ConstructiblePair
<_U1
, _U2
>()
459 && !_PCCFP
<_U1
, _U2
>::template
460 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
462 explicit constexpr pair(const pair
<_U1
, _U2
>& __p
)
463 : first(__p
.first
), second(__p
.second
) { }
465 #if _GLIBCXX_USE_DEPRECATED
467 /// @cond undocumented
469 // A type which can be constructed from literal zero, but not nullptr
470 struct __null_ptr_constant
472 __null_ptr_constant(int __null_ptr_constant::*) { }
473 template<typename _Tp
,
474 typename
= __enable_if_t
<is_null_pointer
<_Tp
>::value
>>
475 __null_ptr_constant(_Tp
) = delete;
478 // True if type _Up is one of _Tp& or const _Tp&
479 template<typename _Up
, typename _Tp
>
481 = __or_
<is_same
<_Up
, const _Tp
&>, is_same
<_Up
, _Tp
&>>;
486 // Deprecated extensions to DR 811.
487 template<typename _U1
,
488 __enable_if_t
<!__is_lvalue_of
<_U1
, _T1
>::value
490 _DeprConsPair
<true, _U1
, nullptr_t
>(),
492 _GLIBCXX_DEPRECATED_SUGGEST("nullptr")
493 constexpr pair(_U1
&& __x
, __null_ptr_constant
)
494 : first(std::forward
<_U1
>(__x
)), second(nullptr) { }
496 template<typename _U1
,
497 __enable_if_t
<!__is_lvalue_of
<_U1
, _T1
>::value
499 _DeprConsPair
<false, _U1
, nullptr_t
>(),
501 _GLIBCXX_DEPRECATED_SUGGEST("nullptr")
502 explicit constexpr pair(_U1
&& __x
, __null_ptr_constant
)
503 : first(std::forward
<_U1
>(__x
)), second(nullptr) { }
505 template<typename _U2
,
506 __enable_if_t
<!__is_lvalue_of
<_U2
, _T2
>::value
508 _DeprConsPair
<true, nullptr_t
, _U2
>(),
510 _GLIBCXX_DEPRECATED_SUGGEST("nullptr")
511 constexpr pair(__null_ptr_constant
, _U2
&& __y
)
512 : first(nullptr), second(std::forward
<_U2
>(__y
)) { }
514 template<typename _U2
,
515 __enable_if_t
<!__is_lvalue_of
<_U2
, _T2
>::value
517 _DeprConsPair
<false, nullptr_t
, _U2
>(),
519 _GLIBCXX_DEPRECATED_SUGGEST("nullptr")
520 explicit pair(__null_ptr_constant
, _U2
&& __y
)
521 : first(nullptr), second(std::forward
<_U2
>(__y
)) { }
524 template<typename _U1
, typename _U2
, typename
525 enable_if
<_PCCP::template
526 _MoveConstructiblePair
<_U1
, _U2
>()
528 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
530 constexpr pair(_U1
&& __x
, _U2
&& __y
)
531 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
)) { }
533 template<typename _U1
, typename _U2
, typename
534 enable_if
<_PCCP::template
535 _MoveConstructiblePair
<_U1
, _U2
>()
537 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
539 explicit constexpr pair(_U1
&& __x
, _U2
&& __y
)
540 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
)) { }
543 template<typename _U1
, typename _U2
, typename
544 enable_if
<_PCCFP
<_U1
, _U2
>::template
545 _MoveConstructiblePair
<_U1
, _U2
>()
546 && _PCCFP
<_U1
, _U2
>::template
547 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
549 constexpr pair(pair
<_U1
, _U2
>&& __p
)
550 : first(std::forward
<_U1
>(__p
.first
)),
551 second(std::forward
<_U2
>(__p
.second
)) { }
553 template<typename _U1
, typename _U2
, typename
554 enable_if
<_PCCFP
<_U1
, _U2
>::template
555 _MoveConstructiblePair
<_U1
, _U2
>()
556 && !_PCCFP
<_U1
, _U2
>::template
557 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
559 explicit constexpr pair(pair
<_U1
, _U2
>&& __p
)
560 : first(std::forward
<_U1
>(__p
.first
)),
561 second(std::forward
<_U2
>(__p
.second
)) { }
564 operator=(typename conditional
<
565 __and_
<is_copy_assignable
<_T1
>,
566 is_copy_assignable
<_T2
>>::value
,
567 const pair
&, const __nonesuch
&>::type __p
)
575 operator=(typename conditional
<
576 __and_
<is_move_assignable
<_T1
>,
577 is_move_assignable
<_T2
>>::value
,
578 pair
&&, __nonesuch
&&>::type __p
)
579 noexcept(__and_
<is_nothrow_move_assignable
<_T1
>,
580 is_nothrow_move_assignable
<_T2
>>::value
)
582 first
= std::forward
<first_type
>(__p
.first
);
583 second
= std::forward
<second_type
>(__p
.second
);
587 template<typename _U1
, typename _U2
>
588 typename enable_if
<__and_
<is_assignable
<_T1
&, const _U1
&>,
589 is_assignable
<_T2
&, const _U2
&>>::value
,
591 operator=(const pair
<_U1
, _U2
>& __p
)
598 template<typename _U1
, typename _U2
>
599 typename enable_if
<__and_
<is_assignable
<_T1
&, _U1
&&>,
600 is_assignable
<_T2
&, _U2
&&>>::value
,
602 operator=(pair
<_U1
, _U2
>&& __p
)
604 first
= std::forward
<_U1
>(__p
.first
);
605 second
= std::forward
<_U2
>(__p
.second
);
608 #endif // lib concepts
610 // C++03 implementation
612 // _GLIBCXX_RESOLVE_LIB_DEFECTS
613 // 265. std::pair::pair() effects overly restrictive
614 /** The default constructor creates @c first and @c second using their
615 * respective default constructors. */
616 pair() : first(), second() { }
618 /// Two objects may be passed to a `pair` constructor to be copied.
619 pair(const _T1
& __a
, const _T2
& __b
)
620 : first(__a
), second(__b
) { }
622 /// Templated constructor to convert from other pairs.
623 template<typename _U1
, typename _U2
>
624 pair(const pair
<_U1
, _U2
>& __p
)
625 : first(__p
.first
), second(__p
.second
) { }
631 #if __cpp_deduction_guides >= 201606
632 template<typename _T1
, typename _T2
> pair(_T1
, _T2
) -> pair
<_T1
, _T2
>;
635 /// Two pairs of the same type are equal iff their members are equal.
636 template<typename _T1
, typename _T2
>
637 inline _GLIBCXX_CONSTEXPR
bool
638 operator==(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
639 { return __x
.first
== __y
.first
&& __x
.second
== __y
.second
; }
641 #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
642 template<typename _T1
, typename _T2
>
643 constexpr common_comparison_category_t
<__detail::__synth3way_t
<_T1
>,
644 __detail::__synth3way_t
<_T2
>>
645 operator<=>(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
647 if (auto __c
= __detail::__synth3way(__x
.first
, __y
.first
); __c
!= 0)
649 return __detail::__synth3way(__x
.second
, __y
.second
);
652 /** Defines a lexicographical order for pairs.
654 * For two pairs of the same type, `P` is ordered before `Q` if
655 * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
656 * are equivalent (neither is less than the other) and `P.second` is less
659 template<typename _T1
, typename _T2
>
660 inline _GLIBCXX_CONSTEXPR
bool
661 operator<(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
662 { return __x
.first
< __y
.first
663 || (!(__y
.first
< __x
.first
) && __x
.second
< __y
.second
); }
665 /// Uses @c operator== to find the result.
666 template<typename _T1
, typename _T2
>
667 inline _GLIBCXX_CONSTEXPR
bool
668 operator!=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
669 { return !(__x
== __y
); }
671 /// Uses @c operator< to find the result.
672 template<typename _T1
, typename _T2
>
673 inline _GLIBCXX_CONSTEXPR
bool
674 operator>(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
675 { return __y
< __x
; }
677 /// Uses @c operator< to find the result.
678 template<typename _T1
, typename _T2
>
679 inline _GLIBCXX_CONSTEXPR
bool
680 operator<=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
681 { return !(__y
< __x
); }
683 /// Uses @c operator< to find the result.
684 template<typename _T1
, typename _T2
>
685 inline _GLIBCXX_CONSTEXPR
bool
686 operator>=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
687 { return !(__x
< __y
); }
688 #endif // !(three_way_comparison && concepts)
690 #if __cplusplus >= 201103L
691 /** Swap overload for pairs. Calls std::pair::swap().
693 * @note This std::swap overload is not declared in C++03 mode,
694 * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
696 template<typename _T1
, typename _T2
>
697 _GLIBCXX20_CONSTEXPR
inline
698 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
699 // Constrained free swap overload, see p0185r1
700 typename enable_if
<__and_
<__is_swappable
<_T1
>,
701 __is_swappable
<_T2
>>::value
>::type
705 swap(pair
<_T1
, _T2
>& __x
, pair
<_T1
, _T2
>& __y
)
706 noexcept(noexcept(__x
.swap(__y
)))
709 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
710 template<typename _T1
, typename _T2
>
711 typename enable_if
<!__and_
<__is_swappable
<_T1
>,
712 __is_swappable
<_T2
>>::value
>::type
713 swap(pair
<_T1
, _T2
>&, pair
<_T1
, _T2
>&) = delete;
715 #endif // __cplusplus >= 201103L
720 * @brief A convenience wrapper for creating a pair from two objects.
721 * @param __x The first object.
722 * @param __y The second object.
723 * @return A newly-constructed pair<> object of the appropriate type.
725 * The C++98 standard says the objects are passed by reference-to-const,
726 * but C++03 says they are passed by value (this was LWG issue #181).
728 * Since C++11 they have been passed by forwarding reference and then
729 * forwarded to the new members of the pair. To create a pair with a
730 * member of reference type, pass a `reference_wrapper` to this function.
732 // _GLIBCXX_RESOLVE_LIB_DEFECTS
733 // 181. make_pair() unintended behavior
734 #if __cplusplus >= 201103L
736 template<typename _T1
, typename _T2
>
737 constexpr pair
<typename __decay_and_strip
<_T1
>::__type
,
738 typename __decay_and_strip
<_T2
>::__type
>
739 make_pair(_T1
&& __x
, _T2
&& __y
)
741 typedef typename __decay_and_strip
<_T1
>::__type __ds_type1
;
742 typedef typename __decay_and_strip
<_T2
>::__type __ds_type2
;
743 typedef pair
<__ds_type1
, __ds_type2
> __pair_type
;
744 return __pair_type(std::forward
<_T1
>(__x
), std::forward
<_T2
>(__y
));
747 template<typename _T1
, typename _T2
>
748 inline pair
<_T1
, _T2
>
749 make_pair(_T1 __x
, _T2 __y
)
750 { return pair
<_T1
, _T2
>(__x
, __y
); }
755 #if __cplusplus >= 201103L
756 // Various functions which give std::pair a tuple-like interface.
758 template<typename _T1
, typename _T2
>
759 struct __is_tuple_like_impl
<pair
<_T1
, _T2
>> : true_type
762 /// Partial specialization for std::pair
763 template<class _Tp1
, class _Tp2
>
764 struct tuple_size
<pair
<_Tp1
, _Tp2
>>
765 : public integral_constant
<size_t, 2> { };
767 /// Partial specialization for std::pair
768 template<class _Tp1
, class _Tp2
>
769 struct tuple_element
<0, pair
<_Tp1
, _Tp2
>>
770 { typedef _Tp1 type
; };
772 /// Partial specialization for std::pair
773 template<class _Tp1
, class _Tp2
>
774 struct tuple_element
<1, pair
<_Tp1
, _Tp2
>>
775 { typedef _Tp2 type
; };
777 /// @cond undocumented
778 template<size_t _Int
>
784 template<typename _Tp1
, typename _Tp2
>
785 static constexpr _Tp1
&
786 __get(pair
<_Tp1
, _Tp2
>& __pair
) noexcept
787 { return __pair
.first
; }
789 template<typename _Tp1
, typename _Tp2
>
790 static constexpr _Tp1
&&
791 __move_get(pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
792 { return std::forward
<_Tp1
>(__pair
.first
); }
794 template<typename _Tp1
, typename _Tp2
>
795 static constexpr const _Tp1
&
796 __const_get(const pair
<_Tp1
, _Tp2
>& __pair
) noexcept
797 { return __pair
.first
; }
799 template<typename _Tp1
, typename _Tp2
>
800 static constexpr const _Tp1
&&
801 __const_move_get(const pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
802 { return std::forward
<const _Tp1
>(__pair
.first
); }
808 template<typename _Tp1
, typename _Tp2
>
809 static constexpr _Tp2
&
810 __get(pair
<_Tp1
, _Tp2
>& __pair
) noexcept
811 { return __pair
.second
; }
813 template<typename _Tp1
, typename _Tp2
>
814 static constexpr _Tp2
&&
815 __move_get(pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
816 { return std::forward
<_Tp2
>(__pair
.second
); }
818 template<typename _Tp1
, typename _Tp2
>
819 static constexpr const _Tp2
&
820 __const_get(const pair
<_Tp1
, _Tp2
>& __pair
) noexcept
821 { return __pair
.second
; }
823 template<typename _Tp1
, typename _Tp2
>
824 static constexpr const _Tp2
&&
825 __const_move_get(const pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
826 { return std::forward
<const _Tp2
>(__pair
.second
); }
831 * std::get overloads for accessing members of std::pair
834 template<size_t _Int
, class _Tp1
, class _Tp2
>
835 constexpr typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&
836 get(pair
<_Tp1
, _Tp2
>& __in
) noexcept
837 { return __pair_get
<_Int
>::__get(__in
); }
839 template<size_t _Int
, class _Tp1
, class _Tp2
>
840 constexpr typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&&
841 get(pair
<_Tp1
, _Tp2
>&& __in
) noexcept
842 { return __pair_get
<_Int
>::__move_get(std::move(__in
)); }
844 template<size_t _Int
, class _Tp1
, class _Tp2
>
845 constexpr const typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&
846 get(const pair
<_Tp1
, _Tp2
>& __in
) noexcept
847 { return __pair_get
<_Int
>::__const_get(__in
); }
849 template<size_t _Int
, class _Tp1
, class _Tp2
>
850 constexpr const typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&&
851 get(const pair
<_Tp1
, _Tp2
>&& __in
) noexcept
852 { return __pair_get
<_Int
>::__const_move_get(std::move(__in
)); }
854 #if __cplusplus >= 201402L
856 #define __cpp_lib_tuples_by_type 201304L
858 template <typename _Tp
, typename _Up
>
860 get(pair
<_Tp
, _Up
>& __p
) noexcept
861 { return __p
.first
; }
863 template <typename _Tp
, typename _Up
>
865 get(const pair
<_Tp
, _Up
>& __p
) noexcept
866 { return __p
.first
; }
868 template <typename _Tp
, typename _Up
>
870 get(pair
<_Tp
, _Up
>&& __p
) noexcept
871 { return std::move(__p
.first
); }
873 template <typename _Tp
, typename _Up
>
874 constexpr const _Tp
&&
875 get(const pair
<_Tp
, _Up
>&& __p
) noexcept
876 { return std::move(__p
.first
); }
878 template <typename _Tp
, typename _Up
>
880 get(pair
<_Up
, _Tp
>& __p
) noexcept
881 { return __p
.second
; }
883 template <typename _Tp
, typename _Up
>
885 get(const pair
<_Up
, _Tp
>& __p
) noexcept
886 { return __p
.second
; }
888 template <typename _Tp
, typename _Up
>
890 get(pair
<_Up
, _Tp
>&& __p
) noexcept
891 { return std::move(__p
.second
); }
893 template <typename _Tp
, typename _Up
>
894 constexpr const _Tp
&&
895 get(const pair
<_Up
, _Tp
>&& __p
) noexcept
896 { return std::move(__p
.second
); }
902 _GLIBCXX_END_NAMESPACE_VERSION
905 #endif /* _STL_PAIR_H */