190 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___CXX03___MATH_TRAITS_H10#define _LIBCPP___CXX03___MATH_TRAITS_H11 12#include <__cxx03/__config>13#include <__cxx03/__type_traits/enable_if.h>14#include <__cxx03/__type_traits/is_arithmetic.h>15#include <__cxx03/__type_traits/is_integral.h>16#include <__cxx03/__type_traits/is_signed.h>17#include <__cxx03/__type_traits/promote.h>18#include <__cxx03/limits>19 20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)21# pragma GCC system_header22#endif23 24_LIBCPP_BEGIN_NAMESPACE_STD25 26namespace __math {27 28// signbit29 30// The universal C runtime (UCRT) in the WinSDK provides floating point overloads31// for std::signbit(). By defining our overloads as templates, we can work around32// this issue as templates are less preferred than non-template functions.33template <class = void>34_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT {35 return __builtin_signbit(__x);36}37 38template <class = void>39_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(double __x) _NOEXCEPT {40 return __builtin_signbit(__x);41}42 43template <class = void>44_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(long double __x) _NOEXCEPT {45 return __builtin_signbit(__x);46}47 48template <class _A1, __enable_if_t<is_integral<_A1>::value && is_signed<_A1>::value, int> = 0>49_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {50 return __x < 0;51}52 53template <class _A1, __enable_if_t<is_integral<_A1>::value && !is_signed<_A1>::value, int> = 0>54_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT {55 return false;56}57 58// isfinite59 60template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0>61_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT {62 return __builtin_isfinite((typename __promote<_A1>::type)__x);63}64 65template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0>66_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {67 return true;68}69 70_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isfinite(float __x) _NOEXCEPT { return __builtin_isfinite(__x); }71 72_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isfinite(double __x) _NOEXCEPT { return __builtin_isfinite(__x); }73 74_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isfinite(long double __x) _NOEXCEPT {75 return __builtin_isfinite(__x);76}77 78// isinf79 80template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0>81_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT {82 return __builtin_isinf((typename __promote<_A1>::type)__x);83}84 85template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0>86_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT {87 return false;88}89 90#ifdef _LIBCPP_PREFERRED_OVERLOAD91_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); }92 93_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT {94 return __builtin_isinf(__x);95}96 97_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); }98#endif99 100// isnan101 102template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0>103_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT {104 return __builtin_isnan(__x);105}106 107template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>108_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT {109 return false;110}111 112#ifdef _LIBCPP_PREFERRED_OVERLOAD113_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); }114 115_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT {116 return __builtin_isnan(__x);117}118 119_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); }120#endif121 122// isnormal123 124template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>125_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {126 return __x != 0;127}128 129_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isnormal(float __x) _NOEXCEPT { return __builtin_isnormal(__x); }130 131_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isnormal(double __x) _NOEXCEPT { return __builtin_isnormal(__x); }132 133_LIBCPP_NODISCARD inline _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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {141 using type = typename __promote<_A1, _A2>::type;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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {149 using type = typename __promote<_A1, _A2>::type;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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {157 using type = typename __promote<_A1, _A2>::type;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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {165 using type = typename __promote<_A1, _A2>::type;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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {173 using type = typename __promote<_A1, _A2>::type;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_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {181 using type = typename __promote<_A1, _A2>::type;182 return __builtin_isunordered((type)__x, (type)__y);183}184 185} // namespace __math186 187_LIBCPP_END_NAMESPACE_STD188 189#endif // _LIBCPP___CXX03___MATH_TRAITS_H190