Line data Source code
1 : // <utility> -*- C++ -*-
2 :
3 : // Copyright (C) 2001-2021 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 include/utility
52 : * This is a Standard C++ Library header.
53 : */
54 :
55 : #ifndef _GLIBCXX_UTILITY
56 : #define _GLIBCXX_UTILITY 1
57 :
58 : #pragma GCC system_header
59 :
60 : /**
61 : * @defgroup utilities Utilities
62 : *
63 : * Components deemed generally useful. Includes pair, tuple,
64 : * forward/move helpers, ratio, function object, metaprogramming and
65 : * type traits, time, date, and memory functions.
66 : */
67 :
68 : #include <bits/c++config.h>
69 : #include <bits/stl_relops.h>
70 : #include <bits/stl_pair.h>
71 :
72 : #if __cplusplus >= 201103L
73 :
74 : #include <type_traits>
75 : #include <bits/move.h>
76 : #include <initializer_list>
77 :
78 : #if __cplusplus > 201703L
79 : #include <ext/numeric_traits.h>
80 : #endif
81 :
82 : namespace std _GLIBCXX_VISIBILITY(default)
83 : {
84 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
85 :
86 : /// Finds the size of a given tuple type.
87 : template<typename _Tp>
88 : struct tuple_size;
89 :
90 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
91 : // 2313. tuple_size should always derive from integral_constant<size_t, N>
92 : // 2770. tuple_size<const T> specialization is not SFINAE compatible
93 :
94 : template<typename _Tp,
95 : typename _Up = typename remove_cv<_Tp>::type,
96 : typename = typename enable_if<is_same<_Tp, _Up>::value>::type,
97 : size_t = tuple_size<_Tp>::value>
98 : using __enable_if_has_tuple_size = _Tp;
99 :
100 : template<typename _Tp>
101 : struct tuple_size<const __enable_if_has_tuple_size<_Tp>>
102 : : public tuple_size<_Tp> { };
103 :
104 : template<typename _Tp>
105 : struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>>
106 : : public tuple_size<_Tp> { };
107 :
108 : template<typename _Tp>
109 : struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
110 : : public tuple_size<_Tp> { };
111 :
112 : /// Gives the type of the ith element of a given tuple type.
113 : template<size_t __i, typename _Tp>
114 : struct tuple_element;
115 :
116 : // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
117 : template<size_t __i, typename _Tp>
118 : using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
119 :
120 : template<size_t __i, typename _Tp>
121 : struct tuple_element<__i, const _Tp>
122 : {
123 : typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
124 : };
125 :
126 : template<size_t __i, typename _Tp>
127 : struct tuple_element<__i, volatile _Tp>
128 : {
129 : typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
130 : };
131 :
132 : template<size_t __i, typename _Tp>
133 : struct tuple_element<__i, const volatile _Tp>
134 : {
135 : typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
136 : };
137 :
138 : #if __cplusplus >= 201402L
139 : // The standard says this macro and alias template should be in <tuple>
140 : // but we define them here, to be available when the partial specializations
141 : // of tuple_element<pair<T,U>> and tuple_element<array<T,N>> are defined.
142 : #define __cpp_lib_tuple_element_t 201402L
143 :
144 : template<size_t __i, typename _Tp>
145 : using tuple_element_t = typename tuple_element<__i, _Tp>::type;
146 : #endif
147 :
148 : // Various functions which give std::pair a tuple-like interface.
149 :
150 : /// Partial specialization for std::pair
151 : template<typename _T1, typename _T2>
152 : struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
153 : { };
154 :
155 : /// Partial specialization for std::pair
156 : template<class _Tp1, class _Tp2>
157 : struct tuple_size<pair<_Tp1, _Tp2>>
158 : : public integral_constant<size_t, 2> { };
159 :
160 : /// Partial specialization for std::pair
161 : template<class _Tp1, class _Tp2>
162 : struct tuple_element<0, pair<_Tp1, _Tp2>>
163 : { typedef _Tp1 type; };
164 :
165 : /// Partial specialization for std::pair
166 : template<class _Tp1, class _Tp2>
167 : struct tuple_element<1, pair<_Tp1, _Tp2>>
168 : { typedef _Tp2 type; };
169 :
170 : template<size_t _Int>
171 : struct __pair_get;
172 :
173 : template<>
174 : struct __pair_get<0>
175 : {
176 : template<typename _Tp1, typename _Tp2>
177 : static constexpr _Tp1&
178 4029 : __get(pair<_Tp1, _Tp2>& __pair) noexcept
179 4029 : { return __pair.first; }
180 :
181 : template<typename _Tp1, typename _Tp2>
182 : static constexpr _Tp1&&
183 4684 : __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
184 4684 : { return std::forward<_Tp1>(__pair.first); }
185 :
186 : template<typename _Tp1, typename _Tp2>
187 : static constexpr const _Tp1&
188 39126 : __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
189 39126 : { return __pair.first; }
190 :
191 : template<typename _Tp1, typename _Tp2>
192 : static constexpr const _Tp1&&
193 : __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
194 : { return std::forward<const _Tp1>(__pair.first); }
195 : };
196 :
197 : template<>
198 : struct __pair_get<1>
199 : {
200 : template<typename _Tp1, typename _Tp2>
201 : static constexpr _Tp2&
202 4029 : __get(pair<_Tp1, _Tp2>& __pair) noexcept
203 4029 : { return __pair.second; }
204 :
205 : template<typename _Tp1, typename _Tp2>
206 : static constexpr _Tp2&&
207 4684 : __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
208 4684 : { return std::forward<_Tp2>(__pair.second); }
209 :
210 : template<typename _Tp1, typename _Tp2>
211 : static constexpr const _Tp2&
212 39126 : __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
213 39126 : { return __pair.second; }
214 :
215 : template<typename _Tp1, typename _Tp2>
216 : static constexpr const _Tp2&&
217 : __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
218 : { return std::forward<const _Tp2>(__pair.second); }
219 : };
220 :
221 : template<size_t _Int, class _Tp1, class _Tp2>
222 : constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
223 8058 : get(pair<_Tp1, _Tp2>& __in) noexcept
224 8058 : { return __pair_get<_Int>::__get(__in); }
225 :
226 : template<size_t _Int, class _Tp1, class _Tp2>
227 : constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
228 9368 : get(pair<_Tp1, _Tp2>&& __in) noexcept
229 9368 : { return __pair_get<_Int>::__move_get(std::move(__in)); }
230 :
231 : template<size_t _Int, class _Tp1, class _Tp2>
232 : constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
233 78252 : get(const pair<_Tp1, _Tp2>& __in) noexcept
234 78252 : { return __pair_get<_Int>::__const_get(__in); }
235 :
236 : template<size_t _Int, class _Tp1, class _Tp2>
237 : constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
238 : get(const pair<_Tp1, _Tp2>&& __in) noexcept
239 : { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
240 :
241 : #if __cplusplus >= 201402L
242 :
243 : #define __cpp_lib_tuples_by_type 201304
244 :
245 : template <typename _Tp, typename _Up>
246 : constexpr _Tp&
247 : get(pair<_Tp, _Up>& __p) noexcept
248 : { return __p.first; }
249 :
250 : template <typename _Tp, typename _Up>
251 : constexpr const _Tp&
252 : get(const pair<_Tp, _Up>& __p) noexcept
253 : { return __p.first; }
254 :
255 : template <typename _Tp, typename _Up>
256 : constexpr _Tp&&
257 : get(pair<_Tp, _Up>&& __p) noexcept
258 : { return std::move(__p.first); }
259 :
260 : template <typename _Tp, typename _Up>
261 : constexpr const _Tp&&
262 : get(const pair<_Tp, _Up>&& __p) noexcept
263 : { return std::move(__p.first); }
264 :
265 : template <typename _Tp, typename _Up>
266 : constexpr _Tp&
267 : get(pair<_Up, _Tp>& __p) noexcept
268 : { return __p.second; }
269 :
270 : template <typename _Tp, typename _Up>
271 : constexpr const _Tp&
272 : get(const pair<_Up, _Tp>& __p) noexcept
273 : { return __p.second; }
274 :
275 : template <typename _Tp, typename _Up>
276 : constexpr _Tp&&
277 : get(pair<_Up, _Tp>&& __p) noexcept
278 : { return std::move(__p.second); }
279 :
280 : template <typename _Tp, typename _Up>
281 : constexpr const _Tp&&
282 : get(const pair<_Up, _Tp>&& __p) noexcept
283 : { return std::move(__p.second); }
284 :
285 : #define __cpp_lib_exchange_function 201304
286 :
287 : /// Assign @p __new_val to @p __obj and return its previous value.
288 : template <typename _Tp, typename _Up = _Tp>
289 : _GLIBCXX20_CONSTEXPR
290 : inline _Tp
291 : exchange(_Tp& __obj, _Up&& __new_val)
292 : { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
293 :
294 : #endif // C++14
295 :
296 : // Stores a tuple of indices. Used by tuple and pair, and by bind() to
297 : // extract the elements in a tuple.
298 : template<size_t... _Indexes> struct _Index_tuple { };
299 :
300 : // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
301 : template<size_t _Num>
302 : struct _Build_index_tuple
303 : {
304 : #if __has_builtin(__make_integer_seq)
305 : template<typename, size_t... _Indices>
306 : using _IdxTuple = _Index_tuple<_Indices...>;
307 :
308 : // Clang defines __make_integer_seq for this purpose.
309 : using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
310 : #else
311 : // For GCC and other compilers, use __integer_pack instead.
312 : using __type = _Index_tuple<__integer_pack(_Num)...>;
313 : #endif
314 : };
315 :
316 : #if __cplusplus >= 201402L
317 :
318 : #define __cpp_lib_integer_sequence 201304
319 :
320 : /// Class template integer_sequence
321 : template<typename _Tp, _Tp... _Idx>
322 : struct integer_sequence
323 : {
324 : typedef _Tp value_type;
325 : static constexpr size_t size() noexcept { return sizeof...(_Idx); }
326 : };
327 :
328 : /// Alias template make_integer_sequence
329 : template<typename _Tp, _Tp _Num>
330 : using make_integer_sequence
331 : #if __has_builtin(__make_integer_seq)
332 : = __make_integer_seq<integer_sequence, _Tp, _Num>;
333 : #else
334 : = integer_sequence<_Tp, __integer_pack(_Num)...>;
335 : #endif
336 :
337 : /// Alias template index_sequence
338 : template<size_t... _Idx>
339 : using index_sequence = integer_sequence<size_t, _Idx...>;
340 :
341 : /// Alias template make_index_sequence
342 : template<size_t _Num>
343 : using make_index_sequence = make_integer_sequence<size_t, _Num>;
344 :
345 : /// Alias template index_sequence_for
346 : template<typename... _Types>
347 : using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
348 : #endif
349 :
350 : #if __cplusplus > 201402L
351 :
352 : struct in_place_t {
353 : explicit in_place_t() = default;
354 : };
355 :
356 : inline constexpr in_place_t in_place{};
357 :
358 : template<typename _Tp> struct in_place_type_t
359 : {
360 : explicit in_place_type_t() = default;
361 : };
362 :
363 : template<typename _Tp>
364 : inline constexpr in_place_type_t<_Tp> in_place_type{};
365 :
366 : template<size_t _Idx> struct in_place_index_t
367 : {
368 : explicit in_place_index_t() = default;
369 : };
370 :
371 : template<size_t _Idx>
372 : inline constexpr in_place_index_t<_Idx> in_place_index{};
373 :
374 : template<typename>
375 : inline constexpr bool __is_in_place_type_v = false;
376 :
377 : template<typename _Tp>
378 : inline constexpr bool __is_in_place_type_v<in_place_type_t<_Tp>> = true;
379 :
380 : template<typename _Tp>
381 : using __is_in_place_type = bool_constant<__is_in_place_type_v<_Tp>>;
382 :
383 : #define __cpp_lib_as_const 201510
384 : template<typename _Tp>
385 : [[nodiscard]]
386 : constexpr add_const_t<_Tp>&
387 : as_const(_Tp& __t) noexcept
388 : { return __t; }
389 :
390 : template<typename _Tp>
391 : void as_const(const _Tp&&) = delete;
392 :
393 : #if __cplusplus > 201703L
394 : #define __cpp_lib_integer_comparison_functions 202002L
395 :
396 : template<typename _Tp, typename _Up>
397 : constexpr bool
398 : cmp_equal(_Tp __t, _Up __u) noexcept
399 : {
400 : static_assert(__is_standard_integer<_Tp>::value);
401 : static_assert(__is_standard_integer<_Up>::value);
402 :
403 : if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
404 : return __t == __u;
405 : else if constexpr (is_signed_v<_Tp>)
406 : return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u;
407 : else
408 : return __u >= 0 && __t == make_unsigned_t<_Up>(__u);
409 : }
410 :
411 : template<typename _Tp, typename _Up>
412 : constexpr bool
413 : cmp_not_equal(_Tp __t, _Up __u) noexcept
414 : { return !std::cmp_equal(__t, __u); }
415 :
416 : template<typename _Tp, typename _Up>
417 : constexpr bool
418 : cmp_less(_Tp __t, _Up __u) noexcept
419 : {
420 : static_assert(__is_standard_integer<_Tp>::value);
421 : static_assert(__is_standard_integer<_Up>::value);
422 :
423 : if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
424 : return __t < __u;
425 : else if constexpr (is_signed_v<_Tp>)
426 : return __t < 0 || make_unsigned_t<_Tp>(__t) < __u;
427 : else
428 : return __u >= 0 && __t < make_unsigned_t<_Up>(__u);
429 : }
430 :
431 : template<typename _Tp, typename _Up>
432 : constexpr bool
433 : cmp_greater(_Tp __t, _Up __u) noexcept
434 : { return std::cmp_less(__u, __t); }
435 :
436 : template<typename _Tp, typename _Up>
437 : constexpr bool
438 : cmp_less_equal(_Tp __t, _Up __u) noexcept
439 : { return !std::cmp_less(__u, __t); }
440 :
441 : template<typename _Tp, typename _Up>
442 : constexpr bool
443 : cmp_greater_equal(_Tp __t, _Up __u) noexcept
444 : { return !std::cmp_less(__t, __u); }
445 :
446 : template<typename _Up, typename _Tp>
447 : constexpr bool
448 : in_range(_Tp __t) noexcept
449 : {
450 : static_assert(__is_standard_integer<_Up>::value);
451 : static_assert(__is_standard_integer<_Tp>::value);
452 : using __gnu_cxx::__int_traits;
453 :
454 : if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
455 : return __int_traits<_Up>::__min <= __t
456 : && __t <= __int_traits<_Up>::__max;
457 : else if constexpr (is_signed_v<_Tp>)
458 : return __t >= 0
459 : && make_unsigned_t<_Tp>(__t) <= __int_traits<_Up>::__max;
460 : else
461 : return __t <= make_unsigned_t<_Up>(__int_traits<_Up>::__max);
462 : }
463 :
464 : #if __cplusplus > 202002L
465 : #define __cpp_lib_to_underlying 202102L
466 : /// Convert an object of enumeration type to its underlying type.
467 : template<typename _Tp>
468 : [[nodiscard]]
469 : constexpr underlying_type_t<_Tp>
470 : to_underlying(_Tp __value) noexcept
471 : { return static_cast<underlying_type_t<_Tp>>(__value); }
472 : #endif // C++23
473 : #endif // C++20
474 : #endif // C++17
475 :
476 : _GLIBCXX_END_NAMESPACE_VERSION
477 : } // namespace
478 :
479 : #endif
480 :
481 : #endif /* _GLIBCXX_UTILITY */
|