[libcxx-commits] [libcxx] [libc++][math] Add `constexpr` for `std::signbit()` (PR #105946)

Robin Caloudis via libcxx-commits libcxx-commits at lists.llvm.org
Wed Aug 28 23:15:51 PDT 2024


================
@@ -29,17 +29,64 @@ namespace __math {
 // signbit
 
 template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0>
-_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
+// TODO(LLVM 22): Remove `__builtin_copysign`-workaround once support for Clang 19 is dropped.
+#if !__has_constexpr_builtin(__builtin_signbit) && _LIBCPP_STD_VER >= 23
+  return __builtin_copysign(1.0, __x) == -1.0;
+#else
   return __builtin_signbit(__x);
+#endif
+}
+
+_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
+#ifdef _LIBCPP_PREFERRED_OVERLOAD
+_LIBCPP_PREFERRED_OVERLOAD
+#endif
----------------
robincaloudis wrote:

Good point. `_LIBCPP_PREFERRED_OVERLOAD` was added in order to work around the already provided fp overloads in the [WinSDK](https://github.com/microsoft/win32metadata/blob/e012b29924c53aa941fc010850b68331b0c3ea80/generation/WinSDK/RecompiledIdlHeaders/ucrt/corecrt_math.h#L309-L322), not for kind-of-support `constexpr`-support for windows. Compilation would otherwise error out due to duplicated definitions. See for example:

```bash
D:\a\llvm-project\llvm-project\build\clang-cl-debug\include\c++\v1\math.h(415,20): error: target of using declaration conflicts with declaration already in scope
  415 | using std::__math::signbit;
      |                    ^
D:\a\llvm-project\llvm-project\build\clang-cl-debug\include\c++\v1\__math/traits.h(41,83): note: target of using declaration
   41 | _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT {
      |                                                                                   ^
C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt\corecrt_math.h(309,32): note: conflicting declaration
  309 |     _Check_return_ inline bool signbit(_In_ float _X) throw()
```
(https://github.com/llvm/llvm-project/actions/runs/10541183450/job/29206893262?pr=105946)

Perhaps, we doesn't hit the same issue for `signbit` as templates are less preferred than non-template functions. Right now, I cannot think of a different way to provide the `signbit` overloads for floating point types `float, double, long double` in `libstdc++`. Can you think of a better mechanism? 

https://github.com/llvm/llvm-project/pull/105946


More information about the libcxx-commits mailing list