| 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 |
__get(pair<_Tp1, _Tp2>& __pair) noexcept |
| 179 |
{ return __pair.first; } |
| 180 |
|
| 181 |
template<typename _Tp1, typename _Tp2> |
| 182 |
static constexpr _Tp1&& |
| 183 |
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept |
| 184 |
{ return std::forward<_Tp1>(__pair.first); } |
| 185 |
|
| 186 |
template<typename _Tp1, typename _Tp2> |
| 187 |
static constexpr const _Tp1& |
| 188 |
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept |
| 189 |
{ 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 |
__get(pair<_Tp1, _Tp2>& __pair) noexcept |
| 203 |
{ return __pair.second; } |
| 204 |
|
| 205 |
template<typename _Tp1, typename _Tp2> |
| 206 |
static constexpr _Tp2&& |
| 207 |
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept |
| 208 |
{ return std::forward<_Tp2>(__pair.second); } |
| 209 |
|
| 210 |
template<typename _Tp1, typename _Tp2> |
| 211 |
static constexpr const _Tp2& |
| 212 |
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept |
| 213 |
{ 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 |
get(pair<_Tp1, _Tp2>& __in) noexcept |
| 224 |
{ 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 |
get(pair<_Tp1, _Tp2>&& __in) noexcept |
| 229 |
{ 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 |
get(const pair<_Tp1, _Tp2>& __in) noexcept |
| 234 |
{ 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 |
struct __is_in_place_type_impl : false_type |
| 376 |
{ }; |
| 377 |
|
| 378 |
template<typename _Tp> |
| 379 |
struct __is_in_place_type_impl<in_place_type_t<_Tp>> : true_type |
| 380 |
{ }; |
| 381 |
|
| 382 |
template<typename _Tp> |
| 383 |
struct __is_in_place_type |
| 384 |
: public __is_in_place_type_impl<_Tp> |
| 385 |
{ }; |
| 386 |
|
| 387 |
#define __cpp_lib_as_const 201510 |
| 388 |
template<typename _Tp> |
| 389 |
[[nodiscard]] |
| 390 |
constexpr add_const_t<_Tp>& |
| 391 |
as_const(_Tp& __t) noexcept |
| 392 |
{ return __t; } |
| 393 |
|
| 394 |
template<typename _Tp> |
| 395 |
void as_const(const _Tp&&) = delete; |
| 396 |
|
| 397 |
#if __cplusplus > 201703L |
| 398 |
#define __cpp_lib_integer_comparison_functions 202002L |
| 399 |
|
| 400 |
template<typename _Tp, typename _Up> |
| 401 |
constexpr bool |
| 402 |
cmp_equal(_Tp __t, _Up __u) noexcept |
| 403 |
{ |
| 404 |
static_assert(__is_standard_integer<_Tp>::value); |
| 405 |
static_assert(__is_standard_integer<_Up>::value); |
| 406 |
|
| 407 |
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) |
| 408 |
return __t == __u; |
| 409 |
else if constexpr (is_signed_v<_Tp>) |
| 410 |
return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u; |
| 411 |
else |
| 412 |
return __u >= 0 && __t == make_unsigned_t<_Up>(__u); |
| 413 |
} |
| 414 |
|
| 415 |
template<typename _Tp, typename _Up> |
| 416 |
constexpr bool |
| 417 |
cmp_not_equal(_Tp __t, _Up __u) noexcept |
| 418 |
{ return !std::cmp_equal(__t, __u); } |
| 419 |
|
| 420 |
template<typename _Tp, typename _Up> |
| 421 |
constexpr bool |
| 422 |
cmp_less(_Tp __t, _Up __u) noexcept |
| 423 |
{ |
| 424 |
static_assert(__is_standard_integer<_Tp>::value); |
| 425 |
static_assert(__is_standard_integer<_Up>::value); |
| 426 |
|
| 427 |
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) |
| 428 |
return __t < __u; |
| 429 |
else if constexpr (is_signed_v<_Tp>) |
| 430 |
return __t < 0 || make_unsigned_t<_Tp>(__t) < __u; |
| 431 |
else |
| 432 |
return __u >= 0 && __t < make_unsigned_t<_Up>(__u); |
| 433 |
} |
| 434 |
|
| 435 |
template<typename _Tp, typename _Up> |
| 436 |
constexpr bool |
| 437 |
cmp_greater(_Tp __t, _Up __u) noexcept |
| 438 |
{ return std::cmp_less(__u, __t); } |
| 439 |
|
| 440 |
template<typename _Tp, typename _Up> |
| 441 |
constexpr bool |
| 442 |
cmp_less_equal(_Tp __t, _Up __u) noexcept |
| 443 |
{ return !std::cmp_less(__u, __t); } |
| 444 |
|
| 445 |
template<typename _Tp, typename _Up> |
| 446 |
constexpr bool |
| 447 |
cmp_greater_equal(_Tp __t, _Up __u) noexcept |
| 448 |
{ return !std::cmp_less(__t, __u); } |
| 449 |
|
| 450 |
template<typename _Up, typename _Tp> |
| 451 |
constexpr bool |
| 452 |
in_range(_Tp __t) noexcept |
| 453 |
{ |
| 454 |
static_assert(__is_standard_integer<_Up>::value); |
| 455 |
static_assert(__is_standard_integer<_Tp>::value); |
| 456 |
using __gnu_cxx::__int_traits; |
| 457 |
|
| 458 |
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) |
| 459 |
return __int_traits<_Up>::__min <= __t |
| 460 |
&& __t <= __int_traits<_Up>::__max; |
| 461 |
else if constexpr (is_signed_v<_Tp>) |
| 462 |
return __t >= 0 |
| 463 |
&& make_unsigned_t<_Tp>(__t) <= __int_traits<_Up>::__max; |
| 464 |
else |
| 465 |
return __t <= make_unsigned_t<_Up>(__int_traits<_Up>::__max); |
| 466 |
} |
| 467 |
|
| 468 |
#if __cplusplus > 202002L |
| 469 |
#define __cpp_lib_to_underlying 202102L |
| 470 |
/// Convert an object of enumeration type to its underlying type. |
| 471 |
template<typename _Tp> |
| 472 |
[[nodiscard]] |
| 473 |
constexpr underlying_type_t<_Tp> |
| 474 |
to_underlying(_Tp __value) noexcept |
| 475 |
{ return static_cast<underlying_type_t<_Tp>>(__value); } |
| 476 |
#endif // C++23 |
| 477 |
#endif // C++20 |
| 478 |
#endif // C++17 |
| 479 |
|
| 480 |
_GLIBCXX_END_NAMESPACE_VERSION |
| 481 |
} // namespace |
| 482 |
|
| 483 |
#endif |
| 484 |
|
| 485 |
#endif /* _GLIBCXX_UTILITY */ |