xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/stl_pair.h (revision 2dd295436a0082eb4f8d294f4aa73c223413d0f2)
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 
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 =
84     piecewise_construct_t();
85 
86   /// @cond undocumented
87 
88   // Forward declarations.
89   template<typename...>
90     class tuple;
91 
92   template<size_t...>
93     struct _Index_tuple;
94 
95 #if ! __cpp_lib_concepts
96   // Concept utility functions, reused in conditionally-explicit
97   // constructors.
98   // See PR 70437, don't look at is_constructible or
99   // is_convertible if the types are the same to
100   // avoid querying those properties for incomplete types.
101   template <bool, typename _T1, typename _T2>
102     struct _PCC
103     {
104       template <typename _U1, typename _U2>
105       static constexpr bool _ConstructiblePair()
106       {
107 	return __and_<is_constructible<_T1, const _U1&>,
108 		      is_constructible<_T2, const _U2&>>::value;
109       }
110 
111       template <typename _U1, typename _U2>
112       static constexpr bool _ImplicitlyConvertiblePair()
113       {
114 	return __and_<is_convertible<const _U1&, _T1>,
115 		      is_convertible<const _U2&, _T2>>::value;
116       }
117 
118       template <typename _U1, typename _U2>
119       static constexpr bool _MoveConstructiblePair()
120       {
121 	return __and_<is_constructible<_T1, _U1&&>,
122 		      is_constructible<_T2, _U2&&>>::value;
123       }
124 
125       template <typename _U1, typename _U2>
126       static constexpr bool _ImplicitlyMoveConvertiblePair()
127       {
128 	return __and_<is_convertible<_U1&&, _T1>,
129 		      is_convertible<_U2&&, _T2>>::value;
130       }
131     };
132 
133   template <typename _T1, typename _T2>
134     struct _PCC<false, _T1, _T2>
135     {
136       template <typename _U1, typename _U2>
137       static constexpr bool _ConstructiblePair()
138       {
139 	return false;
140       }
141 
142       template <typename _U1, typename _U2>
143       static constexpr bool _ImplicitlyConvertiblePair()
144       {
145 	return false;
146       }
147 
148       template <typename _U1, typename _U2>
149       static constexpr bool _MoveConstructiblePair()
150       {
151 	return false;
152       }
153 
154       template <typename _U1, typename _U2>
155       static constexpr bool _ImplicitlyMoveConvertiblePair()
156       {
157 	return false;
158       }
159     };
160 #endif // lib concepts
161 #endif // C++11
162 
163   template<typename _U1, typename _U2> class __pair_base
164   {
165 #if __cplusplus >= 201103L && ! __cpp_lib_concepts
166     template<typename _T1, typename _T2> friend struct pair;
167     __pair_base() = default;
168     ~__pair_base() = default;
169     __pair_base(const __pair_base&) = default;
170     __pair_base& operator=(const __pair_base&) = delete;
171 #endif // C++11
172   };
173 
174   /// @endcond
175 
176  /**
177    *  @brief Struct holding two objects of arbitrary type.
178    *
179    *  @tparam _T1  Type of first object.
180    *  @tparam _T2  Type of second object.
181    *
182    *  <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
183    */
184   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
200 	pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
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
217 	pair(tuple<_Args1...>&, tuple<_Args2...>&,
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_<
390                        is_default_constructible<_U1>,
391                        is_default_constructible<_U2>,
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
428 			    || !is_same<_T2, _U2>::value,
429 			    _T1, _T2>;
430       /// @endcond
431 
432       template<typename _U1, typename _U2, typename
433 	       enable_if<_PCCFP<_U1, _U2>::template
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
640     operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
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
670     operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
671     { return !(__x == __y); }
672 
673   /// Uses @c operator< to find the result.
674   template<typename _T1, typename _T2>
675     inline _GLIBCXX_CONSTEXPR bool
676     operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
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
688     operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
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
702     typename enable_if<__and_<__is_swappable<_T1>,
703                               __is_swappable<_T2>>::value>::type
704 #else
705     void
706 #endif
707     swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
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>
713     typename enable_if<!__and_<__is_swappable<_T1>,
714 			       __is_swappable<_T2>>::value>::type
715     swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
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>
739     constexpr pair<typename __decay_and_strip<_T1>::__type,
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 */
925