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 | |