Line data Source code
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 24734 : 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 3617 : 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 36157 : 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 3926509541 : constexpr pair(_U1&& __x, _U2&& __y)
535 3926004809 : : 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 111633 : constexpr pair(pair<_U1, _U2>&& __p)
554 : : first(std::forward<_U1>(__p.first)),
555 111633 : 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 7821586700 : operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
569 : is_copy_assignable<_T2>>::value,
570 : const pair&, const __nonesuch&> __p)
571 : {
572 7821586700 : first = __p.first;
573 3910527755 : 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 1026809 : 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 1026809 : 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 24807 : { 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 */
|