traits.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef _LIBCPP___MATH_TRAITS_H
  9. #define _LIBCPP___MATH_TRAITS_H
  10. #include <__config>
  11. #include <__type_traits/enable_if.h>
  12. #include <__type_traits/is_arithmetic.h>
  13. #include <__type_traits/is_floating_point.h>
  14. #include <__type_traits/is_integral.h>
  15. #include <__type_traits/is_signed.h>
  16. #include <__type_traits/promote.h>
  17. #include <limits>
  18. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  19. # pragma GCC system_header
  20. #endif
  21. _LIBCPP_BEGIN_NAMESPACE_STD
  22. namespace __math {
  23. // signbit
  24. template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0>
  25. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
  26. return __builtin_signbit(__x);
  27. }
  28. template <class _A1, __enable_if_t<is_integral<_A1>::value && is_signed<_A1>::value, int> = 0>
  29. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
  30. return __x < 0;
  31. }
  32. template <class _A1, __enable_if_t<is_integral<_A1>::value && !is_signed<_A1>::value, int> = 0>
  33. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT {
  34. return false;
  35. }
  36. // isfinite
  37. template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0>
  38. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT {
  39. return __builtin_isfinite((typename __promote<_A1>::type)__x);
  40. }
  41. template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0>
  42. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {
  43. return true;
  44. }
  45. // isinf
  46. template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0>
  47. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT {
  48. return __builtin_isinf((typename __promote<_A1>::type)__x);
  49. }
  50. template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0>
  51. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT {
  52. return false;
  53. }
  54. #ifdef _LIBCPP_PREFERRED_OVERLOAD && !defined(__CUDACC__)
  55. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT {
  56. return __builtin_isinf(__x);
  57. }
  58. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool
  59. isinf(double __x) _NOEXCEPT {
  60. return __builtin_isinf(__x);
  61. }
  62. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT {
  63. return __builtin_isinf(__x);
  64. }
  65. #endif
  66. // isnan
  67. template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0>
  68. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT {
  69. return __builtin_isnan(__x);
  70. }
  71. template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
  72. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT {
  73. return false;
  74. }
  75. #ifdef _LIBCPP_PREFERRED_OVERLOAD && !defined(__CUDACC__)
  76. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT {
  77. return __builtin_isnan(__x);
  78. }
  79. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool
  80. isnan(double __x) _NOEXCEPT {
  81. return __builtin_isnan(__x);
  82. }
  83. _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT {
  84. return __builtin_isnan(__x);
  85. }
  86. #endif
  87. // isnormal
  88. template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0>
  89. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
  90. return __builtin_isnormal(__x);
  91. }
  92. template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
  93. _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
  94. return __x != 0;
  95. }
  96. // isgreater
  97. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  98. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {
  99. using type = typename __promote<_A1, _A2>::type;
  100. return __builtin_isgreater((type)__x, (type)__y);
  101. }
  102. // isgreaterequal
  103. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  104. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {
  105. using type = typename __promote<_A1, _A2>::type;
  106. return __builtin_isgreaterequal((type)__x, (type)__y);
  107. }
  108. // isless
  109. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  110. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {
  111. using type = typename __promote<_A1, _A2>::type;
  112. return __builtin_isless((type)__x, (type)__y);
  113. }
  114. // islessequal
  115. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  116. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {
  117. using type = typename __promote<_A1, _A2>::type;
  118. return __builtin_islessequal((type)__x, (type)__y);
  119. }
  120. // islessgreater
  121. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  122. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {
  123. using type = typename __promote<_A1, _A2>::type;
  124. return __builtin_islessgreater((type)__x, (type)__y);
  125. }
  126. // isunordered
  127. template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
  128. _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {
  129. using type = typename __promote<_A1, _A2>::type;
  130. return __builtin_isunordered((type)__x, (type)__y);
  131. }
  132. } // namespace __math
  133. _LIBCPP_END_NAMESPACE_STD
  134. #endif // _LIBCPP___MATH_TRAITS_H