1 1.1 mrg // <utility> -*- C++ -*- 2 1.1 mrg 3 1.1.1.15 mrg // Copyright (C) 2001-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /* 26 1.1 mrg * 27 1.1 mrg * Copyright (c) 1994 28 1.1 mrg * Hewlett-Packard Company 29 1.1 mrg * 30 1.1 mrg * Permission to use, copy, modify, distribute and sell this software 31 1.1 mrg * and its documentation for any purpose is hereby granted without fee, 32 1.1 mrg * provided that the above copyright notice appear in all copies and 33 1.1 mrg * that both that copyright notice and this permission notice appear 34 1.1 mrg * in supporting documentation. Hewlett-Packard Company makes no 35 1.1 mrg * representations about the suitability of this software for any 36 1.1 mrg * purpose. It is provided "as is" without express or implied warranty. 37 1.1 mrg * 38 1.1 mrg * 39 1.1 mrg * Copyright (c) 1996,1997 40 1.1 mrg * Silicon Graphics Computer Systems, Inc. 41 1.1 mrg * 42 1.1 mrg * Permission to use, copy, modify, distribute and sell this software 43 1.1 mrg * and its documentation for any purpose is hereby granted without fee, 44 1.1 mrg * provided that the above copyright notice appear in all copies and 45 1.1 mrg * that both that copyright notice and this permission notice appear 46 1.1 mrg * in supporting documentation. Silicon Graphics makes no 47 1.1 mrg * representations about the suitability of this software for any 48 1.1 mrg * purpose. It is provided "as is" without express or implied warranty. 49 1.1 mrg */ 50 1.1 mrg 51 1.1 mrg /** @file include/utility 52 1.1.1.7 mrg * This is a Standard C++ Library header. 53 1.1 mrg */ 54 1.1 mrg 55 1.1 mrg #ifndef _GLIBCXX_UTILITY 56 1.1 mrg #define _GLIBCXX_UTILITY 1 57 1.1 mrg 58 1.1 mrg #pragma GCC system_header 59 1.1 mrg 60 1.1 mrg /** 61 1.1 mrg * @defgroup utilities Utilities 62 1.1 mrg * 63 1.1.1.13 mrg * Basic function and class templates used with the rest of the library. 64 1.1.1.13 mrg * Includes pair, swap, forward/move helpers, declval, integer_sequence. 65 1.1 mrg */ 66 1.1 mrg 67 1.1 mrg #include <bits/c++config.h> 68 1.1 mrg #include <bits/stl_relops.h> 69 1.1 mrg #include <bits/stl_pair.h> 70 1.1 mrg 71 1.1.1.2 mrg #if __cplusplus >= 201103L 72 1.1.1.3 mrg 73 1.1.1.13 mrg #include <initializer_list> 74 1.1.1.5 mrg #include <type_traits> 75 1.1.1.2 mrg #include <bits/move.h> 76 1.1.1.13 mrg #include <bits/utility.h> 77 1.1.1.2 mrg 78 1.1.1.13 mrg #if __cplusplus >= 202002L 79 1.1.1.13 mrg #include <ext/numeric_traits.h> // __is_standard_integer, __int_traits 80 1.1.1.12 mrg #endif 81 1.1.1.12 mrg 82 1.1.1.15 mrg #define __glibcxx_want_addressof_constexpr 83 1.1.1.15 mrg #define __glibcxx_want_as_const 84 1.1.1.15 mrg #define __glibcxx_want_constexpr_algorithms 85 1.1.1.15 mrg #define __glibcxx_want_constexpr_utility 86 1.1.1.15 mrg #define __glibcxx_want_exchange_function 87 1.1.1.15 mrg #define __glibcxx_want_forward_like 88 1.1.1.15 mrg #define __glibcxx_want_integer_comparison_functions 89 1.1.1.15 mrg #define __glibcxx_want_integer_sequence 90 1.1.1.15 mrg #define __glibcxx_want_ranges_zip 91 1.1.1.15 mrg #define __glibcxx_want_to_underlying 92 1.1.1.15 mrg #define __glibcxx_want_tuple_element_t 93 1.1.1.15 mrg #define __glibcxx_want_tuples_by_type 94 1.1.1.15 mrg #define __glibcxx_want_unreachable 95 1.1.1.15 mrg #define __glibcxx_want_tuple_like 96 1.1.1.15 mrg #include <bits/version.h> 97 1.1.1.15 mrg 98 1.1.1.2 mrg namespace std _GLIBCXX_VISIBILITY(default) 99 1.1.1.2 mrg { 100 1.1.1.2 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 101 1.1.1.2 mrg 102 1.1.1.15 mrg #ifdef __cpp_lib_exchange_function // C++ >= 14 103 1.1.1.3 mrg /// Assign @p __new_val to @p __obj and return its previous value. 104 1.1.1.3 mrg template <typename _Tp, typename _Up = _Tp> 105 1.1.1.12 mrg _GLIBCXX20_CONSTEXPR 106 1.1.1.3 mrg inline _Tp 107 1.1.1.3 mrg exchange(_Tp& __obj, _Up&& __new_val) 108 1.1.1.13 mrg noexcept(__and_<is_nothrow_move_constructible<_Tp>, 109 1.1.1.13 mrg is_nothrow_assignable<_Tp&, _Up>>::value) 110 1.1.1.3 mrg { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } 111 1.1.1.15 mrg #endif 112 1.1.1.12 mrg 113 1.1.1.15 mrg #ifdef __cpp_lib_as_const // C++ >= 17 114 1.1.1.7 mrg template<typename _Tp> 115 1.1.1.13 mrg [[nodiscard]] 116 1.1.1.13 mrg constexpr add_const_t<_Tp>& 117 1.1.1.13 mrg as_const(_Tp& __t) noexcept 118 1.1.1.13 mrg { return __t; } 119 1.1.1.7 mrg 120 1.1.1.7 mrg template<typename _Tp> 121 1.1.1.7 mrg void as_const(const _Tp&&) = delete; 122 1.1.1.15 mrg #endif 123 1.1.1.7 mrg 124 1.1.1.15 mrg #ifdef __cpp_lib_integer_comparison_functions // C++ >= 20 125 1.1.1.12 mrg template<typename _Tp, typename _Up> 126 1.1.1.12 mrg constexpr bool 127 1.1.1.12 mrg cmp_equal(_Tp __t, _Up __u) noexcept 128 1.1.1.12 mrg { 129 1.1.1.12 mrg static_assert(__is_standard_integer<_Tp>::value); 130 1.1.1.12 mrg static_assert(__is_standard_integer<_Up>::value); 131 1.1.1.12 mrg 132 1.1.1.12 mrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) 133 1.1.1.12 mrg return __t == __u; 134 1.1.1.12 mrg else if constexpr (is_signed_v<_Tp>) 135 1.1.1.12 mrg return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u; 136 1.1.1.12 mrg else 137 1.1.1.12 mrg return __u >= 0 && __t == make_unsigned_t<_Up>(__u); 138 1.1.1.12 mrg } 139 1.1.1.12 mrg 140 1.1.1.12 mrg template<typename _Tp, typename _Up> 141 1.1.1.12 mrg constexpr bool 142 1.1.1.12 mrg cmp_not_equal(_Tp __t, _Up __u) noexcept 143 1.1.1.12 mrg { return !std::cmp_equal(__t, __u); } 144 1.1.1.12 mrg 145 1.1.1.12 mrg template<typename _Tp, typename _Up> 146 1.1.1.12 mrg constexpr bool 147 1.1.1.12 mrg cmp_less(_Tp __t, _Up __u) noexcept 148 1.1.1.12 mrg { 149 1.1.1.12 mrg static_assert(__is_standard_integer<_Tp>::value); 150 1.1.1.12 mrg static_assert(__is_standard_integer<_Up>::value); 151 1.1.1.12 mrg 152 1.1.1.12 mrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) 153 1.1.1.12 mrg return __t < __u; 154 1.1.1.12 mrg else if constexpr (is_signed_v<_Tp>) 155 1.1.1.12 mrg return __t < 0 || make_unsigned_t<_Tp>(__t) < __u; 156 1.1.1.12 mrg else 157 1.1.1.12 mrg return __u >= 0 && __t < make_unsigned_t<_Up>(__u); 158 1.1.1.12 mrg } 159 1.1.1.12 mrg 160 1.1.1.12 mrg template<typename _Tp, typename _Up> 161 1.1.1.12 mrg constexpr bool 162 1.1.1.12 mrg cmp_greater(_Tp __t, _Up __u) noexcept 163 1.1.1.12 mrg { return std::cmp_less(__u, __t); } 164 1.1.1.12 mrg 165 1.1.1.12 mrg template<typename _Tp, typename _Up> 166 1.1.1.12 mrg constexpr bool 167 1.1.1.12 mrg cmp_less_equal(_Tp __t, _Up __u) noexcept 168 1.1.1.12 mrg { return !std::cmp_less(__u, __t); } 169 1.1.1.12 mrg 170 1.1.1.12 mrg template<typename _Tp, typename _Up> 171 1.1.1.12 mrg constexpr bool 172 1.1.1.12 mrg cmp_greater_equal(_Tp __t, _Up __u) noexcept 173 1.1.1.12 mrg { return !std::cmp_less(__t, __u); } 174 1.1.1.12 mrg 175 1.1.1.14 mrg template<typename _Res, typename _Tp> 176 1.1.1.12 mrg constexpr bool 177 1.1.1.12 mrg in_range(_Tp __t) noexcept 178 1.1.1.12 mrg { 179 1.1.1.14 mrg static_assert(__is_standard_integer<_Res>::value); 180 1.1.1.12 mrg static_assert(__is_standard_integer<_Tp>::value); 181 1.1.1.12 mrg using __gnu_cxx::__int_traits; 182 1.1.1.12 mrg 183 1.1.1.14 mrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Res>) 184 1.1.1.14 mrg return __int_traits<_Res>::__min <= __t 185 1.1.1.14 mrg && __t <= __int_traits<_Res>::__max; 186 1.1.1.12 mrg else if constexpr (is_signed_v<_Tp>) 187 1.1.1.12 mrg return __t >= 0 188 1.1.1.14 mrg && make_unsigned_t<_Tp>(__t) <= __int_traits<_Res>::__max; 189 1.1.1.12 mrg else 190 1.1.1.14 mrg return __t <= make_unsigned_t<_Res>(__int_traits<_Res>::__max); 191 1.1.1.12 mrg } 192 1.1.1.15 mrg #endif // __cpp_lib_integer_comparison_functions 193 1.1.1.13 mrg 194 1.1.1.15 mrg #ifdef __cpp_lib_to_underlying // C++ >= 23 195 1.1.1.13 mrg /// Convert an object of enumeration type to its underlying type. 196 1.1.1.13 mrg template<typename _Tp> 197 1.1.1.13 mrg [[nodiscard]] 198 1.1.1.13 mrg constexpr underlying_type_t<_Tp> 199 1.1.1.13 mrg to_underlying(_Tp __value) noexcept 200 1.1.1.13 mrg { return static_cast<underlying_type_t<_Tp>>(__value); } 201 1.1.1.15 mrg #endif 202 1.1.1.13 mrg 203 1.1.1.15 mrg #ifdef __cpp_lib_unreachable // C++ >= 23 204 1.1.1.13 mrg /// Informs the compiler that program control flow never reaches this point. 205 1.1.1.13 mrg /** 206 1.1.1.13 mrg * Evaluating a call to this function results in undefined behaviour. 207 1.1.1.13 mrg * This can be used as an assertion informing the compiler that certain 208 1.1.1.13 mrg * conditions are impossible, for when the compiler is unable to determine 209 1.1.1.13 mrg * that by itself. 210 1.1.1.13 mrg * 211 1.1.1.13 mrg * For example, it can be used to prevent warnings about reaching the 212 1.1.1.13 mrg * end of a non-void function without returning. 213 1.1.1.13 mrg * 214 1.1.1.13 mrg * @since C++23 215 1.1.1.13 mrg */ 216 1.1.1.13 mrg [[noreturn,__gnu__::__always_inline__]] 217 1.1.1.13 mrg inline void 218 1.1.1.13 mrg unreachable() 219 1.1.1.13 mrg { 220 1.1.1.13 mrg #ifdef _GLIBCXX_DEBUG 221 1.1.1.13 mrg std::__glibcxx_assert_fail(nullptr, 0, "std::unreachable()", nullptr); 222 1.1.1.13 mrg #elif defined _GLIBCXX_ASSERTIONS 223 1.1.1.13 mrg __builtin_trap(); 224 1.1.1.13 mrg #else 225 1.1.1.13 mrg __builtin_unreachable(); 226 1.1.1.13 mrg #endif 227 1.1.1.13 mrg } 228 1.1.1.15 mrg #endif 229 1.1.1.7 mrg 230 1.1.1.2 mrg _GLIBCXX_END_NAMESPACE_VERSION 231 1.1.1.2 mrg } // namespace 232 1.1.1.2 mrg 233 1.1 mrg #endif 234 1.1 mrg 235 1.1 mrg #endif /* _GLIBCXX_UTILITY */ 236