libstdc++
stl_pair.h
Go to the documentation of this file.
1 // Pair implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
51 /** @file bits/stl_pair.h
52  * This is an internal header file, included by other library headers.
53  * Do not attempt to use it directly. @headername{utility}
54  */
55 
56 #ifndef _STL_PAIR_H
57 #define _STL_PAIR_H 1
58 
59 #if __cplusplus >= 201103L
60 # include <type_traits> // for std::__decay_and_strip
61 # include <bits/move.h> // for std::move / std::forward, and std::swap
62 # include <bits/utility.h> // for std::tuple_element, std::tuple_size
63 #endif
64 #if __cplusplus >= 202002L
65 # include <compare>
66 # define __cpp_lib_constexpr_utility 201811L
67 #endif
68 
69 namespace 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 
285  // True if construction from _U1 and _U2 would create a dangling ref.
286  template<typename _U1, typename _U2>
287  static constexpr bool
288  _S_dangles()
289  {
290 #if __has_builtin(__reference_constructs_from_temporary)
291  if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
292  return true;
293  else
294  return __reference_constructs_from_temporary(_T2, _U2&&);
295 #else
296  return false;
297 #endif
298  }
299  /// @endcond
300 
301  public:
302 
303  /// Constructor accepting lvalues of `first_type` and `second_type`
304  constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
305  pair(const _T1& __x, const _T2& __y)
306  noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
307  requires (_S_constructible<const _T1&, const _T2&>())
308  : first(__x), second(__y)
309  { }
310 
311  /// Constructor accepting two values of arbitrary types
312  template<typename _U1, typename _U2>
313  requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
314  constexpr explicit(!_S_convertible<_U1, _U2>())
315  pair(_U1&& __x, _U2&& __y)
316  noexcept(_S_nothrow_constructible<_U1, _U2>())
317  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
318  { }
319 
320  template<typename _U1, typename _U2>
321  requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
322  constexpr explicit(!_S_convertible<_U1, _U2>())
323  pair(_U1&&, _U2&&) = delete;
324 
325  /// Converting constructor from a const `pair<U1, U2>` lvalue
326  template<typename _U1, typename _U2>
327  requires (_S_constructible<const _U1&, const _U2&>())
328  && (!_S_dangles<_U1, _U2>())
329  constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
330  pair(const pair<_U1, _U2>& __p)
331  noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
332  : first(__p.first), second(__p.second)
333  { }
334 
335  template<typename _U1, typename _U2>
336  requires (_S_constructible<const _U1&, const _U2&>())
337  && (_S_dangles<const _U1&, const _U2&>())
338  constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
339  pair(const pair<_U1, _U2>&) = delete;
340 
341  /// Converting constructor from a non-const `pair<U1, U2>` rvalue
342  template<typename _U1, typename _U2>
343  requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
344  constexpr explicit(!_S_convertible<_U1, _U2>())
345  pair(pair<_U1, _U2>&& __p)
346  noexcept(_S_nothrow_constructible<_U1, _U2>())
347  : first(std::forward<_U1>(__p.first)),
348  second(std::forward<_U2>(__p.second))
349  { }
350 
351  template<typename _U1, typename _U2>
352  requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
353  constexpr explicit(!_S_convertible<_U1, _U2>())
354  pair(pair<_U1, _U2>&&) = delete;
355 
356 #if __cplusplus > 202002L
357  /// Converting constructor from a non-const `pair<U1, U2>` lvalue
358  template<typename _U1, typename _U2>
359  requires (_S_constructible<_U1&, _U2&>()) && (!_S_dangles<_U1&, _U2&>())
360  constexpr explicit(!_S_convertible<_U1&, _U2&>())
361  pair(pair<_U1, _U2>& __p)
362  noexcept(_S_nothrow_constructible<_U1&, _U2&>())
363  : first(__p.first), second(__p.second)
364  { }
365 
366  template<typename _U1, typename _U2>
367  requires (_S_constructible<_U1&, _U2&>()) && (_S_dangles<_U1&, _U2&>())
368  constexpr explicit(!_S_convertible<_U1&, _U2&>())
369  pair(pair<_U1, _U2>&) = delete;
370 
371  /// Converting constructor from a const `pair<U1, U2>` rvalue
372  template<typename _U1, typename _U2>
373  requires (_S_constructible<const _U1, const _U2>())
374  && (!_S_dangles<const _U1, const _U2>())
375  constexpr explicit(!_S_convertible<const _U1, const _U2>())
376  pair(const pair<_U1, _U2>&& __p)
377  noexcept(_S_nothrow_constructible<const _U1, const _U2>())
378  : first(std::forward<const _U1>(__p.first)),
379  second(std::forward<const _U2>(__p.second))
380  { }
381 
382  template<typename _U1, typename _U2>
383  requires (_S_constructible<const _U1, const _U2>())
384  && (_S_dangles<const _U1, const _U2>())
385  constexpr explicit(!_S_convertible<const _U1, const _U2>())
386  pair(const pair<_U1, _U2>&&) = delete;
387 #endif // C++23
388 
389  private:
390  /// @cond undocumented
391  template<typename _U1, typename _U2>
392  static constexpr bool
393  _S_assignable()
394  {
395  if constexpr (is_assignable_v<_T1&, _U1>)
396  return is_assignable_v<_T2&, _U2>;
397  return false;
398  }
399 
400  template<typename _U1, typename _U2>
401  static constexpr bool
402  _S_nothrow_assignable()
403  {
404  if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
405  return is_nothrow_assignable_v<_T2&, _U2>;
406  return false;
407  }
408  /// @endcond
409 
410  public:
411 
412  pair& operator=(const pair&) = delete;
413 
414  /// Copy assignment operator
415  constexpr pair&
416  operator=(const pair& __p)
417  noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
418  requires (_S_assignable<const _T1&, const _T2&>())
419  {
420  first = __p.first;
421  second = __p.second;
422  return *this;
423  }
424 
425  /// Move assignment operator
426  constexpr pair&
427  operator=(pair&& __p)
428  noexcept(_S_nothrow_assignable<_T1, _T2>())
429  requires (_S_assignable<_T1, _T2>())
430  {
431  first = std::forward<first_type>(__p.first);
432  second = std::forward<second_type>(__p.second);
433  return *this;
434  }
435 
436  /// Converting assignment from a const `pair<U1, U2>` lvalue
437  template<typename _U1, typename _U2>
438  constexpr pair&
439  operator=(const pair<_U1, _U2>& __p)
440  noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
441  requires (_S_assignable<const _U1&, const _U2&>())
442  {
443  first = __p.first;
444  second = __p.second;
445  return *this;
446  }
447 
448  /// Converting assignment from a non-const `pair<U1, U2>` rvalue
449  template<typename _U1, typename _U2>
450  constexpr pair&
451  operator=(pair<_U1, _U2>&& __p)
452  noexcept(_S_nothrow_assignable<_U1, _U2>())
453  requires (_S_assignable<_U1, _U2>())
454  {
455  first = std::forward<_U1>(__p.first);
456  second = std::forward<_U2>(__p.second);
457  return *this;
458  }
459 
460 #if __cplusplus > 202002L
461  /// Copy assignment operator (const)
462  constexpr const pair&
463  operator=(const pair& __p) const
464  requires is_copy_assignable_v<const first_type>
465  && is_copy_assignable_v<const second_type>
466  {
467  first = __p.first;
468  second = __p.second;
469  return *this;
470  }
471 
472  /// Move assignment operator (const)
473  constexpr const pair&
474  operator=(pair&& __p) const
475  requires is_assignable_v<const first_type&, first_type>
476  && is_assignable_v<const second_type&, second_type>
477  {
478  first = std::forward<first_type>(__p.first);
479  second = std::forward<second_type>(__p.second);
480  return *this;
481  }
482 
483  /// Converting assignment from a const `pair<U1, U2>` lvalue
484  template<typename _U1, typename _U2>
485  constexpr const pair&
486  operator=(const pair<_U1, _U2>& __p) const
487  requires is_assignable_v<const first_type&, const _U1&>
488  && is_assignable_v<const second_type&, const _U2&>
489  {
490  first = __p.first;
491  second = __p.second;
492  return *this;
493  }
494 
495  /// Converting assignment from a non-const `pair<U1, U2>` rvalue
496  template<typename _U1, typename _U2>
497  constexpr const pair&
498  operator=(pair<_U1, _U2>&& __p) const
499  requires is_assignable_v<const first_type&, _U1>
500  && is_assignable_v<const second_type&, _U2>
501  {
502  first = std::forward<_U1>(__p.first);
503  second = std::forward<_U2>(__p.second);
504  return *this;
505  }
506 #endif // C++23
507 #else // !__cpp_lib_concepts
508  // C++11/14/17 implementation using enable_if, partially constexpr.
509 
510  /// @cond undocumented
511  // Error if construction from _U1 and _U2 would create a dangling ref.
512 #if __has_builtin(__reference_constructs_from_temporary) \
513  && defined _GLIBCXX_DEBUG
514 # define __glibcxx_no_dangling_refs(_U1, _U2) \
515  static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
516  && !__reference_constructs_from_temporary(_T2, _U2), \
517  "std::pair constructor creates a dangling reference")
518 #else
519 # define __glibcxx_no_dangling_refs(_U1, _U2)
520 #endif
521  /// @endcond
522 
523  /** The default constructor creates @c first and @c second using their
524  * respective default constructors. */
525  template <typename _U1 = _T1,
526  typename _U2 = _T2,
527  typename enable_if<__and_<
528  __is_implicitly_default_constructible<_U1>,
529  __is_implicitly_default_constructible<_U2>>
530  ::value, bool>::type = true>
531  constexpr pair()
532  : first(), second() { }
533 
534  template <typename _U1 = _T1,
535  typename _U2 = _T2,
536  typename enable_if<__and_<
539  __not_<
540  __and_<__is_implicitly_default_constructible<_U1>,
541  __is_implicitly_default_constructible<_U2>>>>
542  ::value, bool>::type = false>
543  explicit constexpr pair()
544  : first(), second() { }
545 
546  // Shortcut for constraining the templates that don't take pairs.
547  /// @cond undocumented
548  using _PCCP = _PCC<true, _T1, _T2>;
549  /// @endcond
550 
551  /// Construct from two const lvalues, allowing implicit conversions.
552  template<typename _U1 = _T1, typename _U2=_T2, typename
553  enable_if<_PCCP::template
554  _ConstructiblePair<_U1, _U2>()
555  && _PCCP::template
556  _ImplicitlyConvertiblePair<_U1, _U2>(),
557  bool>::type=true>
558  constexpr pair(const _T1& __a, const _T2& __b)
559  : first(__a), second(__b) { }
560 
561  /// Construct from two const lvalues, disallowing implicit conversions.
562  template<typename _U1 = _T1, typename _U2=_T2, typename
563  enable_if<_PCCP::template
564  _ConstructiblePair<_U1, _U2>()
565  && !_PCCP::template
566  _ImplicitlyConvertiblePair<_U1, _U2>(),
567  bool>::type=false>
568  explicit constexpr pair(const _T1& __a, const _T2& __b)
569  : first(__a), second(__b) { }
570 
571  // Shortcut for constraining the templates that take pairs.
572  /// @cond undocumented
573  template <typename _U1, typename _U2>
574  using _PCCFP = _PCC<!is_same<_T1, _U1>::value
576  _T1, _T2>;
577  /// @endcond
578 
579  template<typename _U1, typename _U2, typename
581  _ConstructiblePair<_U1, _U2>()
582  && _PCCFP<_U1, _U2>::template
583  _ImplicitlyConvertiblePair<_U1, _U2>(),
584  bool>::type=true>
585  constexpr pair(const pair<_U1, _U2>& __p)
586  : first(__p.first), second(__p.second)
587  { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
588 
589  template<typename _U1, typename _U2, typename
590  enable_if<_PCCFP<_U1, _U2>::template
591  _ConstructiblePair<_U1, _U2>()
592  && !_PCCFP<_U1, _U2>::template
593  _ImplicitlyConvertiblePair<_U1, _U2>(),
594  bool>::type=false>
595  explicit constexpr pair(const pair<_U1, _U2>& __p)
596  : first(__p.first), second(__p.second)
597  { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
598 
599 #if _GLIBCXX_USE_DEPRECATED
600 #if defined(__DEPRECATED)
601 # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
602  __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
603  "initialize std::pair of move-only " \
604  "type and pointer")))
605 #else
606 # define _GLIBCXX_DEPRECATED_PAIR_CTOR
607 #endif
608 
609  private:
610  /// @cond undocumented
611 
612  // A type which can be constructed from literal zero, but not nullptr
613  struct __zero_as_null_pointer_constant
614  {
615  __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
616  { }
617  template<typename _Tp,
618  typename = __enable_if_t<is_null_pointer<_Tp>::value>>
619  __zero_as_null_pointer_constant(_Tp) = delete;
620  };
621  /// @endcond
622  public:
623 
624  // Deprecated extensions to DR 811.
625  // These allow construction from an rvalue and a literal zero,
626  // in cases where the standard says the zero should be deduced as int
627  template<typename _U1,
628  __enable_if_t<__and_<__not_<is_reference<_U1>>,
629  is_pointer<_T2>,
630  is_constructible<_T1, _U1>,
631  __not_<is_constructible<_T1, const _U1&>>,
632  is_convertible<_U1, _T1>>::value,
633  bool> = true>
634  _GLIBCXX_DEPRECATED_PAIR_CTOR
635  constexpr
636  pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
637  : first(std::forward<_U1>(__x)), second(nullptr)
638  { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
639 
640  template<typename _U1,
641  __enable_if_t<__and_<__not_<is_reference<_U1>>,
642  is_pointer<_T2>,
643  is_constructible<_T1, _U1>,
644  __not_<is_constructible<_T1, const _U1&>>,
645  __not_<is_convertible<_U1, _T1>>>::value,
646  bool> = false>
647  _GLIBCXX_DEPRECATED_PAIR_CTOR
648  explicit constexpr
649  pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
650  : first(std::forward<_U1>(__x)), second(nullptr)
651  { __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
652 
653  template<typename _U2,
654  __enable_if_t<__and_<is_pointer<_T1>,
655  __not_<is_reference<_U2>>,
656  is_constructible<_T2, _U2>,
657  __not_<is_constructible<_T2, const _U2&>>,
658  is_convertible<_U2, _T2>>::value,
659  bool> = true>
660  _GLIBCXX_DEPRECATED_PAIR_CTOR
661  constexpr
662  pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
663  : first(nullptr), second(std::forward<_U2>(__y))
664  { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
665 
666  template<typename _U2,
667  __enable_if_t<__and_<is_pointer<_T1>,
668  __not_<is_reference<_U2>>,
669  is_constructible<_T2, _U2>,
670  __not_<is_constructible<_T2, const _U2&>>,
671  __not_<is_convertible<_U2, _T2>>>::value,
672  bool> = false>
673  _GLIBCXX_DEPRECATED_PAIR_CTOR
674  explicit constexpr
675  pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
676  : first(nullptr), second(std::forward<_U2>(__y))
677  { __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
678 #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
679 #endif
680 
681  template<typename _U1, typename _U2, typename
682  enable_if<_PCCP::template
683  _MoveConstructiblePair<_U1, _U2>()
684  && _PCCP::template
685  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
686  bool>::type=true>
687  constexpr pair(_U1&& __x, _U2&& __y)
688  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
689  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
690 
691  template<typename _U1, typename _U2, typename
692  enable_if<_PCCP::template
693  _MoveConstructiblePair<_U1, _U2>()
694  && !_PCCP::template
695  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
696  bool>::type=false>
697  explicit constexpr pair(_U1&& __x, _U2&& __y)
698  : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
699  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
700 
701 
702  template<typename _U1, typename _U2, typename
703  enable_if<_PCCFP<_U1, _U2>::template
704  _MoveConstructiblePair<_U1, _U2>()
705  && _PCCFP<_U1, _U2>::template
706  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
707  bool>::type=true>
708  constexpr pair(pair<_U1, _U2>&& __p)
709  : first(std::forward<_U1>(__p.first)),
710  second(std::forward<_U2>(__p.second))
711  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
712 
713  template<typename _U1, typename _U2, typename
714  enable_if<_PCCFP<_U1, _U2>::template
715  _MoveConstructiblePair<_U1, _U2>()
716  && !_PCCFP<_U1, _U2>::template
717  _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
718  bool>::type=false>
719  explicit constexpr pair(pair<_U1, _U2>&& __p)
720  : first(std::forward<_U1>(__p.first)),
721  second(std::forward<_U2>(__p.second))
722  { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
723 
724 #undef __glibcxx_no_dangling_refs
725 
726  pair&
727  operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
728  is_copy_assignable<_T2>>::value,
729  const pair&, const __nonesuch&> __p)
730  {
731  first = __p.first;
732  second = __p.second;
733  return *this;
734  }
735 
736  pair&
737  operator=(__conditional_t<__and_<is_move_assignable<_T1>,
738  is_move_assignable<_T2>>::value,
739  pair&&, __nonesuch&&> __p)
740  noexcept(__and_<is_nothrow_move_assignable<_T1>,
741  is_nothrow_move_assignable<_T2>>::value)
742  {
743  first = std::forward<first_type>(__p.first);
744  second = std::forward<second_type>(__p.second);
745  return *this;
746  }
747 
748  template<typename _U1, typename _U2>
749  typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
750  is_assignable<_T2&, const _U2&>>::value,
751  pair&>::type
752  operator=(const pair<_U1, _U2>& __p)
753  {
754  first = __p.first;
755  second = __p.second;
756  return *this;
757  }
758 
759  template<typename _U1, typename _U2>
760  typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
761  is_assignable<_T2&, _U2&&>>::value,
762  pair&>::type
763  operator=(pair<_U1, _U2>&& __p)
764  {
765  first = std::forward<_U1>(__p.first);
766  second = std::forward<_U2>(__p.second);
767  return *this;
768  }
769 #endif // lib concepts
770 #else
771  // C++03 implementation
772 
773  // _GLIBCXX_RESOLVE_LIB_DEFECTS
774  // 265. std::pair::pair() effects overly restrictive
775  /** The default constructor creates @c first and @c second using their
776  * respective default constructors. */
777  pair() : first(), second() { }
778 
779  /// Two objects may be passed to a `pair` constructor to be copied.
780  pair(const _T1& __a, const _T2& __b)
781  : first(__a), second(__b) { }
782 
783  /// Templated constructor to convert from other pairs.
784  template<typename _U1, typename _U2>
785  pair(const pair<_U1, _U2>& __p)
786  : first(__p.first), second(__p.second)
787  {
788 #if __has_builtin(__reference_constructs_from_temporary)
789 #pragma GCC diagnostic push
790 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
791  typedef int _DanglingCheck1[
792  __reference_constructs_from_temporary(_T1, const _U1&) ? -1 : 1
793  ];
794  typedef int _DanglingCheck2[
795  __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
796  ];
797 #pragma GCC diagnostic pop
798 #endif
799  }
800 #endif // C++11
801  };
802 
803  /// @relates pair @{
804 
805 #if __cpp_deduction_guides >= 201606
806  template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
807 #endif
808 
809  /// Two pairs of the same type are equal iff their members are equal.
810  template<typename _T1, typename _T2>
811  inline _GLIBCXX_CONSTEXPR bool
812  operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
813  { return __x.first == __y.first && __x.second == __y.second; }
814 
815 #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
816  template<typename _T1, typename _T2>
817  constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
818  __detail::__synth3way_t<_T2>>
819  operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
820  {
821  if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
822  return __c;
823  return __detail::__synth3way(__x.second, __y.second);
824  }
825 #else
826  /** Defines a lexicographical order for pairs.
827  *
828  * For two pairs of the same type, `P` is ordered before `Q` if
829  * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
830  * are equivalent (neither is less than the other) and `P.second` is less
831  * than `Q.second`.
832  */
833  template<typename _T1, typename _T2>
834  inline _GLIBCXX_CONSTEXPR bool
835  operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
836  { return __x.first < __y.first
837  || (!(__y.first < __x.first) && __x.second < __y.second); }
838 
839  /// Uses @c operator== to find the result.
840  template<typename _T1, typename _T2>
841  inline _GLIBCXX_CONSTEXPR bool
842  operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
843  { return !(__x == __y); }
844 
845  /// Uses @c operator< to find the result.
846  template<typename _T1, typename _T2>
847  inline _GLIBCXX_CONSTEXPR bool
848  operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
849  { return __y < __x; }
850 
851  /// Uses @c operator< to find the result.
852  template<typename _T1, typename _T2>
853  inline _GLIBCXX_CONSTEXPR bool
854  operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
855  { return !(__y < __x); }
856 
857  /// Uses @c operator< to find the result.
858  template<typename _T1, typename _T2>
859  inline _GLIBCXX_CONSTEXPR bool
860  operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
861  { return !(__x < __y); }
862 #endif // !(three_way_comparison && concepts)
863 
864 #if __cplusplus >= 201103L
865  /** Swap overload for pairs. Calls std::pair::swap().
866  *
867  * @note This std::swap overload is not declared in C++03 mode,
868  * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
869  */
870  template<typename _T1, typename _T2>
871  _GLIBCXX20_CONSTEXPR inline
872 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
873  // Constrained free swap overload, see p0185r1
875  __is_swappable<_T2>>::value>::type
876 #else
877  void
878 #endif
880  noexcept(noexcept(__x.swap(__y)))
881  { __x.swap(__y); }
882 
883 #if __cplusplus > 202002L
884  template<typename _T1, typename _T2>
885  requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
886  constexpr void
887  swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
888  noexcept(noexcept(__x.swap(__y)))
889  { __x.swap(__y); }
890 #endif // C++23
891 
892 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
893  template<typename _T1, typename _T2>
894  typename enable_if<!__and_<__is_swappable<_T1>,
895  __is_swappable<_T2>>::value>::type
896  swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
897 #endif
898 #endif // __cplusplus >= 201103L
899 
900  /// @} relates pair
901 
902  /**
903  * @brief A convenience wrapper for creating a pair from two objects.
904  * @param __x The first object.
905  * @param __y The second object.
906  * @return A newly-constructed pair<> object of the appropriate type.
907  *
908  * The C++98 standard says the objects are passed by reference-to-const,
909  * but C++03 says they are passed by value (this was LWG issue #181).
910  *
911  * Since C++11 they have been passed by forwarding reference and then
912  * forwarded to the new members of the pair. To create a pair with a
913  * member of reference type, pass a `reference_wrapper` to this function.
914  */
915  // _GLIBCXX_RESOLVE_LIB_DEFECTS
916  // 181. make_pair() unintended behavior
917 #if __cplusplus >= 201103L
918  // NB: DR 706.
919  template<typename _T1, typename _T2>
920  constexpr pair<typename __decay_and_strip<_T1>::__type,
921  typename __decay_and_strip<_T2>::__type>
922  make_pair(_T1&& __x, _T2&& __y)
923  {
924  typedef typename __decay_and_strip<_T1>::__type __ds_type1;
925  typedef typename __decay_and_strip<_T2>::__type __ds_type2;
926  typedef pair<__ds_type1, __ds_type2> __pair_type;
927  return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
928  }
929 #else
930  template<typename _T1, typename _T2>
931  inline pair<_T1, _T2>
932  make_pair(_T1 __x, _T2 __y)
933  { return pair<_T1, _T2>(__x, __y); }
934 #endif
935 
936  /// @}
937 
938 #if __cplusplus >= 201103L
939  // Various functions which give std::pair a tuple-like interface.
940 
941  /// @cond undocumented
942  template<typename _T1, typename _T2>
943  struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
944  { };
945  /// @endcond
946 
947  /// Partial specialization for std::pair
948  template<class _Tp1, class _Tp2>
949  struct tuple_size<pair<_Tp1, _Tp2>>
950  : public integral_constant<size_t, 2> { };
951 
952  /// Partial specialization for std::pair
953  template<class _Tp1, class _Tp2>
954  struct tuple_element<0, pair<_Tp1, _Tp2>>
955  { typedef _Tp1 type; };
956 
957  /// Partial specialization for std::pair
958  template<class _Tp1, class _Tp2>
959  struct tuple_element<1, pair<_Tp1, _Tp2>>
960  { typedef _Tp2 type; };
961 
962 #if __cplusplus >= 201703L
963  template<typename _Tp1, typename _Tp2>
964  inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
965 
966  template<typename _Tp1, typename _Tp2>
967  inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
968 
969  template<typename _Tp>
970  inline constexpr bool __is_pair = false;
971 
972  template<typename _Tp, typename _Up>
973  inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
974 #endif
975 
976  /// @cond undocumented
977  template<size_t _Int>
978  struct __pair_get;
979 
980  template<>
981  struct __pair_get<0>
982  {
983  template<typename _Tp1, typename _Tp2>
984  static constexpr _Tp1&
985  __get(pair<_Tp1, _Tp2>& __pair) noexcept
986  { return __pair.first; }
987 
988  template<typename _Tp1, typename _Tp2>
989  static constexpr _Tp1&&
990  __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
991  { return std::forward<_Tp1>(__pair.first); }
992 
993  template<typename _Tp1, typename _Tp2>
994  static constexpr const _Tp1&
995  __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
996  { return __pair.first; }
997 
998  template<typename _Tp1, typename _Tp2>
999  static constexpr const _Tp1&&
1000  __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1001  { return std::forward<const _Tp1>(__pair.first); }
1002  };
1003 
1004  template<>
1005  struct __pair_get<1>
1006  {
1007  template<typename _Tp1, typename _Tp2>
1008  static constexpr _Tp2&
1009  __get(pair<_Tp1, _Tp2>& __pair) noexcept
1010  { return __pair.second; }
1011 
1012  template<typename _Tp1, typename _Tp2>
1013  static constexpr _Tp2&&
1014  __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
1015  { return std::forward<_Tp2>(__pair.second); }
1016 
1017  template<typename _Tp1, typename _Tp2>
1018  static constexpr const _Tp2&
1019  __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
1020  { return __pair.second; }
1021 
1022  template<typename _Tp1, typename _Tp2>
1023  static constexpr const _Tp2&&
1024  __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
1025  { return std::forward<const _Tp2>(__pair.second); }
1026  };
1027  /// @endcond
1028 
1029  /** @{
1030  * std::get overloads for accessing members of std::pair
1031  */
1032 
1033  template<size_t _Int, class _Tp1, class _Tp2>
1034  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1035  get(pair<_Tp1, _Tp2>& __in) noexcept
1036  { return __pair_get<_Int>::__get(__in); }
1037 
1038  template<size_t _Int, class _Tp1, class _Tp2>
1039  constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1040  get(pair<_Tp1, _Tp2>&& __in) noexcept
1041  { return __pair_get<_Int>::__move_get(std::move(__in)); }
1042 
1043  template<size_t _Int, class _Tp1, class _Tp2>
1044  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
1045  get(const pair<_Tp1, _Tp2>& __in) noexcept
1046  { return __pair_get<_Int>::__const_get(__in); }
1047 
1048  template<size_t _Int, class _Tp1, class _Tp2>
1049  constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
1050  get(const pair<_Tp1, _Tp2>&& __in) noexcept
1051  { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
1052 
1053 #if __cplusplus >= 201402L
1054 
1055 #define __cpp_lib_tuples_by_type 201304L
1056 
1057  template <typename _Tp, typename _Up>
1058  constexpr _Tp&
1059  get(pair<_Tp, _Up>& __p) noexcept
1060  { return __p.first; }
1061 
1062  template <typename _Tp, typename _Up>
1063  constexpr const _Tp&
1064  get(const pair<_Tp, _Up>& __p) noexcept
1065  { return __p.first; }
1066 
1067  template <typename _Tp, typename _Up>
1068  constexpr _Tp&&
1069  get(pair<_Tp, _Up>&& __p) noexcept
1070  { return std::move(__p.first); }
1071 
1072  template <typename _Tp, typename _Up>
1073  constexpr const _Tp&&
1074  get(const pair<_Tp, _Up>&& __p) noexcept
1075  { return std::move(__p.first); }
1076 
1077  template <typename _Tp, typename _Up>
1078  constexpr _Tp&
1079  get(pair<_Up, _Tp>& __p) noexcept
1080  { return __p.second; }
1081 
1082  template <typename _Tp, typename _Up>
1083  constexpr const _Tp&
1084  get(const pair<_Up, _Tp>& __p) noexcept
1085  { return __p.second; }
1086 
1087  template <typename _Tp, typename _Up>
1088  constexpr _Tp&&
1089  get(pair<_Up, _Tp>&& __p) noexcept
1090  { return std::move(__p.second); }
1091 
1092  template <typename _Tp, typename _Up>
1093  constexpr const _Tp&&
1094  get(const pair<_Up, _Tp>&& __p) noexcept
1095  { return std::move(__p.second); }
1096 
1097 #if __cplusplus > 202002L
1098  template<typename _T1, typename _T2, typename _U1, typename _U2,
1099  template<typename> class _TQual, template<typename> class _UQual>
1100  requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1101  common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
1102  struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
1103  {
1104  using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
1105  common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
1106  };
1107 
1108  template<typename _T1, typename _T2, typename _U1, typename _U2>
1109  requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
1110  struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
1111  { using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; };
1112 #endif // C++23
1113 
1114 #endif // C++14
1115  /// @}
1116 #endif // C++11
1117 
1118 _GLIBCXX_END_NAMESPACE_VERSION
1119 } // namespace std
1120 
1121 #endif /* _STL_PAIR_H */
constexpr bool is_swappable_v
is_swappable_v
Definition: type_traits:2812
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:848
constexpr bool operator!=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator== to find the result.
Definition: stl_pair.h:842
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:812
constexpr bool operator>=(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Uses operator< to find the result.
Definition: stl_pair.h:860
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:879
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
Definition: stl_pair.h:83
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:97
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:922
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:70
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:429
ISO C++ entities toplevel namespace is std.
Primary class template, tuple.
Definition: tuple:747
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:1399
is_constructible
Definition: type_traits:1047
is_default_constructible
Definition: type_traits:1056
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:558
_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:531
_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