Line data Source code
1 : // Pair implementation -*- C++ -*-
2 :
3 : // Copyright (C) 2001-2016 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 : #include <bits/move.h> // for std::move / std::forward, and std::swap
60 :
61 : #if __cplusplus >= 201103L
62 : #include <type_traits> // for std::__decay_and_strip too
63 : #endif
64 :
65 : namespace std _GLIBCXX_VISIBILITY(default)
66 : {
67 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
68 :
69 : /**
70 : * @addtogroup utilities
71 : * @{
72 : */
73 :
74 : #if __cplusplus >= 201103L
75 : /// piecewise_construct_t
76 : struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
77 :
78 : /// piecewise_construct
79 : constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
80 :
81 : // Forward declarations.
82 : template<typename...>
83 : class tuple;
84 :
85 : template<std::size_t...>
86 : struct _Index_tuple;
87 :
88 : // Concept utility functions, reused in conditionally-explicit
89 : // constructors.
90 : // See PR 70437, don't look at is_constructible or
91 : // is_convertible if the types are the same to
92 : // avoid querying those properties for incomplete types.
93 : template <bool, typename _T1, typename _T2>
94 : struct _PCC
95 : {
96 : template <typename _U1, typename _U2>
97 : static constexpr bool _ConstructiblePair()
98 : {
99 : return __and_<is_constructible<_T1, const _U1&>,
100 : is_constructible<_T2, const _U2&>>::value;
101 : }
102 :
103 : template <typename _U1, typename _U2>
104 : static constexpr bool _ImplicitlyConvertiblePair()
105 : {
106 : return __and_<is_convertible<const _U1&, _T1>,
107 : is_convertible<const _U2&, _T2>>::value;
108 : }
109 :
110 : template <typename _U1, typename _U2>
111 : static constexpr bool _MoveConstructiblePair()
112 : {
113 : return __and_<is_constructible<_T1, _U1&&>,
114 : is_constructible<_T2, _U2&&>>::value;
115 : }
116 :
117 : template <typename _U1, typename _U2>
118 : static constexpr bool _ImplicitlyMoveConvertiblePair()
119 : {
120 : return __and_<is_convertible<_U1&&, _T1>,
121 : is_convertible<_U2&&, _T2>>::value;
122 : }
123 :
124 : template <bool __implicit, typename _U1, typename _U2>
125 : static constexpr bool _CopyMovePair()
126 : {
127 : using __do_converts = __and_<is_convertible<const _U1&, _T1>,
128 : is_convertible<_U2&&, _T2>>;
129 : using __converts = typename conditional<__implicit,
130 : __do_converts,
131 : __not_<__do_converts>>::type;
132 : return __and_<is_constructible<_T1, const _U1&>,
133 : is_constructible<_T2, _U2&&>,
134 : __converts
135 : >::value;
136 : }
137 :
138 : template <bool __implicit, typename _U1, typename _U2>
139 : static constexpr bool _MoveCopyPair()
140 : {
141 : using __do_converts = __and_<is_convertible<_U1&&, _T1>,
142 : is_convertible<const _U2&, _T2>>;
143 : using __converts = typename conditional<__implicit,
144 : __do_converts,
145 : __not_<__do_converts>>::type;
146 : return __and_<is_constructible<_T1, _U1&&>,
147 : is_constructible<_T2, const _U2&&>,
148 : __converts
149 : >::value;
150 : }
151 : };
152 :
153 : template <typename _T1, typename _T2>
154 : struct _PCC<false, _T1, _T2>
155 : {
156 : template <typename _U1, typename _U2>
157 : static constexpr bool _ConstructiblePair()
158 : {
159 : return false;
160 : }
161 :
162 : template <typename _U1, typename _U2>
163 : static constexpr bool _ImplicitlyConvertiblePair()
164 : {
165 : return false;
166 : }
167 :
168 : template <typename _U1, typename _U2>
169 : static constexpr bool _MoveConstructiblePair()
170 : {
171 : return false;
172 : }
173 :
174 : template <typename _U1, typename _U2>
175 : static constexpr bool _ImplicitlyMoveConvertiblePair()
176 : {
177 : return false;
178 : }
179 : };
180 :
181 : struct __wrap_nonesuch : std::__nonesuch {
182 : explicit __wrap_nonesuch(const __nonesuch&) = delete;
183 : };
184 :
185 : #endif
186 :
187 : /**
188 : * @brief Struct holding two objects of arbitrary type.
189 : *
190 : * @tparam _T1 Type of first object.
191 : * @tparam _T2 Type of second object.
192 : */
193 : template<typename _T1, typename _T2>
194 15 : struct pair
195 : {
196 : typedef _T1 first_type; /// @c first_type is the first bound type
197 : typedef _T2 second_type; /// @c second_type is the second bound type
198 :
199 : _T1 first; /// @c first is a copy of the first object
200 : _T2 second; /// @c second is a copy of the second object
201 :
202 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
203 : // 265. std::pair::pair() effects overly restrictive
204 : /** The default constructor creates @c first and @c second using their
205 : * respective default constructors. */
206 : #if __cplusplus >= 201103L
207 : template <typename _U1 = _T1,
208 : typename _U2 = _T2,
209 : typename enable_if<__and_<
210 : __is_implicitly_default_constructible<_U1>,
211 : __is_implicitly_default_constructible<_U2>>
212 : ::value, bool>::type = true>
213 : #endif
214 1 : _GLIBCXX_CONSTEXPR pair()
215 1 : : first(), second() { }
216 :
217 : #if __cplusplus >= 201103L
218 : template <typename _U1 = _T1,
219 : typename _U2 = _T2,
220 : typename enable_if<__and_<
221 : is_default_constructible<_U1>,
222 : is_default_constructible<_U2>,
223 : __not_<
224 : __and_<__is_implicitly_default_constructible<_U1>,
225 : __is_implicitly_default_constructible<_U2>>>>
226 : ::value, bool>::type = false>
227 : explicit constexpr pair()
228 : : first(), second() { }
229 : #endif
230 :
231 : /** Two objects may be passed to a @c pair constructor to be copied. */
232 : #if __cplusplus < 201103L
233 : pair(const _T1& __a, const _T2& __b)
234 : : first(__a), second(__b) { }
235 : #else
236 : // Shortcut for constraining the templates that don't take pairs.
237 : using _PCCP = _PCC<true, _T1, _T2>;
238 :
239 : template<typename _U1 = _T1, typename _U2=_T2, typename
240 : enable_if<_PCCP::template
241 : _ConstructiblePair<_U1, _U2>()
242 : && _PCCP::template
243 : _ImplicitlyConvertiblePair<_U1, _U2>(),
244 : bool>::type=true>
245 1 : constexpr pair(const _T1& __a, const _T2& __b)
246 1 : : first(__a), second(__b) { }
247 :
248 : template<typename _U1 = _T1, typename _U2=_T2, typename
249 : enable_if<_PCCP::template
250 : _ConstructiblePair<_U1, _U2>()
251 : && !_PCCP::template
252 : _ImplicitlyConvertiblePair<_U1, _U2>(),
253 : bool>::type=false>
254 : explicit constexpr pair(const _T1& __a, const _T2& __b)
255 : : first(__a), second(__b) { }
256 : #endif
257 :
258 : /** There is also a templated copy ctor for the @c pair class itself. */
259 : #if __cplusplus < 201103L
260 : template<typename _U1, typename _U2>
261 : pair(const pair<_U1, _U2>& __p)
262 : : first(__p.first), second(__p.second) { }
263 : #else
264 : // Shortcut for constraining the templates that take pairs.
265 : template <typename _U1, typename _U2>
266 : using _PCCFP = _PCC<!is_same<_T1, _U1>::value
267 : || !is_same<_T2, _U2>::value,
268 : _T1, _T2>;
269 :
270 : template<typename _U1, typename _U2, typename
271 : enable_if<_PCCFP<_U1, _U2>::template
272 : _ConstructiblePair<_U1, _U2>()
273 : && _PCCFP<_U1, _U2>::template
274 : _ImplicitlyConvertiblePair<_U1, _U2>(),
275 : bool>::type=true>
276 : constexpr pair(const pair<_U1, _U2>& __p)
277 : : first(__p.first), second(__p.second) { }
278 :
279 : template<typename _U1, typename _U2, typename
280 : enable_if<_PCCFP<_U1, _U2>::template
281 : _ConstructiblePair<_U1, _U2>()
282 : && !_PCCFP<_U1, _U2>::template
283 : _ImplicitlyConvertiblePair<_U1, _U2>(),
284 : bool>::type=false>
285 : explicit constexpr pair(const pair<_U1, _U2>& __p)
286 : : first(__p.first), second(__p.second) { }
287 :
288 1 : constexpr pair(const pair&) = default;
289 0 : constexpr pair(pair&&) = default;
290 :
291 : // DR 811.
292 : template<typename _U1, typename
293 : enable_if<_PCCP::template
294 : _MoveCopyPair<true, _U1, _T2>(),
295 : bool>::type=true>
296 0 : constexpr pair(_U1&& __x, const _T2& __y)
297 0 : : first(std::forward<_U1>(__x)), second(__y) { }
298 :
299 : template<typename _U1, typename
300 : enable_if<_PCCP::template
301 : _MoveCopyPair<false, _U1, _T2>(),
302 : bool>::type=false>
303 : explicit constexpr pair(_U1&& __x, const _T2& __y)
304 : : first(std::forward<_U1>(__x)), second(__y) { }
305 :
306 : template<typename _U2, typename
307 : enable_if<_PCCP::template
308 : _CopyMovePair<true, _T1, _U2>(),
309 : bool>::type=true>
310 0 : constexpr pair(const _T1& __x, _U2&& __y)
311 0 : : first(__x), second(std::forward<_U2>(__y)) { }
312 :
313 : template<typename _U2, typename
314 : enable_if<_PCCP::template
315 : _CopyMovePair<false, _T1, _U2>(),
316 : bool>::type=false>
317 : explicit pair(const _T1& __x, _U2&& __y)
318 : : first(__x), second(std::forward<_U2>(__y)) { }
319 :
320 : template<typename _U1, typename _U2, typename
321 : enable_if<_PCCP::template
322 : _MoveConstructiblePair<_U1, _U2>()
323 : && _PCCP::template
324 : _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
325 : bool>::type=true>
326 12 : constexpr pair(_U1&& __x, _U2&& __y)
327 12 : : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
328 :
329 : template<typename _U1, typename _U2, typename
330 : enable_if<_PCCP::template
331 : _MoveConstructiblePair<_U1, _U2>()
332 : && !_PCCP::template
333 : _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
334 : bool>::type=false>
335 : explicit constexpr pair(_U1&& __x, _U2&& __y)
336 : : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
337 :
338 :
339 : template<typename _U1, typename _U2, typename
340 : enable_if<_PCCFP<_U1, _U2>::template
341 : _MoveConstructiblePair<_U1, _U2>()
342 : && _PCCFP<_U1, _U2>::template
343 : _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
344 : bool>::type=true>
345 : constexpr pair(pair<_U1, _U2>&& __p)
346 : : first(std::forward<_U1>(__p.first)),
347 : second(std::forward<_U2>(__p.second)) { }
348 :
349 : template<typename _U1, typename _U2, typename
350 : enable_if<_PCCFP<_U1, _U2>::template
351 : _MoveConstructiblePair<_U1, _U2>()
352 : && !_PCCFP<_U1, _U2>::template
353 : _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
354 : bool>::type=false>
355 : explicit constexpr pair(pair<_U1, _U2>&& __p)
356 : : first(std::forward<_U1>(__p.first)),
357 : second(std::forward<_U2>(__p.second)) { }
358 :
359 : template<typename... _Args1, typename... _Args2>
360 : pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
361 :
362 : pair&
363 : operator=(typename conditional<
364 : __and_<is_copy_assignable<_T1>,
365 : is_copy_assignable<_T2>>::value,
366 : const pair&, const __wrap_nonesuch&>::type __p)
367 : {
368 : first = __p.first;
369 : second = __p.second;
370 : return *this;
371 : }
372 :
373 : pair&
374 : operator=(typename conditional<
375 : __not_<__and_<is_copy_assignable<_T1>,
376 : is_copy_assignable<_T2>>>::value,
377 : const pair&, const __wrap_nonesuch&>::type __p) = delete;
378 :
379 : pair&
380 1 : operator=(typename conditional<
381 : __and_<is_move_assignable<_T1>,
382 : is_move_assignable<_T2>>::value,
383 : pair&&, __wrap_nonesuch&&>::type __p)
384 : noexcept(__and_<is_nothrow_move_assignable<_T1>,
385 : is_nothrow_move_assignable<_T2>>::value)
386 : {
387 1 : first = std::forward<first_type>(__p.first);
388 1 : second = std::forward<second_type>(__p.second);
389 1 : return *this;
390 : }
391 :
392 : template<typename _U1, typename _U2>
393 : typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
394 : is_assignable<_T2&, const _U2&>>::value,
395 : pair&>::type
396 : operator=(const pair<_U1, _U2>& __p)
397 : {
398 : first = __p.first;
399 : second = __p.second;
400 : return *this;
401 : }
402 :
403 : template<typename _U1, typename _U2>
404 : typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
405 : is_assignable<_T2&, _U2&&>>::value,
406 : pair&>::type
407 : operator=(pair<_U1, _U2>&& __p)
408 : {
409 : first = std::forward<_U1>(__p.first);
410 : second = std::forward<_U2>(__p.second);
411 : return *this;
412 : }
413 :
414 : void
415 : swap(pair& __p)
416 : noexcept(__is_nothrow_swappable<_T1>::value
417 : && __is_nothrow_swappable<_T2>::value)
418 : {
419 : using std::swap;
420 : swap(first, __p.first);
421 : swap(second, __p.second);
422 : }
423 :
424 : private:
425 : template<typename... _Args1, std::size_t... _Indexes1,
426 : typename... _Args2, std::size_t... _Indexes2>
427 : pair(tuple<_Args1...>&, tuple<_Args2...>&,
428 : _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
429 : #endif
430 : };
431 :
432 : /// Two pairs of the same type are equal iff their members are equal.
433 : template<typename _T1, typename _T2>
434 : inline _GLIBCXX_CONSTEXPR bool
435 : operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
436 : { return __x.first == __y.first && __x.second == __y.second; }
437 :
438 : /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
439 : template<typename _T1, typename _T2>
440 : inline _GLIBCXX_CONSTEXPR bool
441 : operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
442 : { return __x.first < __y.first
443 : || (!(__y.first < __x.first) && __x.second < __y.second); }
444 :
445 : /// Uses @c operator== to find the result.
446 : template<typename _T1, typename _T2>
447 : inline _GLIBCXX_CONSTEXPR bool
448 : operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
449 : { return !(__x == __y); }
450 :
451 : /// Uses @c operator< to find the result.
452 : template<typename _T1, typename _T2>
453 : inline _GLIBCXX_CONSTEXPR bool
454 : operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
455 : { return __y < __x; }
456 :
457 : /// Uses @c operator< to find the result.
458 : template<typename _T1, typename _T2>
459 : inline _GLIBCXX_CONSTEXPR bool
460 : operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
461 : { return !(__y < __x); }
462 :
463 : /// Uses @c operator< to find the result.
464 : template<typename _T1, typename _T2>
465 : inline _GLIBCXX_CONSTEXPR bool
466 : operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
467 : { return !(__x < __y); }
468 :
469 : #if __cplusplus >= 201103L
470 : /// See std::pair::swap().
471 : // Note: no std::swap overloads in C++03 mode, this has performance
472 : // implications, see, eg, libstdc++/38466.
473 : template<typename _T1, typename _T2>
474 : inline void
475 : swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
476 : noexcept(noexcept(__x.swap(__y)))
477 : { __x.swap(__y); }
478 : #endif
479 :
480 : /**
481 : * @brief A convenience wrapper for creating a pair from two objects.
482 : * @param __x The first object.
483 : * @param __y The second object.
484 : * @return A newly-constructed pair<> object of the appropriate type.
485 : *
486 : * The standard requires that the objects be passed by reference-to-const,
487 : * but LWG issue #181 says they should be passed by const value. We follow
488 : * the LWG by default.
489 : */
490 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
491 : // 181. make_pair() unintended behavior
492 : #if __cplusplus >= 201103L
493 : // NB: DR 706.
494 : template<typename _T1, typename _T2>
495 : constexpr pair<typename __decay_and_strip<_T1>::__type,
496 : typename __decay_and_strip<_T2>::__type>
497 2 : make_pair(_T1&& __x, _T2&& __y)
498 : {
499 : typedef typename __decay_and_strip<_T1>::__type __ds_type1;
500 : typedef typename __decay_and_strip<_T2>::__type __ds_type2;
501 : typedef pair<__ds_type1, __ds_type2> __pair_type;
502 2 : return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
503 : }
504 : #else
505 : template<typename _T1, typename _T2>
506 : inline pair<_T1, _T2>
507 : make_pair(_T1 __x, _T2 __y)
508 : { return pair<_T1, _T2>(__x, __y); }
509 : #endif
510 :
511 : /// @}
512 :
513 : _GLIBCXX_END_NAMESPACE_VERSION
514 : } // namespace std
515 :
516 : #endif /* _STL_PAIR_H */
|