brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.1 KiB · ff22cee Raw
266 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___MATH_TRAITS_H10#define _LIBCPP___MATH_TRAITS_H11 12#include <__config>13#include <__type_traits/enable_if.h>14#include <__type_traits/is_arithmetic.h>15#include <__type_traits/is_integral.h>16#include <__type_traits/promote.h>17 18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)19#  pragma GCC system_header20#endif21 22_LIBCPP_BEGIN_NAMESPACE_STD23 24namespace __math {25 26// signbit27 28// The universal C runtime (UCRT) in the WinSDK provides floating point overloads29// for std::signbit(). By defining our overloads as templates, we can work around30// this issue as templates are less preferred than non-template functions.31template <class = void>32[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT {33  return __builtin_signbit(__x);34}35 36template <class = void>37[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(double __x) _NOEXCEPT {38  return __builtin_signbit(__x);39}40 41template <class = void>42[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(long double __x) _NOEXCEPT {43  return __builtin_signbit(__x);44}45 46template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>47[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {48  return __x < 0;49}50 51// isfinite52 53template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>54[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {55  return true;56}57 58[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(float __x) _NOEXCEPT {59  return __builtin_isfinite(__x);60}61 62[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(double __x) _NOEXCEPT {63  return __builtin_isfinite(__x);64}65 66[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(long double __x) _NOEXCEPT {67  return __builtin_isfinite(__x);68}69 70// isinf71 72template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>73[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT {74  return false;75}76 77[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT {78  return __builtin_isinf(__x);79}80 81[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI82#ifdef _LIBCPP_PREFERRED_OVERLOAD83_LIBCPP_PREFERRED_OVERLOAD84#endif85    bool86    isinf(double __x) _NOEXCEPT {87  return __builtin_isinf(__x);88}89 90[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT {91  return __builtin_isinf(__x);92}93 94// isnan95 96template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>97[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT {98  return false;99}100 101[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT {102  return __builtin_isnan(__x);103}104 105[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI106#ifdef _LIBCPP_PREFERRED_OVERLOAD107_LIBCPP_PREFERRED_OVERLOAD108#endif109    bool110    isnan(double __x) _NOEXCEPT {111  return __builtin_isnan(__x);112}113 114[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT {115  return __builtin_isnan(__x);116}117 118// isnormal119 120template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>121[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {122  return __x != 0;123}124 125[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(float __x) _NOEXCEPT {126  return __builtin_isnormal(__x);127}128 129[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(double __x) _NOEXCEPT {130  return __builtin_isnormal(__x);131}132 133[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(long double __x) _NOEXCEPT {134  return __builtin_isnormal(__x);135}136 137// isgreater138 139template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>140[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {141  using type = __promote_t<_A1, _A2>;142  return __builtin_isgreater((type)__x, (type)__y);143}144 145// isgreaterequal146 147template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>148[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {149  using type = __promote_t<_A1, _A2>;150  return __builtin_isgreaterequal((type)__x, (type)__y);151}152 153// isless154 155template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>156[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {157  using type = __promote_t<_A1, _A2>;158  return __builtin_isless((type)__x, (type)__y);159}160 161// islessequal162 163template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>164[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {165  using type = __promote_t<_A1, _A2>;166  return __builtin_islessequal((type)__x, (type)__y);167}168 169// islessgreater170 171template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>172[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {173  using type = __promote_t<_A1, _A2>;174  return __builtin_islessgreater((type)__x, (type)__y);175}176 177// isunordered178 179template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>180[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {181  using type = __promote_t<_A1, _A2>;182  return __builtin_isunordered((type)__x, (type)__y);183}184 185// MS UCRT incorrectly defines some functions in a way not working with integer types. Until C++20, this was worked186// around by -fdelayed-template-parsing. Since C++20, we can use standard feature "requires" instead.187 188// TODO: Remove the workaround once UCRT fixes these functions. Note that this doesn't seem planned as of 2025-07 per189// https://developercommunity.visualstudio.com/t/10294165.190 191#if defined(_LIBCPP_MSVCRT) && _LIBCPP_STD_VER >= 20192namespace __ucrt {193template <class _A1>194  requires is_integral_v<_A1>195[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) noexcept {196  return true;197}198 199template <class _A1>200  requires is_integral_v<_A1>201[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) noexcept {202  return false;203}204 205template <class _A1>206  requires is_integral_v<_A1>207[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) noexcept {208  return false;209}210 211template <class _A1>212  requires is_integral_v<_A1>213[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) noexcept {214  return __x != 0;215}216 217template <class _A1, class _A2>218  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>219[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) noexcept {220  using type = __promote_t<_A1, _A2>;221  return __builtin_isgreater((type)__x, (type)__y);222}223 224template <class _A1, class _A2>225  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>226[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) noexcept {227  using type = __promote_t<_A1, _A2>;228  return __builtin_isgreaterequal((type)__x, (type)__y);229}230 231template <class _A1, class _A2>232  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>233[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) noexcept {234  using type = __promote_t<_A1, _A2>;235  return __builtin_isless((type)__x, (type)__y);236}237 238template <class _A1, class _A2>239  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>240[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) noexcept {241  using type = __promote_t<_A1, _A2>;242  return __builtin_islessequal((type)__x, (type)__y);243}244 245template <class _A1, class _A2>246  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>247[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) noexcept {248  using type = __promote_t<_A1, _A2>;249  return __builtin_islessgreater((type)__x, (type)__y);250}251 252template <class _A1, class _A2>253  requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>254[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) noexcept {255  using type = __promote_t<_A1, _A2>;256  return __builtin_isunordered((type)__x, (type)__y);257}258} // namespace __ucrt259#endif260 261} // namespace __math262 263_LIBCPP_END_NAMESPACE_STD264 265#endif // _LIBCPP___MATH_TRAITS_H266