libstdc++
stl_pair.h
Go to the documentation of this file.
1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001-2024 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#endif
67
68namespace std _GLIBCXX_VISIBILITY(default)
69{
70_GLIBCXX_BEGIN_NAMESPACE_VERSION
71
72 /**
73 * @addtogroup utilities
74 * @{
75 */
76
77#if __cplusplus >= 201103L
78 /// Tag type for piecewise construction of std::pair objects.
79 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
80
81 /// Tag for piecewise construction of std::pair objects.
82 _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
84
85 /// @cond undocumented
86
87 // Forward declarations.
88 template<typename...>
89 class tuple;
90
91 template<size_t...>
92 struct _Index_tuple;
93
94#if ! __cpp_lib_concepts
95 // Concept utility functions, reused in conditionally-explicit
96 // constructors.
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>
101 struct _PCC
102 {
103 template <typename _U1, typename _U2>
104 static constexpr bool _ConstructiblePair()
105 {
106 return __and_<is_constructible<_T1, const _U1&>,
108 }
109
110 template <typename _U1, typename _U2>
111 static constexpr bool _ImplicitlyConvertiblePair()
112 {
113 return __and_<is_convertible<const _U1&, _T1>,
114 is_convertible<const _U2&, _T2>>::value;
115 }
116
117 template <typename _U1, typename _U2>
118 static constexpr bool _MoveConstructiblePair()
119 {
120 return __and_<is_constructible<_T1, _U1&&>,
121 is_constructible<_T2, _U2&&>>::value;
122 }
123
124 template <typename _U1, typename _U2>
125 static constexpr bool _ImplicitlyMoveConvertiblePair()
126 {
127 return __and_<is_convertible<_U1&&, _T1>,
128 is_convertible<_U2&&, _T2>>::value;
129 }
130 };
131
132 template <typename _T1, typename _T2>
133 struct _PCC<false, _T1, _T2>
134 {
135 template <typename _U1, typename _U2>
136 static constexpr bool _ConstructiblePair()
137 {
138 return false;
139 }
140
141 template <typename _U1, typename _U2>
142 static constexpr bool _ImplicitlyConvertiblePair()
143 {
144 return false;
145 }
146
147 template <typename _U1, typename _U2>
148 static constexpr bool _MoveConstructiblePair()
149 {
150 return false;
151 }
152
153 template <typename _U1, typename _U2>
154 static constexpr bool _ImplicitlyMoveConvertiblePair()
155 {
156 return false;
157 }
158 };
159#endif // lib concepts
160#endif // C++11
161
162 template<typename _U1, typename _U2> class __pair_base
163 {
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;
170#endif // C++11
171 };
172
173 /// @endcond
174
175 /**
176 * @brief Struct holding two objects of arbitrary type.
177 *
178 * @tparam _T1 Type of first object.
179 * @tparam _T2 Type of second object.
180 *
181 * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
182 *
183 * @headerfile utility
184 */
185 template<typename _T1, typename _T2>
186 struct pair
187 : public __pair_base<_T1, _T2>
188 {
189 typedef _T1 first_type; ///< The type of the `first` member
190 typedef _T2 second_type; ///< The type of the `second` member
191
192 _T1 first; ///< The first member
193 _T2 second; ///< The second member
194
195#if __cplusplus >= 201103L
196 constexpr pair(const pair&) = default; ///< Copy constructor
197 constexpr pair(pair&&) = default; ///< Move constructor
198
199 template<typename... _Args1, typename... _Args2>
200 _GLIBCXX20_CONSTEXPR
202
203 /// Swap the first members and then the second members.
204 _GLIBCXX20_CONSTEXPR void
205 swap(pair& __p)
206 noexcept(__and_<__is_nothrow_swappable<_T1>,
207 __is_nothrow_swappable<_T2>>::value)
208 {
209 using std::swap;
210 swap(first, __p.first);
211 swap(second, __p.second);
212 }
213
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.
221 constexpr void
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>
226 {
227 using std::swap;
228 swap(first, __p.first);
229 swap(second, __p.second);
230 }
231#endif // C++23
232
233 private:
234 template<typename... _Args1, size_t... _Indexes1,
235 typename... _Args2, size_t... _Indexes2>
236 _GLIBCXX20_CONSTEXPR
237 pair(tuple<_Args1...>&, tuple<_Args2...>&,
238 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
239 public:
240
241#if __cpp_lib_concepts
242 // C++20 implementation using concepts, explicit(bool), fully constexpr.
243
244 /// Default constructor
245 constexpr
246 explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
247 __is_implicitly_default_constructible<_T2>>>())
248 pair()
249 requires is_default_constructible_v<_T1>
250 && is_default_constructible_v<_T2>
251 : first(), second()
252 { }
253
254 private:
255
256 /// @cond undocumented
257 template<typename _U1, typename _U2>
258 static constexpr bool
259 _S_constructible()
260 {
261 if constexpr (is_constructible_v<_T1, _U1>)
262 return is_constructible_v<_T2, _U2>;
263 return false;
264 }
265
266 template<typename _U1, typename _U2>
267 static constexpr bool
268 _S_nothrow_constructible()
269 {
270 if constexpr (is_nothrow_constructible_v<_T1, _U1>)
271 return is_nothrow_constructible_v<_T2, _U2>;
272 return false;
273 }
274
275 template<typename _U1, typename _U2>
276 static constexpr bool
277 _S_convertible()
278 {
279 if constexpr (is_convertible_v<_U1, _T1>)
280 return is_convertible_v<_U2, _T2>;
281 return false;
282 }
283
284 // True if construction from _U1 and _U2 would create a dangling ref.
285 template<typename _U1, typename _U2>
286 static constexpr bool
287 _S_dangles()
288 {
289#if __has_builtin(__reference_constructs_from_temporary)
290 if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
291 return true;
292 else
293 return __reference_constructs_from_temporary(_T2, _U2&&);
294#else
295 return false;
296#endif
297 }
298 /// @endcond
299
300 public:
301
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)
308 { }
309
310 /// Constructor accepting two values of arbitrary types
311#if __cplusplus > 202002L
312 template<typename _U1 = _T1, typename _U2 = _T2>
313#else
314 template<typename _U1, typename _U2>
315#endif
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))
321 { }
322
323#if __cplusplus > 202002L
324 template<typename _U1 = _T1, typename _U2 = _T2>
325#else
326 template<typename _U1, typename _U2>
327#endif
328 requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
329 constexpr explicit(!_S_convertible<_U1, _U2>())
330 pair(_U1&&, _U2&&) = delete;
331
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)
340 { }
341
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;
347
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))
356 { }
357
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;
362
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)
371 { }
372
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;
377
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))
387 { }
388
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;
394#endif // C++23
395
396 private:
397 /// @cond undocumented
398 template<typename _U1, typename _U2>
399 static constexpr bool
400 _S_assignable()
401 {
402 if constexpr (is_assignable_v<_T1&, _U1>)
403 return is_assignable_v<_T2&, _U2>;
404 return false;
405 }
406
407 template<typename _U1, typename _U2>
408 static constexpr bool
409 _S_nothrow_assignable()
410 {
411 if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
412 return is_nothrow_assignable_v<_T2&, _U2>;
413 return false;
414 }
415 /// @endcond
416
417 public:
418
419 pair& operator=(const pair&) = delete;
420
421 /// Copy assignment operator
422 constexpr pair&
423 operator=(const pair& __p)
424 noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
425 requires (_S_assignable<const _T1&, const _T2&>())
426 {
427 first = __p.first;
428 second = __p.second;
429 return *this;
430 }
431
432 /// Move assignment operator
433 constexpr pair&
434 operator=(pair&& __p)
435 noexcept(_S_nothrow_assignable<_T1, _T2>())
436 requires (_S_assignable<_T1, _T2>())
437 {
438 first = std::forward<first_type>(__p.first);
439 second = std::forward<second_type>(__p.second);
440 return *this;
441 }
442
443 /// Converting assignment from a const `pair<U1, U2>` lvalue
444 template<typename _U1, typename _U2>
445 constexpr pair&
446 operator=(const pair<_U1, _U2>& __p)
447 noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
448 requires (_S_assignable<const _U1&, const _U2&>())
449 {
450 first = __p.first;
451 second = __p.second;
452 return *this;
453 }
454
455 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
456 template<typename _U1, typename _U2>
457 constexpr pair&
458 operator=(pair<_U1, _U2>&& __p)
459 noexcept(_S_nothrow_assignable<_U1, _U2>())
460 requires (_S_assignable<_U1, _U2>())
461 {
462 first = std::forward<_U1>(__p.first);
463 second = std::forward<_U2>(__p.second);
464 return *this;
465 }
466
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>
473 {
474 first = __p.first;
475 second = __p.second;
476 return *this;
477 }
478
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>
484 {
485 first = std::forward<first_type>(__p.first);
486 second = std::forward<second_type>(__p.second);
487 return *this;
488 }
489
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&>
496 {
497 first = __p.first;
498 second = __p.second;
499 return *this;
500 }
501
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>
508 {
509 first = std::forward<_U1>(__p.first);
510 second = std::forward<_U2>(__p.second);
511 return *this;
512 }
513#endif // C++23
514#else // !__cpp_lib_concepts
515 // C++11/14/17 implementation using enable_if, partially constexpr.
516
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")
525#else
526# define __glibcxx_no_dangling_refs(_U1, _U2)
527#endif
528 /// @endcond
529
530 /** The default constructor creates @c first and @c second using their
531 * respective default constructors. */
532 template <typename _U1 = _T1,
533 typename _U2 = _T2,
534 typename enable_if<__and_<
535 __is_implicitly_default_constructible<_U1>,
536 __is_implicitly_default_constructible<_U2>>
537 ::value, bool>::type = true>
538 constexpr pair()
539 : first(), second() { }
540
541 template <typename _U1 = _T1,
542 typename _U2 = _T2,
543 typename enable_if<__and_<
546 __not_<
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() { }
552
553 // Shortcut for constraining the templates that don't take pairs.
554 /// @cond undocumented
555 using _PCCP = _PCC<true, _T1, _T2>;
556 /// @endcond
557
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>()
562 && _PCCP::template
563 _ImplicitlyConvertiblePair<_U1, _U2>(),
564 bool>::type=true>
565 constexpr pair(const _T1& __a, const _T2& __b)
566 : first(__a), second(__b) { }
567
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>()
572 && !_PCCP::template
573 _ImplicitlyConvertiblePair<_U1, _U2>(),
574 bool>::type=false>
575 explicit constexpr pair(const _T1& __a, const _T2& __b)
576 : first(__a), second(__b) { }
577
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
583 _T1, _T2>;
584 /// @endcond
585
586 template<typename _U1, typename _U2, typename
588 _ConstructiblePair<_U1, _U2>()
589 && _PCCFP<_U1, _U2>::template
590 _ImplicitlyConvertiblePair<_U1, _U2>(),
591 bool>::type=true>
592 constexpr pair(const pair<_U1, _U2>& __p)
593 : first(__p.first), second(__p.second)
594 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
595
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>(),
601 bool>::type=false>
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&); }
605
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")))
612#else
613# define _GLIBCXX_DEPRECATED_PAIR_CTOR
614#endif
615
616 private:
617 /// @cond undocumented
618
619 // A type which can be constructed from literal zero, but not nullptr
620 struct __zero_as_null_pointer_constant
621 {
622 __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
623 { }
624 template<typename _Tp,
625 typename = __enable_if_t<is_null_pointer<_Tp>::value>>
626 __zero_as_null_pointer_constant(_Tp) = delete;
627 };
628 /// @endcond
629 public:
630
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>>,
636 is_pointer<_T2>,
637 is_constructible<_T1, _U1>,
638 __not_<is_constructible<_T1, const _U1&>>,
639 is_convertible<_U1, _T1>>::value,
640 bool> = true>
641 _GLIBCXX_DEPRECATED_PAIR_CTOR
642 constexpr
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); }
646
647 template<typename _U1,
648 __enable_if_t<__and_<__not_<is_reference<_U1>>,
649 is_pointer<_T2>,
650 is_constructible<_T1, _U1>,
651 __not_<is_constructible<_T1, const _U1&>>,
652 __not_<is_convertible<_U1, _T1>>>::value,
653 bool> = false>
654 _GLIBCXX_DEPRECATED_PAIR_CTOR
655 explicit constexpr
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); }
659
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,
666 bool> = true>
667 _GLIBCXX_DEPRECATED_PAIR_CTOR
668 constexpr
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&&); }
672
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,
679 bool> = false>
680 _GLIBCXX_DEPRECATED_PAIR_CTOR
681 explicit constexpr
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
686#endif
687
688 template<typename _U1, typename _U2, typename
689 enable_if<_PCCP::template
690 _MoveConstructiblePair<_U1, _U2>()
691 && _PCCP::template
692 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
693 bool>::type=true>
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&&); }
697
698 template<typename _U1, typename _U2, typename
699 enable_if<_PCCP::template
700 _MoveConstructiblePair<_U1, _U2>()
701 && !_PCCP::template
702 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
703 bool>::type=false>
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&&); }
707
708
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>(),
714 bool>::type=true>
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&&); }
719
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>(),
725 bool>::type=false>
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&&); }
730
731#undef __glibcxx_no_dangling_refs
732
733 pair&
734 operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
735 is_copy_assignable<_T2>>::value,
736 const pair&, const __nonesuch&> __p)
737 {
738 first = __p.first;
739 second = __p.second;
740 return *this;
741 }
742
743 pair&
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)
749 {
750 first = std::forward<first_type>(__p.first);
751 second = std::forward<second_type>(__p.second);
752 return *this;
753 }
754
755 template<typename _U1, typename _U2>
756 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
757 is_assignable<_T2&, const _U2&>>::value,
758 pair&>::type
759 operator=(const pair<_U1, _U2>& __p)
760 {
761 first = __p.first;
762 second = __p.second;
763 return *this;
764 }
765
766 template<typename _U1, typename _U2>
767 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
768 is_assignable<_T2&, _U2&&>>::value,
769 pair&>::type
770 operator=(pair<_U1, _U2>&& __p)
771 {
772 first = std::forward<_U1>(__p.first);
773 second = std::forward<_U2>(__p.second);
774 return *this;
775 }
776#endif // lib concepts
777#else
778 // C++03 implementation
779
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() { }
785
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) { }
789
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)
794 {
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
800 ];
801 typedef int _DanglingCheck2[
802 __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
803 ];
804#pragma GCC diagnostic pop
805#endif
806 }
807#endif // C++11
808 };
809
810 /// @relates pair @{
811
812#if __cpp_deduction_guides >= 201606
813 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
814#endif
815
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
820 { return __x.first == __y.first && __x.second == __y.second; }
821
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)
827 {
828 if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
829 return __c;
830 return __detail::__synth3way(__x.second, __y.second);
831 }
832#else
833 /** Defines a lexicographical order for pairs.
834 *
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
838 * than `Q.second`.
839 */
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); }
845
846 /// Uses @c operator== to find the result.
847 template<typename _T1, typename _T2>
848 inline _GLIBCXX_CONSTEXPR bool
850 { return !(__x == __y); }
851
852 /// Uses @c operator< to find the result.
853 template<typename _T1, typename _T2>
854 inline _GLIBCXX_CONSTEXPR bool
856 { return __y < __x; }
857
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); }
863
864 /// Uses @c operator< to find the result.
865 template<typename _T1, typename _T2>
866 inline _GLIBCXX_CONSTEXPR bool
868 { return !(__x < __y); }
869#endif // !(three_way_comparison && concepts)
870
871#if __cplusplus >= 201103L
872 /** Swap overload for pairs. Calls std::pair::swap().
873 *
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
876 */
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
882 __is_swappable<_T2>>::value>::type
883#else
884 void
885#endif
887 noexcept(noexcept(__x.swap(__y)))
888 { __x.swap(__y); }
889
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>
893 constexpr void
894 swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
895 noexcept(noexcept(__x.swap(__y)))
896 { __x.swap(__y); }
897#endif // C++23
898
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;
904#endif
905#endif // __cplusplus >= 201103L
906
907 /// @} relates pair
908
909 /**
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.
914 *
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).
917 *
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.
921 */
922 // _GLIBCXX_RESOLVE_LIB_DEFECTS
923 // 181. make_pair() unintended behavior
924#if __cplusplus >= 201103L
925 // NB: DR 706.
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)
930 {
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));
935 }
936#else
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); }
941#endif
942
943 /// @}
944
945#if __cplusplus >= 201103L
946 // Various functions which give std::pair a tuple-like interface.
947
948 /// @cond undocumented
949 template<typename _T1, typename _T2>
950 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
951 { };
952 /// @endcond
953
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> { };
958
959 /// Partial specialization for std::pair
960 template<class _Tp1, class _Tp2>
961 struct tuple_element<0, pair<_Tp1, _Tp2>>
962 { typedef _Tp1 type; };
963
964 /// Partial specialization for std::pair
965 template<class _Tp1, class _Tp2>
966 struct tuple_element<1, pair<_Tp1, _Tp2>>
967 { typedef _Tp2 type; };
968
969#if __cplusplus >= 201703L
970 template<typename _Tp1, typename _Tp2>
971 inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
972
973 template<typename _Tp1, typename _Tp2>
974 inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
975
976 template<typename _Tp>
977 inline constexpr bool __is_pair = false;
978
979 template<typename _Tp, typename _Up>
980 inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
981#endif
982
983 /// @cond undocumented
984 template<size_t _Int>
985 struct __pair_get;
986
987 template<>
988 struct __pair_get<0>
989 {
990 template<typename _Tp1, typename _Tp2>
991 static constexpr _Tp1&
992 __get(pair<_Tp1, _Tp2>& __pair) noexcept
993 { return __pair.first; }
994
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); }
999
1000 template<typename _Tp1, typename _Tp2>
1001 static constexpr const _Tp1&
1002 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1003 { return __pair.first; }
1004
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); }
1009 };
1010
1011 template<>
1012 struct __pair_get<1>
1013 {
1014 template<typename _Tp1, typename _Tp2>
1015 static constexpr _Tp2&
1016 __get(pair<_Tp1, _Tp2>& __pair) noexcept
1017 { return __pair.second; }
1018
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); }
1023
1024 template<typename _Tp1, typename _Tp2>
1025 static constexpr const _Tp2&
1026 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1027 { return __pair.second; }
1028
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); }
1033 };
1034 /// @endcond
1035
1036 /** @{
1037 * std::get overloads for accessing members of std::pair
1038 */
1039
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); }
1044
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)); }
1049
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); }
1054
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)); }
1059
1060
1061#ifdef __glibcxx_tuples_by_type // C++ >= 14
1062 template <typename _Tp, typename _Up>
1063 constexpr _Tp&
1064 get(pair<_Tp, _Up>& __p) noexcept
1065 { return __p.first; }
1066
1067 template <typename _Tp, typename _Up>
1068 constexpr const _Tp&
1069 get(const pair<_Tp, _Up>& __p) noexcept
1070 { return __p.first; }
1071
1072 template <typename _Tp, typename _Up>
1073 constexpr _Tp&&
1074 get(pair<_Tp, _Up>&& __p) noexcept
1075 { return std::move(__p.first); }
1076
1077 template <typename _Tp, typename _Up>
1078 constexpr const _Tp&&
1079 get(const pair<_Tp, _Up>&& __p) noexcept
1080 { return std::move(__p.first); }
1081
1082 template <typename _Tp, typename _Up>
1083 constexpr _Tp&
1084 get(pair<_Up, _Tp>& __p) noexcept
1085 { return __p.second; }
1086
1087 template <typename _Tp, typename _Up>
1088 constexpr const _Tp&
1089 get(const pair<_Up, _Tp>& __p) noexcept
1090 { return __p.second; }
1091
1092 template <typename _Tp, typename _Up>
1093 constexpr _Tp&&
1094 get(pair<_Up, _Tp>&& __p) noexcept
1095 { return std::move(__p.second); }
1096
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
1102
1103
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>
1110 {
1111 using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1112 common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
1113 };
1114
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>>; };
1119#endif // C++23
1120
1121 /// @}
1122#endif // C++11
1123
1124_GLIBCXX_END_NAMESPACE_VERSION
1125} // namespace std
1126
1127#endif /* _STL_PAIR_H */
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition type_traits:111
pair(_T1, _T2) -> pair< _T1, _T2 >
Two pairs of the same type are equal iff their members are equal.
constexpr bool operator>(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator< to find the result.
Definition stl_pair.h:855
constexpr bool operator!=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator== to find the result.
Definition stl_pair.h:849
constexpr bool operator==(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Two pairs of the same type are equal iff their members are equal.
Definition stl_pair.h:819
constexpr bool operator>=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator< to find the result.
Definition stl_pair.h:867
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:126
constexpr enable_if< __and_< __is_swappable< _T1 >, __is_swappable< _T2 > >::value >::type swap(pair< _T1, _T2 > &__x, pair< _T1, _T2 > &__y) noexcept(noexcept(__x.swap(__y)))
Definition stl_pair.h:886
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
Definition stl_pair.h:82
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Definition stl_pair.h:929
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:70
ISO C++ entities toplevel namespace is std.
Primary class template, tuple.
Definition tuple:754
integral_constant
Definition type_traits:88
Define a member typedef type only if a boolean constant is true.
Definition type_traits:129
is_constructible
Definition type_traits:1117
is_default_constructible
Definition type_traits:1126
Struct holding two objects of arbitrary type.
Definition stl_pair.h:188
constexpr pair(const _T1 &__a, const _T2 &__b)
Construct from two const lvalues, allowing implicit conversions.
Definition stl_pair.h:565
_T1 first
The first member.
Definition stl_pair.h:192
_T1 first_type
The type of the first member.
Definition stl_pair.h:189
constexpr void swap(pair &__p) noexcept(__and_< __is_nothrow_swappable< _T1 >, __is_nothrow_swappable< _T2 > >::value)
Swap the first members and then the second members.
Definition stl_pair.h:205
constexpr pair(const pair &)=default
Copy constructor.
constexpr pair()
Definition stl_pair.h:538
_T2 second_type
The type of the second member.
Definition stl_pair.h:190
constexpr pair(pair &&)=default
Move constructor.
_T2 second
The second member.
Definition stl_pair.h:193
Tag type for piecewise construction of std::pair objects.
Definition stl_pair.h:79
Finds the size of a given tuple type.
Definition utility.h:49
Gives the type of the ith element of a given tuple type.
Definition utility.h:80