libstdc++
stl_pair.h
Go to the documentation of this file.
1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001-2022 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 =
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&>,
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
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 /// @endcond
285
286 public:
287
288 /// Constructor accepting lvalues of `first_type` and `second_type`
289 constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
290 pair(const _T1& __x, const _T2& __y)
291 noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
292 requires (_S_constructible<const _T1&, const _T2&>())
293 : first(__x), second(__y)
294 { }
295
296 /// Constructor accepting two values of arbitrary types
297 template<typename _U1, typename _U2>
298 requires (_S_constructible<_U1, _U2>())
299 constexpr explicit(!_S_convertible<_U1, _U2>())
300 pair(_U1&& __x, _U2&& __y)
301 noexcept(_S_nothrow_constructible<_U1, _U2>())
302 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
303 { }
304
305 /// Converting constructor from a const `pair<U1, U2>` lvalue
306 template<typename _U1, typename _U2>
307 requires (_S_constructible<const _U1&, const _U2&>())
308 constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
309 pair(const pair<_U1, _U2>& __p)
310 noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
311 : first(__p.first), second(__p.second)
312 { }
313
314 /// Converting constructor from a non-const `pair<U1, U2>` rvalue
315 template<typename _U1, typename _U2>
316 requires (_S_constructible<_U1, _U2>())
317 constexpr explicit(!_S_convertible<_U1, _U2>())
318 pair(pair<_U1, _U2>&& __p)
319 noexcept(_S_nothrow_constructible<_U1, _U2>())
320 : first(std::forward<_U1>(__p.first)),
321 second(std::forward<_U2>(__p.second))
322 { }
323
324#if __cplusplus > 202002L
325 /// Converting constructor from a non-const `pair<U1, U2>` lvalue
326 template<typename _U1, typename _U2>
327 requires (_S_constructible<_U1&, _U2&>())
328 constexpr explicit(!_S_convertible<_U1&, _U2&>())
329 pair(pair<_U1, _U2>& __p)
330 noexcept(_S_nothrow_constructible<_U1&, _U2&>())
331 : first(__p.first), second(__p.second)
332 { }
333
334 /// Converting constructor from a const `pair<U1, U2>` rvalue
335 template<typename _U1, typename _U2>
336 requires (_S_constructible<const _U1, const _U2>())
337 constexpr explicit(!_S_convertible<const _U1, const _U2>())
338 pair(const pair<_U1, _U2>&& __p)
339 noexcept(_S_nothrow_constructible<const _U1, const _U2>())
340 : first(std::forward<const _U1>(__p.first)),
341 second(std::forward<const _U2>(__p.second))
342 { }
343#endif // C++23
344
345 private:
346 /// @cond undocumented
347 template<typename _U1, typename _U2>
348 static constexpr bool
349 _S_assignable()
350 {
351 if constexpr (is_assignable_v<_T1&, _U1>)
352 return is_assignable_v<_T2&, _U2>;
353 return false;
354 }
355
356 template<typename _U1, typename _U2>
357 static constexpr bool
358 _S_nothrow_assignable()
359 {
360 if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
361 return is_nothrow_assignable_v<_T2&, _U2>;
362 return false;
363 }
364 /// @endcond
365
366 public:
367
368 pair& operator=(const pair&) = delete;
369
370 /// Copy assignment operator
371 constexpr pair&
372 operator=(const pair& __p)
373 noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
374 requires (_S_assignable<const _T1&, const _T2&>())
375 {
376 first = __p.first;
377 second = __p.second;
378 return *this;
379 }
380
381 /// Move assignment operator
382 constexpr pair&
383 operator=(pair&& __p)
384 noexcept(_S_nothrow_assignable<_T1, _T2>())
385 requires (_S_assignable<_T1, _T2>())
386 {
387 first = std::forward<first_type>(__p.first);
388 second = std::forward<second_type>(__p.second);
389 return *this;
390 }
391
392 /// Converting assignment from a const `pair<U1, U2>` lvalue
393 template<typename _U1, typename _U2>
394 constexpr pair&
395 operator=(const pair<_U1, _U2>& __p)
396 noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
397 requires (_S_assignable<const _U1&, const _U2&>())
398 {
399 first = __p.first;
400 second = __p.second;
401 return *this;
402 }
403
404 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
405 template<typename _U1, typename _U2>
406 constexpr pair&
407 operator=(pair<_U1, _U2>&& __p)
408 noexcept(_S_nothrow_assignable<_U1, _U2>())
409 requires (_S_assignable<_U1, _U2>())
410 {
411 first = std::forward<_U1>(__p.first);
412 second = std::forward<_U2>(__p.second);
413 return *this;
414 }
415
416#if __cplusplus > 202002L
417 /// Copy assignment operator (const)
418 constexpr const pair&
419 operator=(const pair& __p) const
420 requires is_copy_assignable_v<const first_type>
421 && is_copy_assignable_v<const second_type>
422 {
423 first = __p.first;
424 second = __p.second;
425 return *this;
426 }
427
428 /// Move assignment operator (const)
429 constexpr const pair&
430 operator=(pair&& __p) const
431 requires is_assignable_v<const first_type&, first_type>
432 && is_assignable_v<const second_type&, second_type>
433 {
434 first = std::forward<first_type>(__p.first);
435 second = std::forward<second_type>(__p.second);
436 return *this;
437 }
438
439 /// Converting assignment from a const `pair<U1, U2>` lvalue
440 template<typename _U1, typename _U2>
441 constexpr const pair&
442 operator=(const pair<_U1, _U2>& __p) const
443 requires is_assignable_v<const first_type&, const _U1&>
444 && is_assignable_v<const second_type&, const _U2&>
445 {
446 first = __p.first;
447 second = __p.second;
448 return *this;
449 }
450
451 /// Converting assignment from a non-const `pair<U1, U2>` rvalue
452 template<typename _U1, typename _U2>
453 constexpr const pair&
454 operator=(pair<_U1, _U2>&& __p) const
455 requires is_assignable_v<const first_type&, _U1>
456 && is_assignable_v<const second_type&, _U2>
457 {
458 first = std::forward<_U1>(__p.first);
459 second = std::forward<_U2>(__p.second);
460 return *this;
461 }
462#endif // C++23
463#else // !__cpp_lib_concepts
464 // C++11/14/17 implementation using enable_if, partially constexpr.
465
466 /** The default constructor creates @c first and @c second using their
467 * respective default constructors. */
468 template <typename _U1 = _T1,
469 typename _U2 = _T2,
470 typename enable_if<__and_<
471 __is_implicitly_default_constructible<_U1>,
472 __is_implicitly_default_constructible<_U2>>
473 ::value, bool>::type = true>
474 constexpr pair()
475 : first(), second() { }
476
477 template <typename _U1 = _T1,
478 typename _U2 = _T2,
479 typename enable_if<__and_<
482 __not_<
483 __and_<__is_implicitly_default_constructible<_U1>,
484 __is_implicitly_default_constructible<_U2>>>>
485 ::value, bool>::type = false>
486 explicit constexpr pair()
487 : first(), second() { }
488
489 // Shortcut for constraining the templates that don't take pairs.
490 /// @cond undocumented
491 using _PCCP = _PCC<true, _T1, _T2>;
492 /// @endcond
493
494 /// Construct from two const lvalues, allowing implicit conversions.
495 template<typename _U1 = _T1, typename _U2=_T2, typename
496 enable_if<_PCCP::template
497 _ConstructiblePair<_U1, _U2>()
498 && _PCCP::template
499 _ImplicitlyConvertiblePair<_U1, _U2>(),
500 bool>::type=true>
501 constexpr pair(const _T1& __a, const _T2& __b)
502 : first(__a), second(__b) { }
503
504 /// Construct from two const lvalues, disallowing implicit conversions.
505 template<typename _U1 = _T1, typename _U2=_T2, typename
506 enable_if<_PCCP::template
507 _ConstructiblePair<_U1, _U2>()
508 && !_PCCP::template
509 _ImplicitlyConvertiblePair<_U1, _U2>(),
510 bool>::type=false>
511 explicit constexpr pair(const _T1& __a, const _T2& __b)
512 : first(__a), second(__b) { }
513
514 // Shortcut for constraining the templates that take pairs.
515 /// @cond undocumented
516 template <typename _U1, typename _U2>
517 using _PCCFP = _PCC<!is_same<_T1, _U1>::value
519 _T1, _T2>;
520 /// @endcond
521
522 template<typename _U1, typename _U2, typename
524 _ConstructiblePair<_U1, _U2>()
525 && _PCCFP<_U1, _U2>::template
526 _ImplicitlyConvertiblePair<_U1, _U2>(),
527 bool>::type=true>
528 constexpr pair(const pair<_U1, _U2>& __p)
529 : first(__p.first), second(__p.second) { }
530
531 template<typename _U1, typename _U2, typename
532 enable_if<_PCCFP<_U1, _U2>::template
533 _ConstructiblePair<_U1, _U2>()
534 && !_PCCFP<_U1, _U2>::template
535 _ImplicitlyConvertiblePair<_U1, _U2>(),
536 bool>::type=false>
537 explicit constexpr pair(const pair<_U1, _U2>& __p)
538 : first(__p.first), second(__p.second) { }
539
540#if _GLIBCXX_USE_DEPRECATED
541#if defined(__DEPRECATED)
542# define _GLIBCXX_DEPRECATED_PAIR_CTOR \
543 __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
544 "initialize std::pair of move-only " \
545 "type and pointer")))
546#else
547# define _GLIBCXX_DEPRECATED_PAIR_CTOR
548#endif
549
550 private:
551 /// @cond undocumented
552
553 // A type which can be constructed from literal zero, but not nullptr
554 struct __zero_as_null_pointer_constant
555 {
556 __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
557 { }
558 template<typename _Tp,
559 typename = __enable_if_t<is_null_pointer<_Tp>::value>>
560 __zero_as_null_pointer_constant(_Tp) = delete;
561 };
562 /// @endcond
563 public:
564
565 // Deprecated extensions to DR 811.
566 // These allow construction from an rvalue and a literal zero,
567 // in cases where the standard says the zero should be deduced as int
568 template<typename _U1,
569 __enable_if_t<__and_<__not_<is_reference<_U1>>,
570 is_pointer<_T2>,
571 is_constructible<_T1, _U1>,
572 __not_<is_constructible<_T1, const _U1&>>,
573 is_convertible<_U1, _T1>>::value,
574 bool> = true>
575 _GLIBCXX_DEPRECATED_PAIR_CTOR
576 constexpr
577 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
578 : first(std::forward<_U1>(__x)), second(nullptr) { }
579
580 template<typename _U1,
581 __enable_if_t<__and_<__not_<is_reference<_U1>>,
582 is_pointer<_T2>,
583 is_constructible<_T1, _U1>,
584 __not_<is_constructible<_T1, const _U1&>>,
585 __not_<is_convertible<_U1, _T1>>>::value,
586 bool> = false>
587 _GLIBCXX_DEPRECATED_PAIR_CTOR
588 explicit constexpr
589 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
590 : first(std::forward<_U1>(__x)), second(nullptr) { }
591
592 template<typename _U2,
593 __enable_if_t<__and_<is_pointer<_T1>,
594 __not_<is_reference<_U2>>,
595 is_constructible<_T2, _U2>,
596 __not_<is_constructible<_T2, const _U2&>>,
597 is_convertible<_U2, _T2>>::value,
598 bool> = true>
599 _GLIBCXX_DEPRECATED_PAIR_CTOR
600 constexpr
601 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
602 : first(nullptr), second(std::forward<_U2>(__y)) { }
603
604 template<typename _U2,
605 __enable_if_t<__and_<is_pointer<_T1>,
606 __not_<is_reference<_U2>>,
607 is_constructible<_T2, _U2>,
608 __not_<is_constructible<_T2, const _U2&>>,
609 __not_<is_convertible<_U2, _T2>>>::value,
610 bool> = false>
611 _GLIBCXX_DEPRECATED_PAIR_CTOR
612 explicit constexpr
613 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
614 : first(nullptr), second(std::forward<_U2>(__y)) { }
615#undef _GLIBCXX_DEPRECATED_PAIR_CTOR
616#endif
617
618 template<typename _U1, typename _U2, typename
619 enable_if<_PCCP::template
620 _MoveConstructiblePair<_U1, _U2>()
621 && _PCCP::template
622 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
623 bool>::type=true>
624 constexpr pair(_U1&& __x, _U2&& __y)
625 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
626
627 template<typename _U1, typename _U2, typename
628 enable_if<_PCCP::template
629 _MoveConstructiblePair<_U1, _U2>()
630 && !_PCCP::template
631 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
632 bool>::type=false>
633 explicit constexpr pair(_U1&& __x, _U2&& __y)
634 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
635
636
637 template<typename _U1, typename _U2, typename
638 enable_if<_PCCFP<_U1, _U2>::template
639 _MoveConstructiblePair<_U1, _U2>()
640 && _PCCFP<_U1, _U2>::template
641 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
642 bool>::type=true>
643 constexpr pair(pair<_U1, _U2>&& __p)
644 : first(std::forward<_U1>(__p.first)),
645 second(std::forward<_U2>(__p.second)) { }
646
647 template<typename _U1, typename _U2, typename
648 enable_if<_PCCFP<_U1, _U2>::template
649 _MoveConstructiblePair<_U1, _U2>()
650 && !_PCCFP<_U1, _U2>::template
651 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
652 bool>::type=false>
653 explicit constexpr pair(pair<_U1, _U2>&& __p)
654 : first(std::forward<_U1>(__p.first)),
655 second(std::forward<_U2>(__p.second)) { }
656
657 pair&
658 operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
659 is_copy_assignable<_T2>>::value,
660 const pair&, const __nonesuch&> __p)
661 {
662 first = __p.first;
663 second = __p.second;
664 return *this;
665 }
666
667 pair&
668 operator=(__conditional_t<__and_<is_move_assignable<_T1>,
669 is_move_assignable<_T2>>::value,
670 pair&&, __nonesuch&&> __p)
671 noexcept(__and_<is_nothrow_move_assignable<_T1>,
672 is_nothrow_move_assignable<_T2>>::value)
673 {
674 first = std::forward<first_type>(__p.first);
675 second = std::forward<second_type>(__p.second);
676 return *this;
677 }
678
679 template<typename _U1, typename _U2>
680 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
681 is_assignable<_T2&, const _U2&>>::value,
682 pair&>::type
683 operator=(const pair<_U1, _U2>& __p)
684 {
685 first = __p.first;
686 second = __p.second;
687 return *this;
688 }
689
690 template<typename _U1, typename _U2>
691 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
692 is_assignable<_T2&, _U2&&>>::value,
693 pair&>::type
694 operator=(pair<_U1, _U2>&& __p)
695 {
696 first = std::forward<_U1>(__p.first);
697 second = std::forward<_U2>(__p.second);
698 return *this;
699 }
700#endif // lib concepts
701#else
702 // C++03 implementation
703
704 // _GLIBCXX_RESOLVE_LIB_DEFECTS
705 // 265. std::pair::pair() effects overly restrictive
706 /** The default constructor creates @c first and @c second using their
707 * respective default constructors. */
708 pair() : first(), second() { }
709
710 /// Two objects may be passed to a `pair` constructor to be copied.
711 pair(const _T1& __a, const _T2& __b)
712 : first(__a), second(__b) { }
713
714 /// Templated constructor to convert from other pairs.
715 template<typename _U1, typename _U2>
716 pair(const pair<_U1, _U2>& __p)
717 : first(__p.first), second(__p.second) { }
718#endif // C++11
719 };
720
721 /// @relates pair @{
722
723#if __cpp_deduction_guides >= 201606
724 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
725#endif
726
727 /// Two pairs of the same type are equal iff their members are equal.
728 template<typename _T1, typename _T2>
729 inline _GLIBCXX_CONSTEXPR bool
731 { return __x.first == __y.first && __x.second == __y.second; }
732
733#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
734 template<typename _T1, typename _T2>
735 constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
736 __detail::__synth3way_t<_T2>>
737 operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
738 {
739 if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
740 return __c;
741 return __detail::__synth3way(__x.second, __y.second);
742 }
743#else
744 /** Defines a lexicographical order for pairs.
745 *
746 * For two pairs of the same type, `P` is ordered before `Q` if
747 * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
748 * are equivalent (neither is less than the other) and `P.second` is less
749 * than `Q.second`.
750 */
751 template<typename _T1, typename _T2>
752 inline _GLIBCXX_CONSTEXPR bool
753 operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
754 { return __x.first < __y.first
755 || (!(__y.first < __x.first) && __x.second < __y.second); }
756
757 /// Uses @c operator== to find the result.
758 template<typename _T1, typename _T2>
759 inline _GLIBCXX_CONSTEXPR bool
761 { return !(__x == __y); }
762
763 /// Uses @c operator< to find the result.
764 template<typename _T1, typename _T2>
765 inline _GLIBCXX_CONSTEXPR bool
767 { return __y < __x; }
768
769 /// Uses @c operator< to find the result.
770 template<typename _T1, typename _T2>
771 inline _GLIBCXX_CONSTEXPR bool
772 operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
773 { return !(__y < __x); }
774
775 /// Uses @c operator< to find the result.
776 template<typename _T1, typename _T2>
777 inline _GLIBCXX_CONSTEXPR bool
779 { return !(__x < __y); }
780#endif // !(three_way_comparison && concepts)
781
782#if __cplusplus >= 201103L
783 /** Swap overload for pairs. Calls std::pair::swap().
784 *
785 * @note This std::swap overload is not declared in C++03 mode,
786 * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
787 */
788 template<typename _T1, typename _T2>
789 _GLIBCXX20_CONSTEXPR inline
790#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
791 // Constrained free swap overload, see p0185r1
793 __is_swappable<_T2>>::value>::type
794#else
795 void
796#endif
798 noexcept(noexcept(__x.swap(__y)))
799 { __x.swap(__y); }
800
801#if __cplusplus > 202002L
802 template<typename _T1, typename _T2>
803 requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
804 constexpr void
805 swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
806 noexcept(noexcept(__x.swap(__y)))
807 { __x.swap(__y); }
808#endif // C++23
809
810#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
811 template<typename _T1, typename _T2>
812 typename enable_if<!__and_<__is_swappable<_T1>,
813 __is_swappable<_T2>>::value>::type
814 swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
815#endif
816#endif // __cplusplus >= 201103L
817
818 /// @} relates pair
819
820 /**
821 * @brief A convenience wrapper for creating a pair from two objects.
822 * @param __x The first object.
823 * @param __y The second object.
824 * @return A newly-constructed pair<> object of the appropriate type.
825 *
826 * The C++98 standard says the objects are passed by reference-to-const,
827 * but C++03 says they are passed by value (this was LWG issue #181).
828 *
829 * Since C++11 they have been passed by forwarding reference and then
830 * forwarded to the new members of the pair. To create a pair with a
831 * member of reference type, pass a `reference_wrapper` to this function.
832 */
833 // _GLIBCXX_RESOLVE_LIB_DEFECTS
834 // 181. make_pair() unintended behavior
835#if __cplusplus >= 201103L
836 // NB: DR 706.
837 template<typename _T1, typename _T2>
838 constexpr pair<typename __decay_and_strip<_T1>::__type,
839 typename __decay_and_strip<_T2>::__type>
840 make_pair(_T1&& __x, _T2&& __y)
841 {
842 typedef typename __decay_and_strip<_T1>::__type __ds_type1;
843 typedef typename __decay_and_strip<_T2>::__type __ds_type2;
844 typedef pair<__ds_type1, __ds_type2> __pair_type;
845 return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
846 }
847#else
848 template<typename _T1, typename _T2>
849 inline pair<_T1, _T2>
850 make_pair(_T1 __x, _T2 __y)
851 { return pair<_T1, _T2>(__x, __y); }
852#endif
853
854 /// @}
855
856#if __cplusplus >= 201103L
857 // Various functions which give std::pair a tuple-like interface.
858
859 /// @cond undocumented
860 template<typename _T1, typename _T2>
861 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
862 { };
863 /// @endcond
864
865 /// Partial specialization for std::pair
866 template<class _Tp1, class _Tp2>
867 struct tuple_size<pair<_Tp1, _Tp2>>
868 : public integral_constant<size_t, 2> { };
869
870 /// Partial specialization for std::pair
871 template<class _Tp1, class _Tp2>
872 struct tuple_element<0, pair<_Tp1, _Tp2>>
873 { typedef _Tp1 type; };
874
875 /// Partial specialization for std::pair
876 template<class _Tp1, class _Tp2>
877 struct tuple_element<1, pair<_Tp1, _Tp2>>
878 { typedef _Tp2 type; };
879
880#if __cplusplus >= 201703L
881 template<typename _Tp1, typename _Tp2>
882 inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
883
884 template<typename _Tp1, typename _Tp2>
885 inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
886
887 template<typename _Tp>
888 inline constexpr bool __is_pair = false;
889
890 template<typename _Tp, typename _Up>
891 inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
892
893 template<typename _Tp, typename _Up>
894 inline constexpr bool __is_pair<const pair<_Tp, _Up>> = true;
895#endif
896
897 /// @cond undocumented
898 template<size_t _Int>
899 struct __pair_get;
900
901 template<>
902 struct __pair_get<0>
903 {
904 template<typename _Tp1, typename _Tp2>
905 static constexpr _Tp1&
906 __get(pair<_Tp1, _Tp2>& __pair) noexcept
907 { return __pair.first; }
908
909 template<typename _Tp1, typename _Tp2>
910 static constexpr _Tp1&&
911 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
912 { return std::forward<_Tp1>(__pair.first); }
913
914 template<typename _Tp1, typename _Tp2>
915 static constexpr const _Tp1&
916 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
917 { return __pair.first; }
918
919 template<typename _Tp1, typename _Tp2>
920 static constexpr const _Tp1&&
921 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
922 { return std::forward<const _Tp1>(__pair.first); }
923 };
924
925 template<>
926 struct __pair_get<1>
927 {
928 template<typename _Tp1, typename _Tp2>
929 static constexpr _Tp2&
930 __get(pair<_Tp1, _Tp2>& __pair) noexcept
931 { return __pair.second; }
932
933 template<typename _Tp1, typename _Tp2>
934 static constexpr _Tp2&&
935 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
936 { return std::forward<_Tp2>(__pair.second); }
937
938 template<typename _Tp1, typename _Tp2>
939 static constexpr const _Tp2&
940 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
941 { return __pair.second; }
942
943 template<typename _Tp1, typename _Tp2>
944 static constexpr const _Tp2&&
945 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
946 { return std::forward<const _Tp2>(__pair.second); }
947 };
948 /// @endcond
949
950 /** @{
951 * std::get overloads for accessing members of std::pair
952 */
953
954 template<size_t _Int, class _Tp1, class _Tp2>
955 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
956 get(pair<_Tp1, _Tp2>& __in) noexcept
957 { return __pair_get<_Int>::__get(__in); }
958
959 template<size_t _Int, class _Tp1, class _Tp2>
960 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
961 get(pair<_Tp1, _Tp2>&& __in) noexcept
962 { return __pair_get<_Int>::__move_get(std::move(__in)); }
963
964 template<size_t _Int, class _Tp1, class _Tp2>
965 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
966 get(const pair<_Tp1, _Tp2>& __in) noexcept
967 { return __pair_get<_Int>::__const_get(__in); }
968
969 template<size_t _Int, class _Tp1, class _Tp2>
970 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
971 get(const pair<_Tp1, _Tp2>&& __in) noexcept
972 { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
973
974#if __cplusplus >= 201402L
975
976#define __cpp_lib_tuples_by_type 201304L
977
978 template <typename _Tp, typename _Up>
979 constexpr _Tp&
980 get(pair<_Tp, _Up>& __p) noexcept
981 { return __p.first; }
982
983 template <typename _Tp, typename _Up>
984 constexpr const _Tp&
985 get(const pair<_Tp, _Up>& __p) noexcept
986 { return __p.first; }
987
988 template <typename _Tp, typename _Up>
989 constexpr _Tp&&
990 get(pair<_Tp, _Up>&& __p) noexcept
991 { return std::move(__p.first); }
992
993 template <typename _Tp, typename _Up>
994 constexpr const _Tp&&
995 get(const pair<_Tp, _Up>&& __p) noexcept
996 { return std::move(__p.first); }
997
998 template <typename _Tp, typename _Up>
999 constexpr _Tp&
1000 get(pair<_Up, _Tp>& __p) noexcept
1001 { return __p.second; }
1002
1003 template <typename _Tp, typename _Up>
1004 constexpr const _Tp&
1005 get(const pair<_Up, _Tp>& __p) noexcept
1006 { return __p.second; }
1007
1008 template <typename _Tp, typename _Up>
1009 constexpr _Tp&&
1010 get(pair<_Up, _Tp>&& __p) noexcept
1011 { return std::move(__p.second); }
1012
1013 template <typename _Tp, typename _Up>
1014 constexpr const _Tp&&
1015 get(const pair<_Up, _Tp>&& __p) noexcept
1016 { return std::move(__p.second); }
1017
1018#if __cplusplus > 202002L
1019 template<typename _T1, typename _T2, typename _U1, typename _U2,
1020 template<typename> class _TQual, template<typename> class _UQual>
1021 requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1022 common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
1023 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
1024 {
1025 using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1026 common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
1027 };
1028
1029 template<typename _T1, typename _T2, typename _U1, typename _U2>
1030 requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
1031 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
1032 { using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; };
1033#endif // C++23
1034
1035#endif // C++14
1036 /// @}
1037#endif // C++11
1038
1039_GLIBCXX_END_NAMESPACE_VERSION
1040} // namespace std
1041
1042#endif /* _STL_PAIR_H */
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:82
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:766
constexpr bool operator!=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator== to find the result.
Definition: stl_pair.h:760
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:730
constexpr bool operator>=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator< to find the result.
Definition: stl_pair.h:778
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:104
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:797
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
Definition: stl_pair.h:83
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:840
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:429
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:77
ISO C++ entities toplevel namespace is std.
Primary class template, tuple.
Definition: tuple:746
integral_constant
Definition: type_traits:63
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:107
is_same
Definition: type_traits:1369
is_constructible
Definition: type_traits:1017
is_default_constructible
Definition: type_traits:1026
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:189
constexpr pair(const _T1 &__a, const _T2 &__b)
Construct from two const lvalues, allowing implicit conversions.
Definition: stl_pair.h:501
_T1 first
The first member.
Definition: stl_pair.h:193
_T1 first_type
The type of the first member.
Definition: stl_pair.h:190
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:206
constexpr pair(const pair &)=default
Copy constructor.
constexpr pair()
Definition: stl_pair.h:474
_T2 second_type
The type of the second member.
Definition: stl_pair.h:191
constexpr pair(pair &&)=default
Move constructor.
_T2 second
The second member.
Definition: stl_pair.h:194
Tag type for piecewise construction of std::pair objects.
Definition: stl_pair.h:80
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