1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001-2023 Free Software Foundation, Inc.
4//
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)
9// any later version.
10
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.
15
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.
19
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/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
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.
37 *
38 *
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
41 *
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.
49 */
50
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}
54 */
55
56#ifndef _STL_PAIR_H
57#define _STL_PAIR_H 1
58
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
63#endif
64#if __cplusplus >= 202002L
65# include <compare>
66# define __cpp_lib_constexpr_utility 201811L
67#endif
68
69namespace std _GLIBCXX_VISIBILITY(default)
70{
71_GLIBCXX_BEGIN_NAMESPACE_VERSION
72
73 /**
74 * @addtogroup utilities
75 * @{
76 */
77
78#if __cplusplus >= 201103L
79 /// Tag type for piecewise construction of std::pair objects.
80 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
81
82 /// Tag for piecewise construction of std::pair objects.
83 _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
84 piecewise_construct_t();
85
86 /// @cond undocumented
87
88 // Forward declarations.
89 template<typename...>
90 class tuple;
91
92 template<size_t...>
93 struct _Index_tuple;
94
95#if ! __cpp_lib_concepts
96 // Concept utility functions, reused in conditionally-explicit
97 // constructors.
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>
102 struct _PCC
103 {
104 template <typename _U1, typename _U2>
105 static constexpr bool _ConstructiblePair()
106 {
107 return __and_<is_constructible<_T1, const _U1&>,
108 is_constructible<_T2, const _U2&>>::value;
109 }
110
111 template <typename _U1, typename _U2>
112 static constexpr bool _ImplicitlyConvertiblePair()
113 {
114 return __and_<is_convertible<const _U1&, _T1>,
115 is_convertible<const _U2&, _T2>>::value;
116 }
117
118 template <typename _U1, typename _U2>
119 static constexpr bool _MoveConstructiblePair()
120 {
121 return __and_<is_constructible<_T1, _U1&&>,
122 is_constructible<_T2, _U2&&>>::value;
123 }
124
125 template <typename _U1, typename _U2>
126 static constexpr bool _ImplicitlyMoveConvertiblePair()
127 {
128 return __and_<is_convertible<_U1&&, _T1>,
129 is_convertible<_U2&&, _T2>>::value;
130 }
131 };
132
133 template <typename _T1, typename _T2>
134 struct _PCC<false, _T1, _T2>
135 {
136 template <typename _U1, typename _U2>
137 static constexpr bool _ConstructiblePair()
138 {
139 return false;
140 }
141
142 template <typename _U1, typename _U2>
143 static constexpr bool _ImplicitlyConvertiblePair()
144 {
145 return false;
146 }
147
148 template <typename _U1, typename _U2>
149 static constexpr bool _MoveConstructiblePair()
150 {
151 return false;
152 }
153
154 template <typename _U1, typename _U2>
155 static constexpr bool _ImplicitlyMoveConvertiblePair()
156 {
157 return false;
158 }
159 };
160#endif // lib concepts
161#endif // C++11
162
163 template<typename _U1, typename _U2> class __pair_base
164 {
165#if __cplusplus >= 201103L && ! __cpp_lib_concepts
166 template<typename _T1, typename _T2> friend struct pair;
167 __pair_base() = default;
168 ~__pair_base() = default;
169 __pair_base(const __pair_base&) = default;
170 __pair_base& operator=(const __pair_base&) = delete;
171#endif // C++11
172 };
173
174 /// @endcond
175
176 /**
177 * @brief Struct holding two objects of arbitrary type.
178 *
179 * @tparam _T1 Type of first object.
180 * @tparam _T2 Type of second object.
181 *
182 * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
183 *
184 * @headerfile utility
185 */
186 template<typename _T1, typename _T2>
187 struct pair
188 : public __pair_base<_T1, _T2>
189 {
190 typedef _T1 first_type; ///< The type of the `first` member
191 typedef _T2 second_type; ///< The type of the `second` member
192
193 _T1 first; ///< The first member
194 _T2 second; ///< The second member
195
196#if __cplusplus >= 201103L
197 constexpr pair(const pair&) = default; ///< Copy constructor
198 constexpr pair(pair&&) = default; ///< Move constructor
199
200 template<typename... _Args1, typename... _Args2>
201 _GLIBCXX20_CONSTEXPR
202 pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
203
204 /// Swap the first members and then the second members.
205 _GLIBCXX20_CONSTEXPR void
206 swap(pair& __p)
207 noexcept(__and_<__is_nothrow_swappable<_T1>,
208 __is_nothrow_swappable<_T2>>::value)
209 {
210 using std::swap;
211 swap(first, __p.first);
212 swap(second, __p.second);
213 }
214
215#if __cplusplus > 202002L
216 // As an extension, we constrain the const swap member function in order
217 // to continue accepting explicit instantiation of pairs whose elements
218 // are not all const swappable. Without this constraint, such an
219 // explicit instantiation would also instantiate the ill-formed body of
220 // this function and yield a hard error. This constraint shouldn't
221 // affect the behavior of valid programs.
222 constexpr void
223 swap(const pair& __p) const
224 noexcept(__and_v<__is_nothrow_swappable<const _T1>,
225 __is_nothrow_swappable<const _T2>>)
226 requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
227 {
228 using std::swap;
229 swap(first, __p.first);
230 swap(second, __p.second);
231 }
232#endif // C++23
233
234 private:
235 template<typename... _Args1, size_t... _Indexes1,
236 typename... _Args2, size_t... _Indexes2>
237 _GLIBCXX20_CONSTEXPR
238 pair(tuple<_Args1...>&, tuple<_Args2...>&,
239 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
240 public:
241
242#if __cpp_lib_concepts
243 // C++20 implementation using concepts, explicit(bool), fully constexpr.
244
245 /// Default constructor
246 constexpr
247 explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
248 __is_implicitly_default_constructible<_T2>>>())
249 pair()
250 requires is_default_constructible_v<_T1>
251 && is_default_constructible_v<_T2>
252 : first(), second()
253 { }
254
255 private:
256
257 /// @cond undocumented
258 template<typename _U1, typename _U2>
259 static constexpr bool
260 _S_constructible()
261 {
262 if constexpr (is_constructible_v<_T1, _U1>)
263 return is_constructible_v<_T2, _U2>;
264 return false;
265 }
266
267 template<typename _U1, typename _U2>
268 static constexpr bool
269 _S_nothrow_constructible()
270 {
271 if constexpr (is_nothrow_constructible_v<_T1, _U1>)
272 return is_nothrow_constructible_v<_T2, _U2>;
273 return false;
274 }
275
276 template<typename _U1, typename _U2>
277 static constexpr bool
278 _S_convertible()
279 {
280 if constexpr (is_convertible_v<_U1, _T1>)
281 return is_convertible_v<_U2, _T2>;
282 return false;
283 }
284
285 // True if construction from _U1 and _U2 would create a dangling ref.
286 template<typename _U1, typename _U2>
287 static constexpr bool
288 _S_dangles()
289 {
290#if __has_builtin(__reference_constructs_from_temporary)
291 if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
292 return true;
293 else
294 return __reference_constructs_from_temporary(_T2, _U2&&);
295#else
296 return false;
297#endif
298 }
299 /// @endcond
300
301 public:
302
303 /// Constructor accepting lvalues of `first_type` and `second_type`
304 constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
305 pair(const _T1& __x, const _T2& __y)
306 noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
307 requires (_S_constructible<const _T1&, const _T2&>())
308 : first(__x), second(__y)
309 { }
310
311 /// Constructor accepting two values of arbitrary types
312 template<typename _U1, typename _U2>
313 requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
314 constexpr explicit(!_S_convertible<_U1, _U2>())
315 pair(_U1&& __x, _U2&& __y)
316 noexcept(_S_nothrow_constructible<_U1, _U2>())
317 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
318 { }
319
320 template<typename _U1, typename _U2>
321 requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
322 constexpr explicit(!_S_convertible<_U1, _U2>())
323 pair(_U1&&, _U2&&) = delete;
324
325 /// Converting constructor from a const `pair<U1, U2>` lvalue
326 template<typename _U1, typename _U2>
327 requires (_S_constructible<const _U1&, const _U2&>())
328 && (!_S_dangles<_U1, _U2>())
329 constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
330 pair(const pair<_U1, _U2>& __p)
331 noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
332 : first(__p.first), second(__p.second)
333 { }
334
335 template<typename _U1, typename _U2>
336 requires (_S_constructible<const _U1&, const _U2&>())
337 && (_S_dangles<const _U1&, const _U2&>())
338 constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
339 pair(const pair<_U1, _U2>&) = delete;
340
341 /// Converting constructor from a non-const `pair<U1, U2>` rvalue
342 template<typename _U1, typename _U2>
343 requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
344 constexpr explicit(!_S_convertible<_U1, _U2>())
345 pair(pair<_U1, _U2>&& __p)
346 noexcept(_S_nothrow_constructible<_U1, _U2>())
347 : first(std::forward<_U1>(__p.first)),
348 second(std::forward<_U2>(__p.second))
349 { }
350
351 template<typename _U1, typename _U2>
352 requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
353 constexpr explicit(!_S_convertible<_U1, _U2>())
354 pair(pair<_U1, _U2>&&) = delete;
355
356#if __cplusplus > 202002L
357 /// Converting constructor from a non-const `pair<U1, U2>` lvalue
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>& __p)
362 noexcept(_S_nothrow_constructible<_U1&, _U2&>())
363 : first(__p.first), second(__p.second)
364 { }
365
366 template<typename _U1, typename _U2>
367 requires (_S_constructible<_U1&, _U2&>()) && (_S_dangles<_U1&, _U2&>())
368 constexpr explicit(!_S_convertible<_U1&, _U2&>())
369 pair(pair<_U1, _U2>&) = delete;
370
371 /// Converting constructor from a const `pair<U1, U2>` rvalue
372 template<typename _U1, typename _U2>
373 requires (_S_constructible<const _U1, const _U2>())
374 && (!_S_dangles<const _U1, const _U2>())
375 constexpr explicit(!_S_convertible<const _U1, const _U2>())
376 pair(const pair<_U1, _U2>&& __p)
377 noexcept(_S_nothrow_constructible<const _U1, const _U2>())
378 : first(std::forward<const _U1>(__p.first)),
379 second(std::forward<const _U2>(__p.second))
380 { }
381
382 template<typename _U1, typename _U2>
383 requires (_S_constructible<const _U1, const _U2>())
384 && (_S_dangles<const _U1, const _U2>())
385 constexpr explicit(!_S_convertible<const _U1, const _U2>())
386 pair(const pair<_U1, _U2>&&) = delete;
387#endif // C++23
388
389 private:
390 /// @cond undocumented
391 template<typename _U1, typename _U2>
392 static constexpr bool
393 _S_assignable()
394 {
395 if constexpr (is_assignable_v<_T1&, _U1>)
396 return is_assignable_v<_T2&, _U2>;
397 return false;
398 }
399
400 template<typename _U1, typename _U2>
401 static constexpr bool
402 _S_nothrow_assignable()
403 {
404 if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
405 return is_nothrow_assignable_v<_T2&, _U2>;
406 return false;
407 }
408 /// @endcond
409
410 public:
411
412 pair& operator=(const pair&) = delete;
413
414 /// Copy assignment operator
415 constexpr pair&
416 operator=(const pair& __p)
417 noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
418 requires (_S_assignable<const _T1&, const _T2&>())
419 {
420 first = __p.first;
421 second = __p.second;
422 return *this;
423 }
424
425 /// Move assignment operator
426 constexpr pair&
427 operator=(pair&& __p)
428 noexcept(_S_nothrow_assignable<_T1, _T2>())
429 requires (_S_assignable<_T1, _T2>())
430 {
431 first = std::forward<first_type>(__p.first);
432 second = std::forward<second_type>(__p.second);
433 return *this;
434 }
435
436 /// Converting assignment from a const `pair<U1, U2>` lvalue
437 template<typename _U1, typename _U2>
438 constexpr pair&
439 operator=(const pair<_U1, _U2>& __p)
440 noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
441 requires (_S_assignable<const _U1&, const _U2&>())
442 {
443 first = __p.first;
444 second = __p.second;
445 return *this;
446 }
447
448 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
449 template<typename _U1, typename _U2>
450 constexpr pair&
451 operator=(pair<_U1, _U2>&& __p)
452 noexcept(_S_nothrow_assignable<_U1, _U2>())
453 requires (_S_assignable<_U1, _U2>())
454 {
455 first = std::forward<_U1>(__p.first);
456 second = std::forward<_U2>(__p.second);
457 return *this;
458 }
459
460#if __cplusplus > 202002L
461 /// Copy assignment operator (const)
462 constexpr const pair&
463 operator=(const pair& __p) const
464 requires is_copy_assignable_v<const first_type>
465 && is_copy_assignable_v<const second_type>
466 {
467 first = __p.first;
468 second = __p.second;
469 return *this;
470 }
471
472 /// Move assignment operator (const)
473 constexpr const pair&
474 operator=(pair&& __p) const
475 requires is_assignable_v<const first_type&, first_type>
476 && is_assignable_v<const second_type&, second_type>
477 {
478 first = std::forward<first_type>(__p.first);
479 second = std::forward<second_type>(__p.second);
480 return *this;
481 }
482
483 /// Converting assignment from a const `pair<U1, U2>` lvalue
484 template<typename _U1, typename _U2>
485 constexpr const pair&
486 operator=(const pair<_U1, _U2>& __p) const
487 requires is_assignable_v<const first_type&, const _U1&>
488 && is_assignable_v<const second_type&, const _U2&>
489 {
490 first = __p.first;
491 second = __p.second;
492 return *this;
493 }
494
495 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
496 template<typename _U1, typename _U2>
497 constexpr const pair&
498 operator=(pair<_U1, _U2>&& __p) const
499 requires is_assignable_v<const first_type&, _U1>
500 && is_assignable_v<const second_type&, _U2>
501 {
502 first = std::forward<_U1>(__p.first);
503 second = std::forward<_U2>(__p.second);
504 return *this;
505 }
506#endif // C++23
507#else // !__cpp_lib_concepts
508 // C++11/14/17 implementation using enable_if, partially constexpr.
509
510 /// @cond undocumented
511 // Error if construction from _U1 and _U2 would create a dangling ref.
512#if __has_builtin(__reference_constructs_from_temporary) \
513 && defined _GLIBCXX_DEBUG
514# define __glibcxx_no_dangling_refs(_U1, _U2) \
515 static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
516 && !__reference_constructs_from_temporary(_T2, _U2), \
517 "std::pair constructor creates a dangling reference")
518#else
519# define __glibcxx_no_dangling_refs(_U1, _U2)
520#endif
521 /// @endcond
522
523 /** The default constructor creates @c first and @c second using their
524 * respective default constructors. */
525 template <typename _U1 = _T1,
526 typename _U2 = _T2,
527 typename enable_if<__and_<
528 __is_implicitly_default_constructible<_U1>,
529 __is_implicitly_default_constructible<_U2>>
530 ::value, bool>::type = true>
531 constexpr pair()
532 : first(), second() { }
533
534 template <typename _U1 = _T1,
535 typename _U2 = _T2,
536 typename enable_if<__and_<
537 is_default_constructible<_U1>,
538 is_default_constructible<_U2>,
539 __not_<
540 __and_<__is_implicitly_default_constructible<_U1>,
541 __is_implicitly_default_constructible<_U2>>>>
542 ::value, bool>::type = false>
543 explicit constexpr pair()
544 : first(), second() { }
545
546 // Shortcut for constraining the templates that don't take pairs.
547 /// @cond undocumented
548 using _PCCP = _PCC<true, _T1, _T2>;
549 /// @endcond
550
551 /// Construct from two const lvalues, allowing implicit conversions.
552 template<typename _U1 = _T1, typename _U2=_T2, typename
553 enable_if<_PCCP::template
554 _ConstructiblePair<_U1, _U2>()
555 && _PCCP::template
556 _ImplicitlyConvertiblePair<_U1, _U2>(),
557 bool>::type=true>
558 constexpr pair(const _T1& __a, const _T2& __b)
559 : first(__a), second(__b) { }
560
561 /// Construct from two const lvalues, disallowing implicit conversions.
562 template<typename _U1 = _T1, typename _U2=_T2, typename
563 enable_if<_PCCP::template
564 _ConstructiblePair<_U1, _U2>()
565 && !_PCCP::template
566 _ImplicitlyConvertiblePair<_U1, _U2>(),
567 bool>::type=false>
568 explicit constexpr pair(const _T1& __a, const _T2& __b)
569 : first(__a), second(__b) { }
570
571 // Shortcut for constraining the templates that take pairs.
572 /// @cond undocumented
573 template <typename _U1, typename _U2>
574 using _PCCFP = _PCC<!is_same<_T1, _U1>::value
575 || !is_same<_T2, _U2>::value,
576 _T1, _T2>;
577 /// @endcond
578
579 template<typename _U1, typename _U2, typename
580 enable_if<_PCCFP<_U1, _U2>::template
581 _ConstructiblePair<_U1, _U2>()
582 && _PCCFP<_U1, _U2>::template
583 _ImplicitlyConvertiblePair<_U1, _U2>(),
584 bool>::type=true>
585 constexpr pair(const pair<_U1, _U2>& __p)
586 : first(__p.first), second(__p.second)
587 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
588
589 template<typename _U1, typename _U2, typename
590 enable_if<_PCCFP<_U1, _U2>::template
591 _ConstructiblePair<_U1, _U2>()
592 && !_PCCFP<_U1, _U2>::template
593 _ImplicitlyConvertiblePair<_U1, _U2>(),
594 bool>::type=false>
595 explicit constexpr pair(const pair<_U1, _U2>& __p)
596 : first(__p.first), second(__p.second)
597 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
598
599#if _GLIBCXX_USE_DEPRECATED
600#if defined(__DEPRECATED)
601# define _GLIBCXX_DEPRECATED_PAIR_CTOR \
602 __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
603 "initialize std::pair of move-only " \
604 "type and pointer")))
605#else
606# define _GLIBCXX_DEPRECATED_PAIR_CTOR
607#endif
608
609 private:
610 /// @cond undocumented
611
612 // A type which can be constructed from literal zero, but not nullptr
613 struct __zero_as_null_pointer_constant
614 {
615 __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
616 { }
617 template<typename _Tp,
618 typename = __enable_if_t<is_null_pointer<_Tp>::value>>
619 __zero_as_null_pointer_constant(_Tp) = delete;
620 };
621 /// @endcond
622 public:
623
624 // Deprecated extensions to DR 811.
625 // These allow construction from an rvalue and a literal zero,
626 // in cases where the standard says the zero should be deduced as int
627 template<typename _U1,
628 __enable_if_t<__and_<__not_<is_reference<_U1>>,
629 is_pointer<_T2>,
630 is_constructible<_T1, _U1>,
631 __not_<is_constructible<_T1, const _U1&>>,
632 is_convertible<_U1, _T1>>::value,
633 bool> = true>
634 _GLIBCXX_DEPRECATED_PAIR_CTOR
635 constexpr
636 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
637 : first(std::forward<_U1>(__x)), second(nullptr)
638 { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
639
640 template<typename _U1,
641 __enable_if_t<__and_<__not_<is_reference<_U1>>,
642 is_pointer<_T2>,
643 is_constructible<_T1, _U1>,
644 __not_<is_constructible<_T1, const _U1&>>,
645 __not_<is_convertible<_U1, _T1>>>::value,
646 bool> = false>
647 _GLIBCXX_DEPRECATED_PAIR_CTOR
648 explicit constexpr
649 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
650 : first(std::forward<_U1>(__x)), second(nullptr)
651 { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
652
653 template<typename _U2,
654 __enable_if_t<__and_<is_pointer<_T1>,
655 __not_<is_reference<_U2>>,
656 is_constructible<_T2, _U2>,
657 __not_<is_constructible<_T2, const _U2&>>,
658 is_convertible<_U2, _T2>>::value,
659 bool> = true>
660 _GLIBCXX_DEPRECATED_PAIR_CTOR
661 constexpr
662 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
663 : first(nullptr), second(std::forward<_U2>(__y))
664 { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
665
666 template<typename _U2,
667 __enable_if_t<__and_<is_pointer<_T1>,
668 __not_<is_reference<_U2>>,
669 is_constructible<_T2, _U2>,
670 __not_<is_constructible<_T2, const _U2&>>,
671 __not_<is_convertible<_U2, _T2>>>::value,
672 bool> = false>
673 _GLIBCXX_DEPRECATED_PAIR_CTOR
674 explicit constexpr
675 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
676 : first(nullptr), second(std::forward<_U2>(__y))
677 { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
678#undef _GLIBCXX_DEPRECATED_PAIR_CTOR
679#endif
680
681 template<typename _U1, typename _U2, typename
682 enable_if<_PCCP::template
683 _MoveConstructiblePair<_U1, _U2>()
684 && _PCCP::template
685 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
686 bool>::type=true>
687 constexpr pair(_U1&& __x, _U2&& __y)
688 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
689 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
690
691 template<typename _U1, typename _U2, typename
692 enable_if<_PCCP::template
693 _MoveConstructiblePair<_U1, _U2>()
694 && !_PCCP::template
695 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
696 bool>::type=false>
697 explicit constexpr pair(_U1&& __x, _U2&& __y)
698 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
699 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
700
701
702 template<typename _U1, typename _U2, typename
703 enable_if<_PCCFP<_U1, _U2>::template
704 _MoveConstructiblePair<_U1, _U2>()
705 && _PCCFP<_U1, _U2>::template
706 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
707 bool>::type=true>
708 constexpr pair(pair<_U1, _U2>&& __p)
709 : first(std::forward<_U1>(__p.first)),
710 second(std::forward<_U2>(__p.second))
711 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
712
713 template<typename _U1, typename _U2, typename
714 enable_if<_PCCFP<_U1, _U2>::template
715 _MoveConstructiblePair<_U1, _U2>()
716 && !_PCCFP<_U1, _U2>::template
717 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
718 bool>::type=false>
719 explicit constexpr pair(pair<_U1, _U2>&& __p)
720 : first(std::forward<_U1>(__p.first)),
721 second(std::forward<_U2>(__p.second))
722 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
723
724#undef __glibcxx_no_dangling_refs
725
726 pair&
727 operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
728 is_copy_assignable<_T2>>::value,
729 const pair&, const __nonesuch&> __p)
730 {
731 first = __p.first;
732 second = __p.second;
733 return *this;
734 }
735
736 pair&
737 operator=(__conditional_t<__and_<is_move_assignable<_T1>,
738 is_move_assignable<_T2>>::value,
739 pair&&, __nonesuch&&> __p)
740 noexcept(__and_<is_nothrow_move_assignable<_T1>,
741 is_nothrow_move_assignable<_T2>>::value)
742 {
743 first = std::forward<first_type>(__p.first);
744 second = std::forward<second_type>(__p.second);
745 return *this;
746 }
747
748 template<typename _U1, typename _U2>
749 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
750 is_assignable<_T2&, const _U2&>>::value,
751 pair&>::type
752 operator=(const pair<_U1, _U2>& __p)
753 {
754 first = __p.first;
755 second = __p.second;
756 return *this;
757 }
758
759 template<typename _U1, typename _U2>
760 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
761 is_assignable<_T2&, _U2&&>>::value,
762 pair&>::type
763 operator=(pair<_U1, _U2>&& __p)
764 {
765 first = std::forward<_U1>(__p.first);
766 second = std::forward<_U2>(__p.second);
767 return *this;
768 }
769#endif // lib concepts
770#else
771 // C++03 implementation
772
773 // _GLIBCXX_RESOLVE_LIB_DEFECTS
774 // 265. std::pair::pair() effects overly restrictive
775 /** The default constructor creates @c first and @c second using their
776 * respective default constructors. */
777 pair() : first(), second() { }
778
779 /// Two objects may be passed to a `pair` constructor to be copied.
780 pair(const _T1& __a, const _T2& __b)
781 : first(__a), second(__b) { }
782
783 /// Templated constructor to convert from other pairs.
784 template<typename _U1, typename _U2>
785 pair(const pair<_U1, _U2>& __p)
786 : first(__p.first), second(__p.second)
787 {
788#if __has_builtin(__reference_constructs_from_temporary)
789#pragma GCC diagnostic push
790#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
791 typedef int _DanglingCheck1[
792 __reference_constructs_from_temporary(_T1, const _U1&) ? -1 : 1
793 ];
794 typedef int _DanglingCheck2[
795 __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
796 ];
797#pragma GCC diagnostic pop
798#endif
799 }
800#endif // C++11
801 };
802
803 /// @relates pair @{
804
805#if __cpp_deduction_guides >= 201606
806 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
807#endif
808
809 /// Two pairs of the same type are equal iff their members are equal.
810 template<typename _T1, typename _T2>
811 inline _GLIBCXX_CONSTEXPR bool
812 operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
813 { return __x.first == __y.first && __x.second == __y.second; }
814
815#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
816 template<typename _T1, typename _T2>
817 constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
818 __detail::__synth3way_t<_T2>>
819 operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
820 {
821 if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
822 return __c;
823 return __detail::__synth3way(__x.second, __y.second);
824 }
825#else
826 /** Defines a lexicographical order for pairs.
827 *
828 * For two pairs of the same type, `P` is ordered before `Q` if
829 * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
830 * are equivalent (neither is less than the other) and `P.second` is less
831 * than `Q.second`.
832 */
833 template<typename _T1, typename _T2>
834 inline _GLIBCXX_CONSTEXPR bool
835 operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
836 { return __x.first < __y.first
837 || (!(__y.first < __x.first) && __x.second < __y.second); }
838
839 /// Uses @c operator== to find the result.
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 == __y); }
844
845 /// Uses @c operator< to find the result.
846 template<typename _T1, typename _T2>
847 inline _GLIBCXX_CONSTEXPR bool
848 operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
849 { return __y < __x; }
850
851 /// Uses @c operator< to find the result.
852 template<typename _T1, typename _T2>
853 inline _GLIBCXX_CONSTEXPR bool
854 operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
855 { return !(__y < __x); }
856
857 /// Uses @c operator< to find the result.
858 template<typename _T1, typename _T2>
859 inline _GLIBCXX_CONSTEXPR bool
860 operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
861 { return !(__x < __y); }
862#endif // !(three_way_comparison && concepts)
863
864#if __cplusplus >= 201103L
865 /** Swap overload for pairs. Calls std::pair::swap().
866 *
867 * @note This std::swap overload is not declared in C++03 mode,
868 * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
869 */
870 template<typename _T1, typename _T2>
871 _GLIBCXX20_CONSTEXPR inline
872#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
873 // Constrained free swap overload, see p0185r1
874 typename enable_if<__and_<__is_swappable<_T1>,
875 __is_swappable<_T2>>::value>::type
876#else
877 void
878#endif
879 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
880 noexcept(noexcept(__x.swap(__y)))
881 { __x.swap(__y); }
882
883#if __cplusplus > 202002L
884 template<typename _T1, typename _T2>
885 requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
886 constexpr void
887 swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
888 noexcept(noexcept(__x.swap(__y)))
889 { __x.swap(__y); }
890#endif // C++23
891
892#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
893 template<typename _T1, typename _T2>
894 typename enable_if<!__and_<__is_swappable<_T1>,
895 __is_swappable<_T2>>::value>::type
896 swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
897#endif
898#endif // __cplusplus >= 201103L
899
900 /// @} relates pair
901
902 /**
903 * @brief A convenience wrapper for creating a pair from two objects.
904 * @param __x The first object.
905 * @param __y The second object.
906 * @return A newly-constructed pair<> object of the appropriate type.
907 *
908 * The C++98 standard says the objects are passed by reference-to-const,
909 * but C++03 says they are passed by value (this was LWG issue #181).
910 *
911 * Since C++11 they have been passed by forwarding reference and then
912 * forwarded to the new members of the pair. To create a pair with a
913 * member of reference type, pass a `reference_wrapper` to this function.
914 */
915 // _GLIBCXX_RESOLVE_LIB_DEFECTS
916 // 181. make_pair() unintended behavior
917#if __cplusplus >= 201103L
918 // NB: DR 706.
919 template<typename _T1, typename _T2>
920 constexpr pair<typename __decay_and_strip<_T1>::__type,
921 typename __decay_and_strip<_T2>::__type>
922 make_pair(_T1&& __x, _T2&& __y)
923 {
924 typedef typename __decay_and_strip<_T1>::__type __ds_type1;
925 typedef typename __decay_and_strip<_T2>::__type __ds_type2;
926 typedef pair<__ds_type1, __ds_type2> __pair_type;
927 return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
928 }
929#else
930 template<typename _T1, typename _T2>
931 inline pair<_T1, _T2>
932 make_pair(_T1 __x, _T2 __y)
933 { return pair<_T1, _T2>(__x, __y); }
934#endif
935
936 /// @}
937
938#if __cplusplus >= 201103L
939 // Various functions which give std::pair a tuple-like interface.
940
941 /// @cond undocumented
942 template<typename _T1, typename _T2>
943 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
944 { };
945 /// @endcond
946
947 /// Partial specialization for std::pair
948 template<class _Tp1, class _Tp2>
949 struct tuple_size<pair<_Tp1, _Tp2>>
950 : public integral_constant<size_t, 2> { };
951
952 /// Partial specialization for std::pair
953 template<class _Tp1, class _Tp2>
954 struct tuple_element<0, pair<_Tp1, _Tp2>>
955 { typedef _Tp1 type; };
956
957 /// Partial specialization for std::pair
958 template<class _Tp1, class _Tp2>
959 struct tuple_element<1, pair<_Tp1, _Tp2>>
960 { typedef _Tp2 type; };
961
962#if __cplusplus >= 201703L
963 template<typename _Tp1, typename _Tp2>
964 inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
965
966 template<typename _Tp1, typename _Tp2>
967 inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
968
969 template<typename _Tp>
970 inline constexpr bool __is_pair = false;
971
972 template<typename _Tp, typename _Up>
973 inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
974#endif
975
976 /// @cond undocumented
977 template<size_t _Int>
978 struct __pair_get;
979
980 template<>
981 struct __pair_get<0>
982 {
983 template<typename _Tp1, typename _Tp2>
984 static constexpr _Tp1&
985 __get(pair<_Tp1, _Tp2>& __pair) noexcept
986 { return __pair.first; }
987
988 template<typename _Tp1, typename _Tp2>
989 static constexpr _Tp1&&
990 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
991 { return std::forward<_Tp1>(__pair.first); }
992
993 template<typename _Tp1, typename _Tp2>
994 static constexpr const _Tp1&
995 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
996 { return __pair.first; }
997
998 template<typename _Tp1, typename _Tp2>
999 static constexpr const _Tp1&&
1000 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1001 { return std::forward<const _Tp1>(__pair.first); }
1002 };
1003
1004 template<>
1005 struct __pair_get<1>
1006 {
1007 template<typename _Tp1, typename _Tp2>
1008 static constexpr _Tp2&
1009 __get(pair<_Tp1, _Tp2>& __pair) noexcept
1010 { return __pair.second; }
1011
1012 template<typename _Tp1, typename _Tp2>
1013 static constexpr _Tp2&&
1014 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
1015 { return std::forward<_Tp2>(__pair.second); }
1016
1017 template<typename _Tp1, typename _Tp2>
1018 static constexpr const _Tp2&
1019 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1020 { return __pair.second; }
1021
1022 template<typename _Tp1, typename _Tp2>
1023 static constexpr const _Tp2&&
1024 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1025 { return std::forward<const _Tp2>(__pair.second); }
1026 };
1027 /// @endcond
1028
1029 /** @{
1030 * std::get overloads for accessing members of std::pair
1031 */
1032
1033 template<size_t _Int, class _Tp1, class _Tp2>
1034 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1035 get(pair<_Tp1, _Tp2>& __in) noexcept
1036 { return __pair_get<_Int>::__get(__in); }
1037
1038 template<size_t _Int, class _Tp1, class _Tp2>
1039 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1040 get(pair<_Tp1, _Tp2>&& __in) noexcept
1041 { return __pair_get<_Int>::__move_get(std::move(__in)); }
1042
1043 template<size_t _Int, class _Tp1, class _Tp2>
1044 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1045 get(const pair<_Tp1, _Tp2>& __in) noexcept
1046 { return __pair_get<_Int>::__const_get(__in); }
1047
1048 template<size_t _Int, class _Tp1, class _Tp2>
1049 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1050 get(const pair<_Tp1, _Tp2>&& __in) noexcept
1051 { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
1052
1053#if __cplusplus >= 201402L
1054
1055#define __cpp_lib_tuples_by_type 201304L
1056
1057 template <typename _Tp, typename _Up>
1058 constexpr _Tp&
1059 get(pair<_Tp, _Up>& __p) noexcept
1060 { return __p.first; }
1061
1062 template <typename _Tp, typename _Up>
1063 constexpr const _Tp&
1064 get(const pair<_Tp, _Up>& __p) noexcept
1065 { return __p.first; }
1066
1067 template <typename _Tp, typename _Up>
1068 constexpr _Tp&&
1069 get(pair<_Tp, _Up>&& __p) noexcept
1070 { return std::move(__p.first); }
1071
1072 template <typename _Tp, typename _Up>
1073 constexpr const _Tp&&
1074 get(const pair<_Tp, _Up>&& __p) noexcept
1075 { return std::move(__p.first); }
1076
1077 template <typename _Tp, typename _Up>
1078 constexpr _Tp&
1079 get(pair<_Up, _Tp>& __p) noexcept
1080 { return __p.second; }
1081
1082 template <typename _Tp, typename _Up>
1083 constexpr const _Tp&
1084 get(const pair<_Up, _Tp>& __p) noexcept
1085 { return __p.second; }
1086
1087 template <typename _Tp, typename _Up>
1088 constexpr _Tp&&
1089 get(pair<_Up, _Tp>&& __p) noexcept
1090 { return std::move(__p.second); }
1091
1092 template <typename _Tp, typename _Up>
1093 constexpr const _Tp&&
1094 get(const pair<_Up, _Tp>&& __p) noexcept
1095 { return std::move(__p.second); }
1096
1097#if __cplusplus > 202002L
1098 template<typename _T1, typename _T2, typename _U1, typename _U2,
1099 template<typename> class _TQual, template<typename> class _UQual>
1100 requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1101 common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
1102 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
1103 {
1104 using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1105 common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
1106 };
1107
1108 template<typename _T1, typename _T2, typename _U1, typename _U2>
1109 requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
1110 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
1111 { using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; };
1112#endif // C++23
1113
1114#endif // C++14
1115 /// @}
1116#endif // C++11
1117
1118_GLIBCXX_END_NAMESPACE_VERSION
1119} // namespace std
1120
1121#endif /* _STL_PAIR_H */
1122