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 template<typename _T1, typename _T2>
185 struct pair
186 : public __pair_base<_T1, _T2>
187 {
188 typedef _T1 first_type; ///< The type of the `first` member
189 typedef _T2 second_type; ///< The type of the `second` member
190
191 _T1 first; ///< The first member
192 _T2 second; ///< The second member
193
194#if __cplusplus >= 201103L
195 constexpr pair(const pair&) = default; ///< Copy constructor
196 constexpr pair(pair&&) = default; ///< Move constructor
197
198 template<typename... _Args1, typename... _Args2>
199 _GLIBCXX20_CONSTEXPR
201
202 /// Swap the first members and then the second members.
203 _GLIBCXX20_CONSTEXPR void
204 swap(pair& __p)
205 noexcept(__and_<__is_nothrow_swappable<_T1>,
206 __is_nothrow_swappable<_T2>>::value)
207 {
208 using std::swap;
209 swap(first, __p.first);
210 swap(second, __p.second);
211 }
212
213 private:
214 template<typename... _Args1, size_t... _Indexes1,
215 typename... _Args2, size_t... _Indexes2>
216 _GLIBCXX20_CONSTEXPR
218 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
219 public:
220
221#if __cpp_lib_concepts
222 // C++20 implementation using concepts, explicit(bool), fully constexpr.
223
224 /// Default constructor
225 constexpr
226 explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
227 __is_implicitly_default_constructible<_T2>>>())
228 pair()
229 requires is_default_constructible_v<_T1>
230 && is_default_constructible_v<_T2>
231 : first(), second()
232 { }
233
234 private:
235
236 /// @cond undocumented
237 template<typename _U1, typename _U2>
238 static constexpr bool
239 _S_constructible()
240 {
241 if constexpr (is_constructible_v<_T1, _U1>)
242 return is_constructible_v<_T2, _U2>;
243 return false;
244 }
245
246 template<typename _U1, typename _U2>
247 static constexpr bool
248 _S_nothrow_constructible()
249 {
250 if constexpr (is_nothrow_constructible_v<_T1, _U1>)
251 return is_nothrow_constructible_v<_T2, _U2>;
252 return false;
253 }
254
255 template<typename _U1, typename _U2>
256 static constexpr bool
257 _S_convertible()
258 {
259 if constexpr (is_convertible_v<_U1, _T1>)
260 return is_convertible_v<_U2, _T2>;
261 return false;
262 }
263 /// @endcond
264
265 public:
266
267 /// Constructor accepting lvalues of `first_type` and `second_type`
268 constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
269 pair(const _T1& __x, const _T2& __y)
270 noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
271 requires (_S_constructible<const _T1&, const _T2&>())
272 : first(__x), second(__y)
273 { }
274
275 /// Constructor accepting two values of arbitrary types
276 template<typename _U1, typename _U2>
277 requires (_S_constructible<_U1, _U2>())
278 constexpr explicit(!_S_convertible<_U1, _U2>())
279 pair(_U1&& __x, _U2&& __y)
280 noexcept(_S_nothrow_constructible<_U1, _U2>())
281 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
282 { }
283
284 /// Converting constructor from a `pair<U1, U2>` lvalue
285 template<typename _U1, typename _U2>
286 requires (_S_constructible<const _U1&, const _U2&>())
287 constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
288 pair(const pair<_U1, _U2>& __p)
289 noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
290 : first(__p.first), second(__p.second)
291 { }
292
293 /// Converting constructor from a `pair<U1, U2>` rvalue
294 template<typename _U1, typename _U2>
295 requires (_S_constructible<_U1, _U2>())
296 constexpr explicit(!_S_convertible<_U1, _U2>())
297 pair(pair<_U1, _U2>&& __p)
298 noexcept(_S_nothrow_constructible<_U1, _U2>())
299 : first(std::forward<_U1>(__p.first)),
300 second(std::forward<_U2>(__p.second))
301 { }
302
303 private:
304 /// @cond undocumented
305 template<typename _U1, typename _U2>
306 static constexpr bool
307 _S_assignable()
308 {
309 if constexpr (is_assignable_v<_T1&, _U1>)
310 return is_assignable_v<_T2&, _U2>;
311 return false;
312 }
313
314 template<typename _U1, typename _U2>
315 static constexpr bool
316 _S_nothrow_assignable()
317 {
318 if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
319 return is_nothrow_assignable_v<_T2&, _U2>;
320 return false;
321 }
322 /// @endcond
323
324 public:
325
326 pair& operator=(const pair&) = delete;
327
328 /// Copy assignment operator
329 constexpr pair&
330 operator=(const pair& __p)
331 noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
332 requires (_S_assignable<const _T1&, const _T2&>())
333 {
334 first = __p.first;
335 second = __p.second;
336 return *this;
337 }
338
339 /// Move assignment operator
340 constexpr pair&
341 operator=(pair&& __p)
342 noexcept(_S_nothrow_assignable<_T1, _T2>())
343 requires (_S_assignable<_T1, _T2>())
344 {
345 first = std::forward<first_type>(__p.first);
346 second = std::forward<second_type>(__p.second);
347 return *this;
348 }
349
350 /// Converting assignment from a `pair<U1, U2>` lvalue
351 template<typename _U1, typename _U2>
352 constexpr pair&
353 operator=(const pair<_U1, _U2>& __p)
354 noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
355 requires (_S_assignable<const _U1&, const _U2&>())
356 {
357 first = __p.first;
358 second = __p.second;
359 return *this;
360 }
361
362 /// Converting assignment from a `pair<U1, U2>` rvalue
363 template<typename _U1, typename _U2>
364 constexpr pair&
365 operator=(pair<_U1, _U2>&& __p)
366 noexcept(_S_nothrow_assignable<_U1, _U2>())
367 requires (_S_assignable<_U1, _U2>())
368 {
369 first = std::forward<_U1>(__p.first);
370 second = std::forward<_U2>(__p.second);
371 return *this;
372 }
373#else
374 // C++11/14/17 implementation using enable_if, partially constexpr.
375
376 /** The default constructor creates @c first and @c second using their
377 * respective default constructors. */
378 template <typename _U1 = _T1,
379 typename _U2 = _T2,
380 typename enable_if<__and_<
381 __is_implicitly_default_constructible<_U1>,
382 __is_implicitly_default_constructible<_U2>>
383 ::value, bool>::type = true>
384 constexpr pair()
385 : first(), second() { }
386
387 template <typename _U1 = _T1,
388 typename _U2 = _T2,
389 typename enable_if<__and_<
392 __not_<
393 __and_<__is_implicitly_default_constructible<_U1>,
394 __is_implicitly_default_constructible<_U2>>>>
395 ::value, bool>::type = false>
396 explicit constexpr pair()
397 : first(), second() { }
398
399 // Shortcut for constraining the templates that don't take pairs.
400 /// @cond undocumented
401 using _PCCP = _PCC<true, _T1, _T2>;
402 /// @endcond
403
404 /// Construct from two const lvalues, allowing implicit conversions.
405 template<typename _U1 = _T1, typename _U2=_T2, typename
406 enable_if<_PCCP::template
407 _ConstructiblePair<_U1, _U2>()
408 && _PCCP::template
409 _ImplicitlyConvertiblePair<_U1, _U2>(),
410 bool>::type=true>
411 constexpr pair(const _T1& __a, const _T2& __b)
412 : first(__a), second(__b) { }
413
414 /// Construct from two const lvalues, disallowing implicit conversions.
415 template<typename _U1 = _T1, typename _U2=_T2, typename
416 enable_if<_PCCP::template
417 _ConstructiblePair<_U1, _U2>()
418 && !_PCCP::template
419 _ImplicitlyConvertiblePair<_U1, _U2>(),
420 bool>::type=false>
421 explicit constexpr pair(const _T1& __a, const _T2& __b)
422 : first(__a), second(__b) { }
423
424 // Shortcut for constraining the templates that take pairs.
425 /// @cond undocumented
426 template <typename _U1, typename _U2>
427 using _PCCFP = _PCC<!is_same<_T1, _U1>::value
429 _T1, _T2>;
430 /// @endcond
431
432 template<typename _U1, typename _U2, typename
434 _ConstructiblePair<_U1, _U2>()
435 && _PCCFP<_U1, _U2>::template
436 _ImplicitlyConvertiblePair<_U1, _U2>(),
437 bool>::type=true>
438 constexpr pair(const pair<_U1, _U2>& __p)
439 : first(__p.first), second(__p.second) { }
440
441 template<typename _U1, typename _U2, typename
442 enable_if<_PCCFP<_U1, _U2>::template
443 _ConstructiblePair<_U1, _U2>()
444 && !_PCCFP<_U1, _U2>::template
445 _ImplicitlyConvertiblePair<_U1, _U2>(),
446 bool>::type=false>
447 explicit constexpr pair(const pair<_U1, _U2>& __p)
448 : first(__p.first), second(__p.second) { }
449
450#if _GLIBCXX_USE_DEPRECATED
451#if defined(__DEPRECATED)
452# define _GLIBCXX_DEPRECATED_PAIR_CTOR \
453 __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
454 "initialize std::pair of move-only " \
455 "type and pointer")))
456#else
457# define _GLIBCXX_DEPRECATED_PAIR_CTOR
458#endif
459
460 private:
461 /// @cond undocumented
462
463 // A type which can be constructed from literal zero, but not nullptr
464 struct __zero_as_null_pointer_constant
465 {
466 __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
467 { }
468 template<typename _Tp,
469 typename = __enable_if_t<is_null_pointer<_Tp>::value>>
470 __zero_as_null_pointer_constant(_Tp) = delete;
471 };
472 /// @endcond
473 public:
474
475 // Deprecated extensions to DR 811.
476 // These allow construction from an rvalue and a literal zero,
477 // in cases where the standard says the zero should be deduced as int
478 template<typename _U1,
479 __enable_if_t<__and_<__not_<is_reference<_U1>>,
480 is_pointer<_T2>,
481 is_constructible<_T1, _U1>,
482 __not_<is_constructible<_T1, const _U1&>>,
483 is_convertible<_U1, _T1>>::value,
484 bool> = true>
485 _GLIBCXX_DEPRECATED_PAIR_CTOR
486 constexpr
487 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
488 : first(std::forward<_U1>(__x)), second(nullptr) { }
489
490 template<typename _U1,
491 __enable_if_t<__and_<__not_<is_reference<_U1>>,
492 is_pointer<_T2>,
493 is_constructible<_T1, _U1>,
494 __not_<is_constructible<_T1, const _U1&>>,
495 __not_<is_convertible<_U1, _T1>>>::value,
496 bool> = false>
497 _GLIBCXX_DEPRECATED_PAIR_CTOR
498 explicit constexpr
499 pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
500 : first(std::forward<_U1>(__x)), second(nullptr) { }
501
502 template<typename _U2,
503 __enable_if_t<__and_<is_pointer<_T1>,
504 __not_<is_reference<_U2>>,
505 is_constructible<_T2, _U2>,
506 __not_<is_constructible<_T2, const _U2&>>,
507 is_convertible<_U2, _T2>>::value,
508 bool> = true>
509 _GLIBCXX_DEPRECATED_PAIR_CTOR
510 constexpr
511 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
512 : first(nullptr), second(std::forward<_U2>(__y)) { }
513
514 template<typename _U2,
515 __enable_if_t<__and_<is_pointer<_T1>,
516 __not_<is_reference<_U2>>,
517 is_constructible<_T2, _U2>,
518 __not_<is_constructible<_T2, const _U2&>>,
519 __not_<is_convertible<_U2, _T2>>>::value,
520 bool> = false>
521 _GLIBCXX_DEPRECATED_PAIR_CTOR
522 explicit constexpr
523 pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
524 : first(nullptr), second(std::forward<_U2>(__y)) { }
525#undef _GLIBCXX_DEPRECATED_PAIR_CTOR
526#endif
527
528 template<typename _U1, typename _U2, typename
529 enable_if<_PCCP::template
530 _MoveConstructiblePair<_U1, _U2>()
531 && _PCCP::template
532 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
533 bool>::type=true>
534 constexpr pair(_U1&& __x, _U2&& __y)
535 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
536
537 template<typename _U1, typename _U2, typename
538 enable_if<_PCCP::template
539 _MoveConstructiblePair<_U1, _U2>()
540 && !_PCCP::template
541 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
542 bool>::type=false>
543 explicit constexpr pair(_U1&& __x, _U2&& __y)
544 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
545
546
547 template<typename _U1, typename _U2, typename
548 enable_if<_PCCFP<_U1, _U2>::template
549 _MoveConstructiblePair<_U1, _U2>()
550 && _PCCFP<_U1, _U2>::template
551 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
552 bool>::type=true>
553 constexpr pair(pair<_U1, _U2>&& __p)
554 : first(std::forward<_U1>(__p.first)),
555 second(std::forward<_U2>(__p.second)) { }
556
557 template<typename _U1, typename _U2, typename
558 enable_if<_PCCFP<_U1, _U2>::template
559 _MoveConstructiblePair<_U1, _U2>()
560 && !_PCCFP<_U1, _U2>::template
561 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
562 bool>::type=false>
563 explicit constexpr pair(pair<_U1, _U2>&& __p)
564 : first(std::forward<_U1>(__p.first)),
565 second(std::forward<_U2>(__p.second)) { }
566
567 pair&
568 operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
569 is_copy_assignable<_T2>>::value,
570 const pair&, const __nonesuch&> __p)
571 {
572 first = __p.first;
573 second = __p.second;
574 return *this;
575 }
576
577 pair&
578 operator=(__conditional_t<__and_<is_move_assignable<_T1>,
579 is_move_assignable<_T2>>::value,
580 pair&&, __nonesuch&&> __p)
581 noexcept(__and_<is_nothrow_move_assignable<_T1>,
582 is_nothrow_move_assignable<_T2>>::value)
583 {
584 first = std::forward<first_type>(__p.first);
585 second = std::forward<second_type>(__p.second);
586 return *this;
587 }
588
589 template<typename _U1, typename _U2>
590 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
591 is_assignable<_T2&, const _U2&>>::value,
592 pair&>::type
593 operator=(const pair<_U1, _U2>& __p)
594 {
595 first = __p.first;
596 second = __p.second;
597 return *this;
598 }
599
600 template<typename _U1, typename _U2>
601 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
602 is_assignable<_T2&, _U2&&>>::value,
603 pair&>::type
604 operator=(pair<_U1, _U2>&& __p)
605 {
606 first = std::forward<_U1>(__p.first);
607 second = std::forward<_U2>(__p.second);
608 return *this;
609 }
610#endif // lib concepts
611#else
612 // C++03 implementation
613
614 // _GLIBCXX_RESOLVE_LIB_DEFECTS
615 // 265. std::pair::pair() effects overly restrictive
616 /** The default constructor creates @c first and @c second using their
617 * respective default constructors. */
618 pair() : first(), second() { }
619
620 /// Two objects may be passed to a `pair` constructor to be copied.
621 pair(const _T1& __a, const _T2& __b)
622 : first(__a), second(__b) { }
623
624 /// Templated constructor to convert from other pairs.
625 template<typename _U1, typename _U2>
626 pair(const pair<_U1, _U2>& __p)
627 : first(__p.first), second(__p.second) { }
628#endif // C++11
629 };
630
631 /// @relates pair @{
632
633#if __cpp_deduction_guides >= 201606
634 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
635#endif
636
637 /// Two pairs of the same type are equal iff their members are equal.
638 template<typename _T1, typename _T2>
639 inline _GLIBCXX_CONSTEXPR bool
641 { return __x.first == __y.first && __x.second == __y.second; }
642
643#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
644 template<typename _T1, typename _T2>
645 constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
646 __detail::__synth3way_t<_T2>>
647 operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
648 {
649 if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
650 return __c;
651 return __detail::__synth3way(__x.second, __y.second);
652 }
653#else
654 /** Defines a lexicographical order for pairs.
655 *
656 * For two pairs of the same type, `P` is ordered before `Q` if
657 * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
658 * are equivalent (neither is less than the other) and `P.second` is less
659 * than `Q.second`.
660 */
661 template<typename _T1, typename _T2>
662 inline _GLIBCXX_CONSTEXPR bool
663 operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
664 { return __x.first < __y.first
665 || (!(__y.first < __x.first) && __x.second < __y.second); }
666
667 /// Uses @c operator== to find the result.
668 template<typename _T1, typename _T2>
669 inline _GLIBCXX_CONSTEXPR bool
671 { return !(__x == __y); }
672
673 /// Uses @c operator< to find the result.
674 template<typename _T1, typename _T2>
675 inline _GLIBCXX_CONSTEXPR bool
677 { return __y < __x; }
678
679 /// Uses @c operator< to find the result.
680 template<typename _T1, typename _T2>
681 inline _GLIBCXX_CONSTEXPR bool
682 operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
683 { return !(__y < __x); }
684
685 /// Uses @c operator< to find the result.
686 template<typename _T1, typename _T2>
687 inline _GLIBCXX_CONSTEXPR bool
689 { return !(__x < __y); }
690#endif // !(three_way_comparison && concepts)
691
692#if __cplusplus >= 201103L
693 /** Swap overload for pairs. Calls std::pair::swap().
694 *
695 * @note This std::swap overload is not declared in C++03 mode,
696 * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
697 */
698 template<typename _T1, typename _T2>
699 _GLIBCXX20_CONSTEXPR inline
700#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
701 // Constrained free swap overload, see p0185r1
703 __is_swappable<_T2>>::value>::type
704#else
705 void
706#endif
708 noexcept(noexcept(__x.swap(__y)))
709 { __x.swap(__y); }
710
711#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
712 template<typename _T1, typename _T2>
714 __is_swappable<_T2>>::value>::type
716#endif
717#endif // __cplusplus >= 201103L
718
719 /// @} relates pair
720
721 /**
722 * @brief A convenience wrapper for creating a pair from two objects.
723 * @param __x The first object.
724 * @param __y The second object.
725 * @return A newly-constructed pair<> object of the appropriate type.
726 *
727 * The C++98 standard says the objects are passed by reference-to-const,
728 * but C++03 says they are passed by value (this was LWG issue #181).
729 *
730 * Since C++11 they have been passed by forwarding reference and then
731 * forwarded to the new members of the pair. To create a pair with a
732 * member of reference type, pass a `reference_wrapper` to this function.
733 */
734 // _GLIBCXX_RESOLVE_LIB_DEFECTS
735 // 181. make_pair() unintended behavior
736#if __cplusplus >= 201103L
737 // NB: DR 706.
738 template<typename _T1, typename _T2>
740 typename __decay_and_strip<_T2>::__type>
741 make_pair(_T1&& __x, _T2&& __y)
742 {
743 typedef typename __decay_and_strip<_T1>::__type __ds_type1;
744 typedef typename __decay_and_strip<_T2>::__type __ds_type2;
745 typedef pair<__ds_type1, __ds_type2> __pair_type;
746 return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
747 }
748#else
749 template<typename _T1, typename _T2>
750 inline pair<_T1, _T2>
751 make_pair(_T1 __x, _T2 __y)
752 { return pair<_T1, _T2>(__x, __y); }
753#endif
754
755 /// @}
756
757#if __cplusplus >= 201103L
758 // Various functions which give std::pair a tuple-like interface.
759
760 template<typename _T1, typename _T2>
761 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
762 { };
763
764 /// Partial specialization for std::pair
765 template<class _Tp1, class _Tp2>
766 struct tuple_size<pair<_Tp1, _Tp2>>
767 : public integral_constant<size_t, 2> { };
768
769 /// Partial specialization for std::pair
770 template<class _Tp1, class _Tp2>
771 struct tuple_element<0, pair<_Tp1, _Tp2>>
772 { typedef _Tp1 type; };
773
774 /// Partial specialization for std::pair
775 template<class _Tp1, class _Tp2>
776 struct tuple_element<1, pair<_Tp1, _Tp2>>
777 { typedef _Tp2 type; };
778
779#if __cplusplus >= 201703L
780 template<typename _Tp1, typename _Tp2>
781 inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
782
783 template<typename _Tp1, typename _Tp2>
784 inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
785
786 template<typename _Tp>
787 inline constexpr bool __is_pair = false;
788
789 template<typename _Tp, typename _Up>
790 inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
791
792 template<typename _Tp, typename _Up>
793 inline constexpr bool __is_pair<const pair<_Tp, _Up>> = true;
794#endif
795
796 /// @cond undocumented
797 template<size_t _Int>
798 struct __pair_get;
799
800 template<>
801 struct __pair_get<0>
802 {
803 template<typename _Tp1, typename _Tp2>
804 static constexpr _Tp1&
805 __get(pair<_Tp1, _Tp2>& __pair) noexcept
806 { return __pair.first; }
807
808 template<typename _Tp1, typename _Tp2>
809 static constexpr _Tp1&&
810 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
811 { return std::forward<_Tp1>(__pair.first); }
812
813 template<typename _Tp1, typename _Tp2>
814 static constexpr const _Tp1&
815 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
816 { return __pair.first; }
817
818 template<typename _Tp1, typename _Tp2>
819 static constexpr const _Tp1&&
820 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
821 { return std::forward<const _Tp1>(__pair.first); }
822 };
823
824 template<>
825 struct __pair_get<1>
826 {
827 template<typename _Tp1, typename _Tp2>
828 static constexpr _Tp2&
829 __get(pair<_Tp1, _Tp2>& __pair) noexcept
830 { return __pair.second; }
831
832 template<typename _Tp1, typename _Tp2>
833 static constexpr _Tp2&&
834 __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
835 { return std::forward<_Tp2>(__pair.second); }
836
837 template<typename _Tp1, typename _Tp2>
838 static constexpr const _Tp2&
839 __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
840 { return __pair.second; }
841
842 template<typename _Tp1, typename _Tp2>
843 static constexpr const _Tp2&&
844 __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
845 { return std::forward<const _Tp2>(__pair.second); }
846 };
847 /// @endcond
848
849 /** @{
850 * std::get overloads for accessing members of std::pair
851 */
852
853 template<size_t _Int, class _Tp1, class _Tp2>
854 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
855 get(pair<_Tp1, _Tp2>& __in) noexcept
856 { return __pair_get<_Int>::__get(__in); }
857
858 template<size_t _Int, class _Tp1, class _Tp2>
859 constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
860 get(pair<_Tp1, _Tp2>&& __in) noexcept
861 { return __pair_get<_Int>::__move_get(std::move(__in)); }
862
863 template<size_t _Int, class _Tp1, class _Tp2>
864 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
865 get(const pair<_Tp1, _Tp2>& __in) noexcept
866 { return __pair_get<_Int>::__const_get(__in); }
867
868 template<size_t _Int, class _Tp1, class _Tp2>
869 constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
870 get(const pair<_Tp1, _Tp2>&& __in) noexcept
871 { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
872
873#if __cplusplus >= 201402L
874
875#define __cpp_lib_tuples_by_type 201304L
876
877 template <typename _Tp, typename _Up>
878 constexpr _Tp&
879 get(pair<_Tp, _Up>& __p) noexcept
880 { return __p.first; }
881
882 template <typename _Tp, typename _Up>
883 constexpr const _Tp&
884 get(const pair<_Tp, _Up>& __p) noexcept
885 { return __p.first; }
886
887 template <typename _Tp, typename _Up>
888 constexpr _Tp&&
889 get(pair<_Tp, _Up>&& __p) noexcept
890 { return std::move(__p.first); }
891
892 template <typename _Tp, typename _Up>
893 constexpr const _Tp&&
894 get(const pair<_Tp, _Up>&& __p) noexcept
895 { return std::move(__p.first); }
896
897 template <typename _Tp, typename _Up>
898 constexpr _Tp&
899 get(pair<_Up, _Tp>& __p) noexcept
900 { return __p.second; }
901
902 template <typename _Tp, typename _Up>
903 constexpr const _Tp&
904 get(const pair<_Up, _Tp>& __p) noexcept
905 { return __p.second; }
906
907 template <typename _Tp, typename _Up>
908 constexpr _Tp&&
909 get(pair<_Up, _Tp>&& __p) noexcept
910 { return std::move(__p.second); }
911
912 template <typename _Tp, typename _Up>
913 constexpr const _Tp&&
914 get(const pair<_Up, _Tp>&& __p) noexcept
915 { return std::move(__p.second); }
916
917#endif // C++14
918 /// @}
919#endif // C++11
920
921_GLIBCXX_END_NAMESPACE_VERSION
922} // namespace std
923
924#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:676
constexpr bool operator!=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator== to find the result.
Definition: stl_pair.h:670
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:640
constexpr bool operator>=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator< to find the result.
Definition: stl_pair.h:688
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:707
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:741
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:610
integral_constant
Definition: type_traits:63
is_same
Definition: type_traits:1435
is_constructible
Definition: type_traits:979
is_default_constructible
Definition: type_traits:988
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:2223
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:187
constexpr pair(const _T1 &__a, const _T2 &__b)
Construct from two const lvalues, allowing implicit conversions.
Definition: stl_pair.h:411
_T1 first
The first member.
Definition: stl_pair.h:191
_T1 first_type
The type of the first member.
Definition: stl_pair.h:188
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:204
constexpr pair(const pair &)=default
Copy constructor.
constexpr pair()
Definition: stl_pair.h:384
_T2 second_type
The type of the second member.
Definition: stl_pair.h:189
constexpr pair(pair &&)=default
Move constructor.
_T2 second
The second member.
Definition: stl_pair.h:192
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