1 // Pair implementation -*- C++ -*-
3 // Copyright (C) 2001-2024 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
68 namespace std
_GLIBCXX_VISIBILITY(default)
70 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 * @addtogroup utilities
77 #if __cplusplus >= 201103L
78 /// Tag type for piecewise construction of std::pair objects.
79 struct piecewise_construct_t
{ explicit piecewise_construct_t() = default; };
81 /// Tag for piecewise construction of std::pair objects.
82 _GLIBCXX17_INLINE
constexpr piecewise_construct_t piecewise_construct
=
83 piecewise_construct_t();
85 /// @cond undocumented
87 // Forward declarations.
94 #if ! __cpp_lib_concepts
95 // Concept utility functions, reused in conditionally-explicit
97 // See PR 70437, don't look at is_constructible or
98 // is_convertible if the types are the same to
99 // avoid querying those properties for incomplete types.
100 template <bool, typename _T1
, typename _T2
>
103 template <typename _U1
, typename _U2
>
104 static constexpr bool _ConstructiblePair()
106 return __and_
<is_constructible
<_T1
, const _U1
&>,
107 is_constructible
<_T2
, const _U2
&>>::value
;
110 template <typename _U1
, typename _U2
>
111 static constexpr bool _ImplicitlyConvertiblePair()
113 return __and_
<is_convertible
<const _U1
&, _T1
>,
114 is_convertible
<const _U2
&, _T2
>>::value
;
117 template <typename _U1
, typename _U2
>
118 static constexpr bool _MoveConstructiblePair()
120 return __and_
<is_constructible
<_T1
, _U1
&&>,
121 is_constructible
<_T2
, _U2
&&>>::value
;
124 template <typename _U1
, typename _U2
>
125 static constexpr bool _ImplicitlyMoveConvertiblePair()
127 return __and_
<is_convertible
<_U1
&&, _T1
>,
128 is_convertible
<_U2
&&, _T2
>>::value
;
132 template <typename _T1
, typename _T2
>
133 struct _PCC
<false, _T1
, _T2
>
135 template <typename _U1
, typename _U2
>
136 static constexpr bool _ConstructiblePair()
141 template <typename _U1
, typename _U2
>
142 static constexpr bool _ImplicitlyConvertiblePair()
147 template <typename _U1
, typename _U2
>
148 static constexpr bool _MoveConstructiblePair()
153 template <typename _U1
, typename _U2
>
154 static constexpr bool _ImplicitlyMoveConvertiblePair()
159 #endif // lib concepts
162 template<typename _U1
, typename _U2
> class __pair_base
164 #if __cplusplus >= 201103L && ! __cpp_lib_concepts
165 template<typename _T1
, typename _T2
> friend struct pair
;
166 __pair_base() = default;
167 ~__pair_base() = default;
168 __pair_base(const __pair_base
&) = default;
169 __pair_base
& operator=(const __pair_base
&) = delete;
176 * @brief Struct holding two objects of arbitrary type.
178 * @tparam _T1 Type of first object.
179 * @tparam _T2 Type of second object.
181 * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
183 * @headerfile utility
185 template<typename _T1
, typename _T2
>
187 : public __pair_base
<_T1
, _T2
>
189 typedef _T1 first_type
; ///< The type of the `first` member
190 typedef _T2 second_type
; ///< The type of the `second` member
192 _T1 first
; ///< The first member
193 _T2 second
; ///< The second member
195 #if __cplusplus >= 201103L
196 constexpr pair(const pair
&) = default; ///< Copy constructor
197 constexpr pair(pair
&&) = default; ///< Move constructor
199 template<typename
... _Args1
, typename
... _Args2
>
201 pair(piecewise_construct_t
, tuple
<_Args1
...>, tuple
<_Args2
...>);
203 /// Swap the first members and then the second members.
204 _GLIBCXX20_CONSTEXPR
void
206 noexcept(__and_
<__is_nothrow_swappable
<_T1
>,
207 __is_nothrow_swappable
<_T2
>>::value
)
210 swap(first
, __p
.first
);
211 swap(second
, __p
.second
);
214 #if __glibcxx_ranges_zip // >= C++23
215 // As an extension, we constrain the const swap member function in order
216 // to continue accepting explicit instantiation of pairs whose elements
217 // are not all const swappable. Without this constraint, such an
218 // explicit instantiation would also instantiate the ill-formed body of
219 // this function and yield a hard error. This constraint shouldn't
220 // affect the behavior of valid programs.
222 swap(const pair
& __p
) const
223 noexcept(__and_v
<__is_nothrow_swappable
<const _T1
>,
224 __is_nothrow_swappable
<const _T2
>>)
225 requires is_swappable_v
<const _T1
> && is_swappable_v
<const _T2
>
228 swap(first
, __p
.first
);
229 swap(second
, __p
.second
);
234 template<typename
... _Args1
, size_t... _Indexes1
,
235 typename
... _Args2
, size_t... _Indexes2
>
237 pair(tuple
<_Args1
...>&, tuple
<_Args2
...>&,
238 _Index_tuple
<_Indexes1
...>, _Index_tuple
<_Indexes2
...>);
241 #if __cpp_lib_concepts
242 // C++20 implementation using concepts, explicit(bool), fully constexpr.
244 /// Default constructor
246 explicit(__not_
<__and_
<__is_implicitly_default_constructible
<_T1
>,
247 __is_implicitly_default_constructible
<_T2
>>>())
249 requires is_default_constructible_v
<_T1
>
250 && is_default_constructible_v
<_T2
>
256 /// @cond undocumented
257 template<typename _U1
, typename _U2
>
258 static constexpr bool
261 if constexpr (is_constructible_v
<_T1
, _U1
>)
262 return is_constructible_v
<_T2
, _U2
>;
266 template<typename _U1
, typename _U2
>
267 static constexpr bool
268 _S_nothrow_constructible()
270 if constexpr (is_nothrow_constructible_v
<_T1
, _U1
>)
271 return is_nothrow_constructible_v
<_T2
, _U2
>;
275 template<typename _U1
, typename _U2
>
276 static constexpr bool
279 if constexpr (is_convertible_v
<_U1
, _T1
>)
280 return is_convertible_v
<_U2
, _T2
>;
284 // True if construction from _U1 and _U2 would create a dangling ref.
285 template<typename _U1
, typename _U2
>
286 static constexpr bool
289 #if __has_builtin(__reference_constructs_from_temporary)
290 if constexpr (__reference_constructs_from_temporary(_T1
, _U1
&&))
293 return __reference_constructs_from_temporary(_T2
, _U2
&&);
302 /// Constructor accepting lvalues of `first_type` and `second_type`
303 constexpr explicit(!_S_convertible
<const _T1
&, const _T2
&>())
304 pair(const _T1
& __x
, const _T2
& __y
)
305 noexcept(_S_nothrow_constructible
<const _T1
&, const _T2
&>())
306 requires (_S_constructible
<const _T1
&, const _T2
&>())
307 : first(__x
), second(__y
)
310 /// Constructor accepting two values of arbitrary types
311 #if __cplusplus > 202002L
312 template<typename _U1
= _T1
, typename _U2
= _T2
>
314 template<typename _U1
, typename _U2
>
316 requires (_S_constructible
<_U1
, _U2
>()) && (!_S_dangles
<_U1
, _U2
>())
317 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
318 pair(_U1
&& __x
, _U2
&& __y
)
319 noexcept(_S_nothrow_constructible
<_U1
, _U2
>())
320 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
))
323 #if __cplusplus > 202002L
324 template<typename _U1
= _T1
, typename _U2
= _T2
>
326 template<typename _U1
, typename _U2
>
328 requires (_S_constructible
<_U1
, _U2
>()) && (_S_dangles
<_U1
, _U2
>())
329 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
330 pair(_U1
&&, _U2
&&) = delete;
332 /// Converting constructor from a const `pair<U1, U2>` lvalue
333 template<typename _U1
, typename _U2
>
334 requires (_S_constructible
<const _U1
&, const _U2
&>())
335 && (!_S_dangles
<_U1
, _U2
>())
336 constexpr explicit(!_S_convertible
<const _U1
&, const _U2
&>())
337 pair(const pair
<_U1
, _U2
>& __p
)
338 noexcept(_S_nothrow_constructible
<const _U1
&, const _U2
&>())
339 : first(__p
.first
), second(__p
.second
)
342 template<typename _U1
, typename _U2
>
343 requires (_S_constructible
<const _U1
&, const _U2
&>())
344 && (_S_dangles
<const _U1
&, const _U2
&>())
345 constexpr explicit(!_S_convertible
<const _U1
&, const _U2
&>())
346 pair(const pair
<_U1
, _U2
>&) = delete;
348 /// Converting constructor from a non-const `pair<U1, U2>` rvalue
349 template<typename _U1
, typename _U2
>
350 requires (_S_constructible
<_U1
, _U2
>()) && (!_S_dangles
<_U1
, _U2
>())
351 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
352 pair(pair
<_U1
, _U2
>&& __p
)
353 noexcept(_S_nothrow_constructible
<_U1
, _U2
>())
354 : first(std::forward
<_U1
>(__p
.first
)),
355 second(std::forward
<_U2
>(__p
.second
))
358 template<typename _U1
, typename _U2
>
359 requires (_S_constructible
<_U1
, _U2
>()) && (_S_dangles
<_U1
, _U2
>())
360 constexpr explicit(!_S_convertible
<_U1
, _U2
>())
361 pair(pair
<_U1
, _U2
>&&) = delete;
363 #if __glibcxx_ranges_zip // >= C++23
364 /// Converting constructor from a non-const `pair<U1, U2>` lvalue
365 template<typename _U1
, typename _U2
>
366 requires (_S_constructible
<_U1
&, _U2
&>()) && (!_S_dangles
<_U1
&, _U2
&>())
367 constexpr explicit(!_S_convertible
<_U1
&, _U2
&>())
368 pair(pair
<_U1
, _U2
>& __p
)
369 noexcept(_S_nothrow_constructible
<_U1
&, _U2
&>())
370 : first(__p
.first
), second(__p
.second
)
373 template<typename _U1
, typename _U2
>
374 requires (_S_constructible
<_U1
&, _U2
&>()) && (_S_dangles
<_U1
&, _U2
&>())
375 constexpr explicit(!_S_convertible
<_U1
&, _U2
&>())
376 pair(pair
<_U1
, _U2
>&) = delete;
378 /// Converting constructor from a const `pair<U1, U2>` rvalue
379 template<typename _U1
, typename _U2
>
380 requires (_S_constructible
<const _U1
, const _U2
>())
381 && (!_S_dangles
<const _U1
, const _U2
>())
382 constexpr explicit(!_S_convertible
<const _U1
, const _U2
>())
383 pair(const pair
<_U1
, _U2
>&& __p
)
384 noexcept(_S_nothrow_constructible
<const _U1
, const _U2
>())
385 : first(std::forward
<const _U1
>(__p
.first
)),
386 second(std::forward
<const _U2
>(__p
.second
))
389 template<typename _U1
, typename _U2
>
390 requires (_S_constructible
<const _U1
, const _U2
>())
391 && (_S_dangles
<const _U1
, const _U2
>())
392 constexpr explicit(!_S_convertible
<const _U1
, const _U2
>())
393 pair(const pair
<_U1
, _U2
>&&) = delete;
397 /// @cond undocumented
398 template<typename _U1
, typename _U2
>
399 static constexpr bool
402 if constexpr (is_assignable_v
<_T1
&, _U1
>)
403 return is_assignable_v
<_T2
&, _U2
>;
407 template<typename _U1
, typename _U2
>
408 static constexpr bool
409 _S_nothrow_assignable()
411 if constexpr (is_nothrow_assignable_v
<_T1
&, _U1
>)
412 return is_nothrow_assignable_v
<_T2
&, _U2
>;
419 pair
& operator=(const pair
&) = delete;
421 /// Copy assignment operator
423 operator=(const pair
& __p
)
424 noexcept(_S_nothrow_assignable
<const _T1
&, const _T2
&>())
425 requires (_S_assignable
<const _T1
&, const _T2
&>())
432 /// Move assignment operator
434 operator=(pair
&& __p
)
435 noexcept(_S_nothrow_assignable
<_T1
, _T2
>())
436 requires (_S_assignable
<_T1
, _T2
>())
438 first
= std::forward
<first_type
>(__p
.first
);
439 second
= std::forward
<second_type
>(__p
.second
);
443 /// Converting assignment from a const `pair<U1, U2>` lvalue
444 template<typename _U1
, typename _U2
>
446 operator=(const pair
<_U1
, _U2
>& __p
)
447 noexcept(_S_nothrow_assignable
<const _U1
&, const _U2
&>())
448 requires (_S_assignable
<const _U1
&, const _U2
&>())
455 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
456 template<typename _U1
, typename _U2
>
458 operator=(pair
<_U1
, _U2
>&& __p
)
459 noexcept(_S_nothrow_assignable
<_U1
, _U2
>())
460 requires (_S_assignable
<_U1
, _U2
>())
462 first
= std::forward
<_U1
>(__p
.first
);
463 second
= std::forward
<_U2
>(__p
.second
);
467 #if __glibcxx_ranges_zip // >= C++23
468 /// Copy assignment operator (const)
469 constexpr const pair
&
470 operator=(const pair
& __p
) const
471 requires is_copy_assignable_v
<const first_type
>
472 && is_copy_assignable_v
<const second_type
>
479 /// Move assignment operator (const)
480 constexpr const pair
&
481 operator=(pair
&& __p
) const
482 requires is_assignable_v
<const first_type
&, first_type
>
483 && is_assignable_v
<const second_type
&, second_type
>
485 first
= std::forward
<first_type
>(__p
.first
);
486 second
= std::forward
<second_type
>(__p
.second
);
490 /// Converting assignment from a const `pair<U1, U2>` lvalue
491 template<typename _U1
, typename _U2
>
492 constexpr const pair
&
493 operator=(const pair
<_U1
, _U2
>& __p
) const
494 requires is_assignable_v
<const first_type
&, const _U1
&>
495 && is_assignable_v
<const second_type
&, const _U2
&>
502 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
503 template<typename _U1
, typename _U2
>
504 constexpr const pair
&
505 operator=(pair
<_U1
, _U2
>&& __p
) const
506 requires is_assignable_v
<const first_type
&, _U1
>
507 && is_assignable_v
<const second_type
&, _U2
>
509 first
= std::forward
<_U1
>(__p
.first
);
510 second
= std::forward
<_U2
>(__p
.second
);
514 #else // !__cpp_lib_concepts
515 // C++11/14/17 implementation using enable_if, partially constexpr.
517 /// @cond undocumented
518 // Error if construction from _U1 and _U2 would create a dangling ref.
519 #if __has_builtin(__reference_constructs_from_temporary) \
520 && defined _GLIBCXX_DEBUG
521 # define __glibcxx_no_dangling_refs(_U1, _U2) \
522 static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
523 && !__reference_constructs_from_temporary(_T2, _U2), \
524 "std::pair constructor creates a dangling reference")
526 # define __glibcxx_no_dangling_refs(_U1, _U2)
530 /** The default constructor creates @c first and @c second using their
531 * respective default constructors. */
532 template <typename _U1
= _T1
,
534 typename enable_if
<__and_
<
535 __is_implicitly_default_constructible
<_U1
>,
536 __is_implicitly_default_constructible
<_U2
>>
537 ::value
, bool>::type
= true>
539 : first(), second() { }
541 template <typename _U1
= _T1
,
543 typename enable_if
<__and_
<
544 is_default_constructible
<_U1
>,
545 is_default_constructible
<_U2
>,
547 __and_
<__is_implicitly_default_constructible
<_U1
>,
548 __is_implicitly_default_constructible
<_U2
>>>>
549 ::value
, bool>::type
= false>
550 explicit constexpr pair()
551 : first(), second() { }
553 // Shortcut for constraining the templates that don't take pairs.
554 /// @cond undocumented
555 using _PCCP
= _PCC
<true, _T1
, _T2
>;
558 /// Construct from two const lvalues, allowing implicit conversions.
559 template<typename _U1
= _T1
, typename _U2
=_T2
, typename
560 enable_if
<_PCCP::template
561 _ConstructiblePair
<_U1
, _U2
>()
563 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
565 constexpr pair(const _T1
& __a
, const _T2
& __b
)
566 : first(__a
), second(__b
) { }
568 /// Construct from two const lvalues, disallowing implicit conversions.
569 template<typename _U1
= _T1
, typename _U2
=_T2
, typename
570 enable_if
<_PCCP::template
571 _ConstructiblePair
<_U1
, _U2
>()
573 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
575 explicit constexpr pair(const _T1
& __a
, const _T2
& __b
)
576 : first(__a
), second(__b
) { }
578 // Shortcut for constraining the templates that take pairs.
579 /// @cond undocumented
580 template <typename _U1
, typename _U2
>
581 using _PCCFP
= _PCC
<!is_same
<_T1
, _U1
>::value
582 || !is_same
<_T2
, _U2
>::value
,
586 template<typename _U1
, typename _U2
, typename
587 enable_if
<_PCCFP
<_U1
, _U2
>::template
588 _ConstructiblePair
<_U1
, _U2
>()
589 && _PCCFP
<_U1
, _U2
>::template
590 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
592 constexpr pair(const pair
<_U1
, _U2
>& __p
)
593 : first(__p
.first
), second(__p
.second
)
594 { __glibcxx_no_dangling_refs(const _U1
&, const _U2
&); }
596 template<typename _U1
, typename _U2
, typename
597 enable_if
<_PCCFP
<_U1
, _U2
>::template
598 _ConstructiblePair
<_U1
, _U2
>()
599 && !_PCCFP
<_U1
, _U2
>::template
600 _ImplicitlyConvertiblePair
<_U1
, _U2
>(),
602 explicit constexpr pair(const pair
<_U1
, _U2
>& __p
)
603 : first(__p
.first
), second(__p
.second
)
604 { __glibcxx_no_dangling_refs(const _U1
&, const _U2
&); }
606 #if _GLIBCXX_USE_DEPRECATED
607 #if defined(__DEPRECATED)
608 # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
609 __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
610 "initialize std::pair of move-only " \
611 "type and pointer")))
613 # define _GLIBCXX_DEPRECATED_PAIR_CTOR
617 /// @cond undocumented
619 // A type which can be constructed from literal zero, but not nullptr
620 struct __zero_as_null_pointer_constant
622 __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
624 template<typename _Tp
,
625 typename
= __enable_if_t
<is_null_pointer
<_Tp
>::value
>>
626 __zero_as_null_pointer_constant(_Tp
) = delete;
631 // Deprecated extensions to DR 811.
632 // These allow construction from an rvalue and a literal zero,
633 // in cases where the standard says the zero should be deduced as int
634 template<typename _U1
,
635 __enable_if_t
<__and_
<__not_
<is_reference
<_U1
>>,
637 is_constructible
<_T1
, _U1
>,
638 __not_
<is_constructible
<_T1
, const _U1
&>>,
639 is_convertible
<_U1
, _T1
>>::value
,
641 _GLIBCXX_DEPRECATED_PAIR_CTOR
643 pair(_U1
&& __x
, __zero_as_null_pointer_constant
, ...)
644 : first(std::forward
<_U1
>(__x
)), second(nullptr)
645 { __glibcxx_no_dangling_refs(_U1
&&, std::nullptr_t
); }
647 template<typename _U1
,
648 __enable_if_t
<__and_
<__not_
<is_reference
<_U1
>>,
650 is_constructible
<_T1
, _U1
>,
651 __not_
<is_constructible
<_T1
, const _U1
&>>,
652 __not_
<is_convertible
<_U1
, _T1
>>>::value
,
654 _GLIBCXX_DEPRECATED_PAIR_CTOR
656 pair(_U1
&& __x
, __zero_as_null_pointer_constant
, ...)
657 : first(std::forward
<_U1
>(__x
)), second(nullptr)
658 { __glibcxx_no_dangling_refs(_U1
&&, std::nullptr_t
); }
660 template<typename _U2
,
661 __enable_if_t
<__and_
<is_pointer
<_T1
>,
662 __not_
<is_reference
<_U2
>>,
663 is_constructible
<_T2
, _U2
>,
664 __not_
<is_constructible
<_T2
, const _U2
&>>,
665 is_convertible
<_U2
, _T2
>>::value
,
667 _GLIBCXX_DEPRECATED_PAIR_CTOR
669 pair(__zero_as_null_pointer_constant
, _U2
&& __y
, ...)
670 : first(nullptr), second(std::forward
<_U2
>(__y
))
671 { __glibcxx_no_dangling_refs(std::nullptr_t
, _U2
&&); }
673 template<typename _U2
,
674 __enable_if_t
<__and_
<is_pointer
<_T1
>,
675 __not_
<is_reference
<_U2
>>,
676 is_constructible
<_T2
, _U2
>,
677 __not_
<is_constructible
<_T2
, const _U2
&>>,
678 __not_
<is_convertible
<_U2
, _T2
>>>::value
,
680 _GLIBCXX_DEPRECATED_PAIR_CTOR
682 pair(__zero_as_null_pointer_constant
, _U2
&& __y
, ...)
683 : first(nullptr), second(std::forward
<_U2
>(__y
))
684 { __glibcxx_no_dangling_refs(std::nullptr_t
, _U2
&&); }
685 #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
688 template<typename _U1
, typename _U2
, typename
689 enable_if
<_PCCP::template
690 _MoveConstructiblePair
<_U1
, _U2
>()
692 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
694 constexpr pair(_U1
&& __x
, _U2
&& __y
)
695 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
))
696 { __glibcxx_no_dangling_refs(_U1
&&, _U2
&&); }
698 template<typename _U1
, typename _U2
, typename
699 enable_if
<_PCCP::template
700 _MoveConstructiblePair
<_U1
, _U2
>()
702 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
704 explicit constexpr pair(_U1
&& __x
, _U2
&& __y
)
705 : first(std::forward
<_U1
>(__x
)), second(std::forward
<_U2
>(__y
))
706 { __glibcxx_no_dangling_refs(_U1
&&, _U2
&&); }
709 template<typename _U1
, typename _U2
, typename
710 enable_if
<_PCCFP
<_U1
, _U2
>::template
711 _MoveConstructiblePair
<_U1
, _U2
>()
712 && _PCCFP
<_U1
, _U2
>::template
713 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
715 constexpr pair(pair
<_U1
, _U2
>&& __p
)
716 : first(std::forward
<_U1
>(__p
.first
)),
717 second(std::forward
<_U2
>(__p
.second
))
718 { __glibcxx_no_dangling_refs(_U1
&&, _U2
&&); }
720 template<typename _U1
, typename _U2
, typename
721 enable_if
<_PCCFP
<_U1
, _U2
>::template
722 _MoveConstructiblePair
<_U1
, _U2
>()
723 && !_PCCFP
<_U1
, _U2
>::template
724 _ImplicitlyMoveConvertiblePair
<_U1
, _U2
>(),
726 explicit constexpr pair(pair
<_U1
, _U2
>&& __p
)
727 : first(std::forward
<_U1
>(__p
.first
)),
728 second(std::forward
<_U2
>(__p
.second
))
729 { __glibcxx_no_dangling_refs(_U1
&&, _U2
&&); }
731 #undef __glibcxx_no_dangling_refs
734 operator=(__conditional_t
<__and_
<is_copy_assignable
<_T1
>,
735 is_copy_assignable
<_T2
>>::value
,
736 const pair
&, const __nonesuch
&> __p
)
744 operator=(__conditional_t
<__and_
<is_move_assignable
<_T1
>,
745 is_move_assignable
<_T2
>>::value
,
746 pair
&&, __nonesuch
&&> __p
)
747 noexcept(__and_
<is_nothrow_move_assignable
<_T1
>,
748 is_nothrow_move_assignable
<_T2
>>::value
)
750 first
= std::forward
<first_type
>(__p
.first
);
751 second
= std::forward
<second_type
>(__p
.second
);
755 template<typename _U1
, typename _U2
>
756 typename enable_if
<__and_
<is_assignable
<_T1
&, const _U1
&>,
757 is_assignable
<_T2
&, const _U2
&>>::value
,
759 operator=(const pair
<_U1
, _U2
>& __p
)
766 template<typename _U1
, typename _U2
>
767 typename enable_if
<__and_
<is_assignable
<_T1
&, _U1
&&>,
768 is_assignable
<_T2
&, _U2
&&>>::value
,
770 operator=(pair
<_U1
, _U2
>&& __p
)
772 first
= std::forward
<_U1
>(__p
.first
);
773 second
= std::forward
<_U2
>(__p
.second
);
776 #endif // lib concepts
778 // C++03 implementation
780 // _GLIBCXX_RESOLVE_LIB_DEFECTS
781 // 265. std::pair::pair() effects overly restrictive
782 /** The default constructor creates @c first and @c second using their
783 * respective default constructors. */
784 pair() : first(), second() { }
786 /// Two objects may be passed to a `pair` constructor to be copied.
787 pair(const _T1
& __a
, const _T2
& __b
)
788 : first(__a
), second(__b
) { }
790 /// Templated constructor to convert from other pairs.
791 template<typename _U1
, typename _U2
>
792 pair(const pair
<_U1
, _U2
>& __p
)
793 : first(__p
.first
), second(__p
.second
)
795 #if __has_builtin(__reference_constructs_from_temporary)
796 #pragma GCC diagnostic push
797 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
798 typedef int _DanglingCheck1
[
799 __reference_constructs_from_temporary(_T1
, const _U1
&) ? -1 : 1
801 typedef int _DanglingCheck2
[
802 __reference_constructs_from_temporary(_T2
, const _U2
&) ? -1 : 1
804 #pragma GCC diagnostic pop
812 #if __cpp_deduction_guides >= 201606
813 template<typename _T1
, typename _T2
> pair(_T1
, _T2
) -> pair
<_T1
, _T2
>;
816 /// Two pairs of the same type are equal iff their members are equal.
817 template<typename _T1
, typename _T2
>
818 inline _GLIBCXX_CONSTEXPR
bool
819 operator==(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
820 { return __x
.first
== __y
.first
&& __x
.second
== __y
.second
; }
822 #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
823 template<typename _T1
, typename _T2
>
824 constexpr common_comparison_category_t
<__detail::__synth3way_t
<_T1
>,
825 __detail::__synth3way_t
<_T2
>>
826 operator<=>(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
828 if (auto __c
= __detail::__synth3way(__x
.first
, __y
.first
); __c
!= 0)
830 return __detail::__synth3way(__x
.second
, __y
.second
);
833 /** Defines a lexicographical order for pairs.
835 * For two pairs of the same type, `P` is ordered before `Q` if
836 * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
837 * are equivalent (neither is less than the other) and `P.second` is less
840 template<typename _T1
, typename _T2
>
841 inline _GLIBCXX_CONSTEXPR
bool
842 operator<(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
843 { return __x
.first
< __y
.first
844 || (!(__y
.first
< __x
.first
) && __x
.second
< __y
.second
); }
846 /// Uses @c operator== to find the result.
847 template<typename _T1
, typename _T2
>
848 inline _GLIBCXX_CONSTEXPR
bool
849 operator!=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
850 { return !(__x
== __y
); }
852 /// Uses @c operator< to find the result.
853 template<typename _T1
, typename _T2
>
854 inline _GLIBCXX_CONSTEXPR
bool
855 operator>(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
856 { return __y
< __x
; }
858 /// Uses @c operator< to find the result.
859 template<typename _T1
, typename _T2
>
860 inline _GLIBCXX_CONSTEXPR
bool
861 operator<=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
862 { return !(__y
< __x
); }
864 /// Uses @c operator< to find the result.
865 template<typename _T1
, typename _T2
>
866 inline _GLIBCXX_CONSTEXPR
bool
867 operator>=(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
868 { return !(__x
< __y
); }
869 #endif // !(three_way_comparison && concepts)
871 #if __cplusplus >= 201103L
872 /** Swap overload for pairs. Calls std::pair::swap().
874 * @note This std::swap overload is not declared in C++03 mode,
875 * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
877 template<typename _T1
, typename _T2
>
878 _GLIBCXX20_CONSTEXPR
inline
879 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
880 // Constrained free swap overload, see p0185r1
881 typename enable_if
<__and_
<__is_swappable
<_T1
>,
882 __is_swappable
<_T2
>>::value
>::type
886 swap(pair
<_T1
, _T2
>& __x
, pair
<_T1
, _T2
>& __y
)
887 noexcept(noexcept(__x
.swap(__y
)))
890 #if __glibcxx_ranges_zip // >= C++23
891 template<typename _T1
, typename _T2
>
892 requires is_swappable_v
<const _T1
> && is_swappable_v
<const _T2
>
894 swap(const pair
<_T1
, _T2
>& __x
, const pair
<_T1
, _T2
>& __y
)
895 noexcept(noexcept(__x
.swap(__y
)))
899 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
900 template<typename _T1
, typename _T2
>
901 typename enable_if
<!__and_
<__is_swappable
<_T1
>,
902 __is_swappable
<_T2
>>::value
>::type
903 swap(pair
<_T1
, _T2
>&, pair
<_T1
, _T2
>&) = delete;
905 #endif // __cplusplus >= 201103L
910 * @brief A convenience wrapper for creating a pair from two objects.
911 * @param __x The first object.
912 * @param __y The second object.
913 * @return A newly-constructed pair<> object of the appropriate type.
915 * The C++98 standard says the objects are passed by reference-to-const,
916 * but C++03 says they are passed by value (this was LWG issue #181).
918 * Since C++11 they have been passed by forwarding reference and then
919 * forwarded to the new members of the pair. To create a pair with a
920 * member of reference type, pass a `reference_wrapper` to this function.
922 // _GLIBCXX_RESOLVE_LIB_DEFECTS
923 // 181. make_pair() unintended behavior
924 #if __cplusplus >= 201103L
926 template<typename _T1
, typename _T2
>
927 constexpr pair
<typename __decay_and_strip
<_T1
>::__type
,
928 typename __decay_and_strip
<_T2
>::__type
>
929 make_pair(_T1
&& __x
, _T2
&& __y
)
931 typedef typename __decay_and_strip
<_T1
>::__type __ds_type1
;
932 typedef typename __decay_and_strip
<_T2
>::__type __ds_type2
;
933 typedef pair
<__ds_type1
, __ds_type2
> __pair_type
;
934 return __pair_type(std::forward
<_T1
>(__x
), std::forward
<_T2
>(__y
));
937 template<typename _T1
, typename _T2
>
938 inline pair
<_T1
, _T2
>
939 make_pair(_T1 __x
, _T2 __y
)
940 { return pair
<_T1
, _T2
>(__x
, __y
); }
945 #if __cplusplus >= 201103L
946 // Various functions which give std::pair a tuple-like interface.
948 /// @cond undocumented
949 template<typename _T1
, typename _T2
>
950 struct __is_tuple_like_impl
<pair
<_T1
, _T2
>> : true_type
954 /// Partial specialization for std::pair
955 template<class _Tp1
, class _Tp2
>
956 struct tuple_size
<pair
<_Tp1
, _Tp2
>>
957 : public integral_constant
<size_t, 2> { };
959 /// Partial specialization for std::pair
960 template<class _Tp1
, class _Tp2
>
961 struct tuple_element
<0, pair
<_Tp1
, _Tp2
>>
962 { typedef _Tp1 type
; };
964 /// Partial specialization for std::pair
965 template<class _Tp1
, class _Tp2
>
966 struct tuple_element
<1, pair
<_Tp1
, _Tp2
>>
967 { typedef _Tp2 type
; };
969 #if __cplusplus >= 201703L
970 template<typename _Tp1
, typename _Tp2
>
971 inline constexpr size_t tuple_size_v
<pair
<_Tp1
, _Tp2
>> = 2;
973 template<typename _Tp1
, typename _Tp2
>
974 inline constexpr size_t tuple_size_v
<const pair
<_Tp1
, _Tp2
>> = 2;
976 template<typename _Tp
>
977 inline constexpr bool __is_pair
= false;
979 template<typename _Tp
, typename _Up
>
980 inline constexpr bool __is_pair
<pair
<_Tp
, _Up
>> = true;
983 /// @cond undocumented
984 template<size_t _Int
>
990 template<typename _Tp1
, typename _Tp2
>
991 static constexpr _Tp1
&
992 __get(pair
<_Tp1
, _Tp2
>& __pair
) noexcept
993 { return __pair
.first
; }
995 template<typename _Tp1
, typename _Tp2
>
996 static constexpr _Tp1
&&
997 __move_get(pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
998 { return std::forward
<_Tp1
>(__pair
.first
); }
1000 template<typename _Tp1
, typename _Tp2
>
1001 static constexpr const _Tp1
&
1002 __const_get(const pair
<_Tp1
, _Tp2
>& __pair
) noexcept
1003 { return __pair
.first
; }
1005 template<typename _Tp1
, typename _Tp2
>
1006 static constexpr const _Tp1
&&
1007 __const_move_get(const pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
1008 { return std::forward
<const _Tp1
>(__pair
.first
); }
1012 struct __pair_get
<1>
1014 template<typename _Tp1
, typename _Tp2
>
1015 static constexpr _Tp2
&
1016 __get(pair
<_Tp1
, _Tp2
>& __pair
) noexcept
1017 { return __pair
.second
; }
1019 template<typename _Tp1
, typename _Tp2
>
1020 static constexpr _Tp2
&&
1021 __move_get(pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
1022 { return std::forward
<_Tp2
>(__pair
.second
); }
1024 template<typename _Tp1
, typename _Tp2
>
1025 static constexpr const _Tp2
&
1026 __const_get(const pair
<_Tp1
, _Tp2
>& __pair
) noexcept
1027 { return __pair
.second
; }
1029 template<typename _Tp1
, typename _Tp2
>
1030 static constexpr const _Tp2
&&
1031 __const_move_get(const pair
<_Tp1
, _Tp2
>&& __pair
) noexcept
1032 { return std::forward
<const _Tp2
>(__pair
.second
); }
1037 * std::get overloads for accessing members of std::pair
1040 template<size_t _Int
, class _Tp1
, class _Tp2
>
1041 constexpr typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&
1042 get(pair
<_Tp1
, _Tp2
>& __in
) noexcept
1043 { return __pair_get
<_Int
>::__get(__in
); }
1045 template<size_t _Int
, class _Tp1
, class _Tp2
>
1046 constexpr typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&&
1047 get(pair
<_Tp1
, _Tp2
>&& __in
) noexcept
1048 { return __pair_get
<_Int
>::__move_get(std::move(__in
)); }
1050 template<size_t _Int
, class _Tp1
, class _Tp2
>
1051 constexpr const typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&
1052 get(const pair
<_Tp1
, _Tp2
>& __in
) noexcept
1053 { return __pair_get
<_Int
>::__const_get(__in
); }
1055 template<size_t _Int
, class _Tp1
, class _Tp2
>
1056 constexpr const typename tuple_element
<_Int
, pair
<_Tp1
, _Tp2
>>::type
&&
1057 get(const pair
<_Tp1
, _Tp2
>&& __in
) noexcept
1058 { return __pair_get
<_Int
>::__const_move_get(std::move(__in
)); }
1061 #ifdef __glibcxx_tuples_by_type // C++ >= 14
1062 template <typename _Tp
, typename _Up
>
1064 get(pair
<_Tp
, _Up
>& __p
) noexcept
1065 { return __p
.first
; }
1067 template <typename _Tp
, typename _Up
>
1068 constexpr const _Tp
&
1069 get(const pair
<_Tp
, _Up
>& __p
) noexcept
1070 { return __p
.first
; }
1072 template <typename _Tp
, typename _Up
>
1074 get(pair
<_Tp
, _Up
>&& __p
) noexcept
1075 { return std::move(__p
.first
); }
1077 template <typename _Tp
, typename _Up
>
1078 constexpr const _Tp
&&
1079 get(const pair
<_Tp
, _Up
>&& __p
) noexcept
1080 { return std::move(__p
.first
); }
1082 template <typename _Tp
, typename _Up
>
1084 get(pair
<_Up
, _Tp
>& __p
) noexcept
1085 { return __p
.second
; }
1087 template <typename _Tp
, typename _Up
>
1088 constexpr const _Tp
&
1089 get(const pair
<_Up
, _Tp
>& __p
) noexcept
1090 { return __p
.second
; }
1092 template <typename _Tp
, typename _Up
>
1094 get(pair
<_Up
, _Tp
>&& __p
) noexcept
1095 { return std::move(__p
.second
); }
1097 template <typename _Tp
, typename _Up
>
1098 constexpr const _Tp
&&
1099 get(const pair
<_Up
, _Tp
>&& __p
) noexcept
1100 { return std::move(__p
.second
); }
1101 #endif // __glibcxx_tuples_by_type
1104 #if __glibcxx_ranges_zip // >= C++23
1105 template<typename _T1
, typename _T2
, typename _U1
, typename _U2
,
1106 template<typename
> class _TQual
, template<typename
> class _UQual
>
1107 requires requires
{ typename pair
<common_reference_t
<_TQual
<_T1
>, _UQual
<_U1
>>,
1108 common_reference_t
<_TQual
<_T2
>, _UQual
<_U2
>>>; }
1109 struct basic_common_reference
<pair
<_T1
, _T2
>, pair
<_U1
, _U2
>, _TQual
, _UQual
>
1111 using type
= pair
<common_reference_t
<_TQual
<_T1
>, _UQual
<_U1
>>,
1112 common_reference_t
<_TQual
<_T2
>, _UQual
<_U2
>>>;
1115 template<typename _T1
, typename _T2
, typename _U1
, typename _U2
>
1116 requires requires
{ typename pair
<common_type_t
<_T1
, _U1
>, common_type_t
<_T2
, _U2
>>; }
1117 struct common_type
<pair
<_T1
, _T2
>, pair
<_U1
, _U2
>>
1118 { using type
= pair
<common_type_t
<_T1
, _U1
>, common_type_t
<_T2
, _U2
>>; };
1124 _GLIBCXX_END_NAMESPACE_VERSION
1127 #endif /* _STL_PAIR_H */