diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -226,6 +226,12 @@ __chrono/year_month.h __chrono/year_month_day.h __chrono/year_month_weekday.h + __cmath/compare.h + __cmath/isfinite.h + __cmath/isinf.h + __cmath/isnan.h + __cmath/isnormal.h + __cmath/signbit.h __compare/common_comparison_category.h __compare/compare_partial_order_fallback.h __compare/compare_strong_order_fallback.h diff --git a/libcxx/include/__cmath/compare.h b/libcxx/include/__cmath/compare.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/compare.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_COMPARE_H +#define _LIBCPP___CMATH_COMPARE_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_arithmetic.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isless(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_isless(__lhs, __rhs); +} + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool islessequal(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_islessequal(__lhs, __rhs); +} + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool islessgreater(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_islessgreater(__lhs, __rhs); +} + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_isgreaterequal(__lhs, __rhs); +} + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isgreater(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_isgreater(__lhs, __rhs); +} + +template ::value && std::is_arithmetic<_Up>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isunordered(_Tp __lhs, _Up __rhs) _NOEXCEPT { + return __builtin_isunordered(__lhs, __rhs); +} + +#endif // _LIBCPP___CMATH_COMPARE_H diff --git a/libcxx/include/__cmath/isfinite.h b/libcxx/include/__cmath/isfinite.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/isfinite.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_ISFINITE_H +#define _LIBCPP___CMATH_ISFINITE_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_arithmetic.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value && std::numeric_limits<_Tp>::has_infinity, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI bool isfinite(_Tp __lcpp_x) _NOEXCEPT { + return __builtin_isfinite(__lcpp_x); +} + +template ::value && !std::numeric_limits<_Tp>::has_infinity, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI bool isfinite(_Tp) _NOEXCEPT { + return true; +} + +#endif // _LIBCPP___CMATH_ISFINITE_H diff --git a/libcxx/include/__cmath/isinf.h b/libcxx/include/__cmath/isinf.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/isinf.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_ISINF_H +#define _LIBCPP___CMATH_ISINF_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_arithmetic.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value && std::numeric_limits<_Tp>::has_infinity, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isinf(_Tp __v) _NOEXCEPT { + return __builtin_isinf(__v); +} + +template ::value && !std::numeric_limits<_Tp>::has_infinity, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isinf(_Tp) _NOEXCEPT { + return false; +} + +#endif // _LIBCPP___CMATH_ISINF_H diff --git a/libcxx/include/__cmath/isnan.h b/libcxx/include/__cmath/isnan.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/isnan.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_ISNAN_H +#define _LIBCPP___CMATH_ISNAN_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isnan(_Tp __v) _NOEXCEPT { + return __builtin_isnan(__v); +} + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isnan(_Tp) _NOEXCEPT { + return false; +} + +#endif // _LIBCPP___CMATH_ISNAN_H diff --git a/libcxx/include/__cmath/isnormal.h b/libcxx/include/__cmath/isnormal.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/isnormal.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_ISNORMAL_H +#define _LIBCPP___CMATH_ISNORMAL_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isnormal(_Tp __v) _NOEXCEPT { + return __builtin_isnormal(__v); +} + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool isnormal(_Tp __v) _NOEXCEPT { + return __v != 0; +} + +#endif // _LIBCPP___CMATH_ISNORMAL_H diff --git a/libcxx/include/__cmath/signbit.h b/libcxx/include/__cmath/signbit.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__cmath/signbit.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CMATH_SIGNBIT_H +#define _LIBCPP___CMATH_SIGNBIT_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> +#include <__type_traits/is_signed.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool signbit(_Tp __v) _NOEXCEPT { + return __builtin_signbit(__v); +} + +template ::value && std::is_signed<_Tp>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool signbit(_Tp __v) _NOEXCEPT { + return __v < 0; +} + +template ::value && !std::is_signed<_Tp>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool signbit(_Tp) _NOEXCEPT { + return false; +} + +#endif // _LIBCPP___CMATH_SIGNBIT_H diff --git a/libcxx/include/math.h b/libcxx/include/math.h --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -299,82 +299,66 @@ #include_next -#ifdef __cplusplus - -// We support including .h headers inside 'extern "C"' contexts, so switch -// back to C++ linkage before including these C++ headers. -extern "C++" { +#ifdef isless +# undef isless +#endif -#include <__type_traits/promote.h> -#include -#include -#include +#ifdef islessequal +# undef islessequal +#endif -// signbit +#ifdef islessgreater +# undef islessgreater +#endif -#ifdef signbit +#ifdef isgreaterequal +# undef isgreaterequal +#endif -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT -{ -#if __has_builtin(__builtin_signbit) - return __builtin_signbit(__lcpp_x); -#else - return signbit(__lcpp_x); +#ifdef isgreater +# undef isgreater #endif -} -#undef signbit +#ifdef isunordered +# undef isunordered +#endif -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -signbit(_A1 __lcpp_x) _NOEXCEPT -{ - return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x); -} +#ifdef isfinite +# undef isfinite +#endif -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_integral<_A1>::value && std::is_signed<_A1>::value, bool>::type -signbit(_A1 __lcpp_x) _NOEXCEPT -{ return __lcpp_x < 0; } +#ifdef isinf +# undef isinf +#endif -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_integral<_A1>::value && !std::is_signed<_A1>::value, bool>::type -signbit(_A1) _NOEXCEPT -{ return false; } +#ifdef isnan +# undef isnan +#endif -#elif defined(_LIBCPP_MSVCRT) +#ifdef isnormal +# undef isnormal +#endif -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -signbit(_A1 __lcpp_x) _NOEXCEPT -{ - return ::signbit(static_cast::type>(__lcpp_x)); -} +#ifdef signbit +# undef signbit +#endif -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_integral<_A1>::value && std::is_signed<_A1>::value, bool>::type -signbit(_A1 __lcpp_x) _NOEXCEPT -{ return __lcpp_x < 0; } +#ifdef __cplusplus -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_integral<_A1>::value && !std::is_signed<_A1>::value, bool>::type -signbit(_A1) _NOEXCEPT -{ return false; } +// We support including .h headers inside 'extern "C"' contexts, so switch +// back to C++ linkage before including these C++ headers. +extern "C++" { +#include <__cmath/compare.h> +#include <__cmath/isfinite.h> +#include <__cmath/isinf.h> +#include <__cmath/isnan.h> +#include <__cmath/isnormal.h> +#include <__cmath/signbit.h> -#endif // signbit +#include <__type_traits/promote.h> +#include +#include +#include // fpclassify @@ -427,358 +411,6 @@ #endif // fpclassify -// isfinite - -#ifdef isfinite - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT -{ -#if __has_builtin(__builtin_isfinite) - return __builtin_isfinite(__lcpp_x); -#else - return isfinite(__lcpp_x); -#endif -} - -#undef isfinite - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, - bool>::type -isfinite(_A1 __lcpp_x) _NOEXCEPT -{ - return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_arithmetic<_A1>::value && !std::numeric_limits<_A1>::has_infinity, - bool>::type -isfinite(_A1) _NOEXCEPT -{ return true; } - -#endif // isfinite - -// isinf - -#ifdef isinf - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT -{ -#if __has_builtin(__builtin_isinf) - return __builtin_isinf(__lcpp_x); -#else - return isinf(__lcpp_x); -#endif -} - -#undef isinf - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, - bool>::type -isinf(_A1 __lcpp_x) _NOEXCEPT -{ - return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if< - std::is_arithmetic<_A1>::value && !std::numeric_limits<_A1>::has_infinity, - bool>::type -isinf(_A1) _NOEXCEPT -{ return false; } - -#ifdef _LIBCPP_PREFERRED_OVERLOAD -inline _LIBCPP_INLINE_VISIBILITY -bool -isinf(float __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); } - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD -bool -isinf(double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); } - -inline _LIBCPP_INLINE_VISIBILITY -bool -isinf(long double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); } -#endif - -#endif // isinf - -// isnan - -#ifdef isnan - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT -{ -#if __has_builtin(__builtin_isnan) - return __builtin_isnan(__lcpp_x); -#else - return isnan(__lcpp_x); -#endif -} - -#undef isnan - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -isnan(_A1 __lcpp_x) _NOEXCEPT -{ - return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -isnan(_A1) _NOEXCEPT -{ return false; } - -#ifdef _LIBCPP_PREFERRED_OVERLOAD -inline _LIBCPP_INLINE_VISIBILITY -bool -isnan(float __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); } - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD -bool -isnan(double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); } - -inline _LIBCPP_INLINE_VISIBILITY -bool -isnan(long double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); } -#endif - -#endif // isnan - -// isnormal - -#ifdef isnormal - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT -{ -#if __has_builtin(__builtin_isnormal) - return __builtin_isnormal(__lcpp_x); -#else - return isnormal(__lcpp_x); -#endif -} - -#undef isnormal - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -isnormal(_A1 __lcpp_x) _NOEXCEPT -{ - return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type -isnormal(_A1 __lcpp_x) _NOEXCEPT -{ return __lcpp_x != 0; } - -#endif // isnormal - -// isgreater - -#ifdef isgreater - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return isgreater(__lcpp_x, __lcpp_y); -} - -#undef isgreater - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // isgreater - -// isgreaterequal - -#ifdef isgreaterequal - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return isgreaterequal(__lcpp_x, __lcpp_y); -} - -#undef isgreaterequal - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // isgreaterequal - -// isless - -#ifdef isless - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return isless(__lcpp_x, __lcpp_y); -} - -#undef isless - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // isless - -// islessequal - -#ifdef islessequal - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return islessequal(__lcpp_x, __lcpp_y); -} - -#undef islessequal - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // islessequal - -// islessgreater - -#ifdef islessgreater - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return islessgreater(__lcpp_x, __lcpp_y); -} - -#undef islessgreater - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // islessgreater - -// isunordered - -#ifdef isunordered - -template -_LIBCPP_INLINE_VISIBILITY -bool -__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - return isunordered(__lcpp_x, __lcpp_y); -} - -#undef isunordered - -template -inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if -< - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value, - bool ->::type -isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT -{ - typedef typename std::__promote<_A1, _A2>::type type; - return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y); -} - -#endif // isunordered - // abs // // handled in stdlib.h diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -169,6 +169,15 @@ module cmath { header "cmath" export * + + module __cmath { + module compare { private header "__cmath/compare.h" } + module isfinite { private header "__cmath/isfinite.h" } + module isinf { private header "__cmath/isinf.h" } + module isnan { private header "__cmath/isnan.h" } + module isnormal { private header "__cmath/isnormal.h" } + module signbit { private header "__cmath/signbit.h" } + } } module csetjmp { header "csetjmp"