15 Commits

Author SHA1 Message Date
Nikolas Klauser
948bffa951
[libc++] Simplify __promote (#136101)
This avoids instantiating an extra class for every variant `__promote`
is used in.
2025-05-08 16:48:57 -04:00
Nikolas Klauser
66531c998a
[libc++] Remove one of the std::signbit overloads (#130505)
We'e specialized `std::signbit` for signed and unsigned integral types
seperately, even though the optimizer can trivially figure out that
`unsigned_value < 0` always false is. This patch removes the
specialization, since there is really not much of a benefit to it.
2025-03-24 07:30:45 +01:00
Nikolas Klauser
17e0686ab1
[libc++][NFC] Use [[__nodiscard__]] unconditionally (#80454)
`__has_cpp_attribute(__nodiscard__)` is always true now, so we might as
well replace `_LIBCPP_NODISCARD`. It's one less macro that can result in
bad diagnostics.
2024-09-12 21:18:43 +02:00
Robin Caloudis
c6b2aa1896
[libc++][math] Provide overloads for cv-unqualified floating point types for std::signbit (#106566)
## Why
Following up on https://github.com/llvm/llvm-project/pull/105946, this
patch provides the floating point overloads for `std::signbit` as
defined by
[P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf).

## What
* Test and add overloads for cv-unqualified floating point types
* Remove constrained overload as it is not needed anymore
* Make use of `template<class = void>` as the universal C runtime (UCRT)
needed for Clang-Cl comes with overloads for all cv-unqualified floating
point types (float, double, long double) for `std::signbit()` by itself
[in the
WinSDK](e012b29924/generation/WinSDK/RecompiledIdlHeaders/ucrt/corecrt_math.h (L309-L322)).
In a certain way, this can be seen as a deviation from the C standard.
We need to work around it as the compilation would otherwise error out
due to duplicated definitions.
2024-09-12 21:14:00 +02:00
Robin Caloudis
1a1264726d
[libc++][math] Add constexpr for std::signbit() (#105946)
## Why
Since 18th of August, the floating point comparison builtin
``__builtin_signbit`` is available in Clang as constant expression
(https://github.com/llvm/llvm-project/pull/94118).

## What
* Implement `constexpr` for `std::signbit()` as defined by
[P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf)
(new C++23 feature)
* Restrict execution of tests to tip-of-trunk Clang as builtin is not
yet available (note that builtin is available in GCC)
2024-09-05 15:44:16 +02:00
Robin Caloudis
2f0661c211
[libc++][math] Remove constrained overloads of std::{isnan, isinf, isfinite} (#106224)
## Why
Since https://github.com/llvm/llvm-project/pull/98841 and
https://github.com/llvm/llvm-project/pull/98952, the constrained
overloads are unused and not needed anymore as we added explicit
overloads for all floating point types. I forgot to remove them in the
mentioned PRs.

## What
Remove them.
2024-08-28 12:40:26 +02:00
Robin Caloudis
866bec7d3f
[libc++][math] Provide overloads for cv-unqualified floating point types for std::isnormal (#104773)
## Why
Currently, the following does not work when compiled with clang:

```c++
#include <cmath>

struct ConvertibleToFloat {
    operator float();
};

bool test(ConvertibleToFloat x) {
    return std::isnormal(x);
}
```
See https://godbolt.org/z/5bos8v67T for differences with respect to
msvc, gcc or icx. It fails for `float`, `double` and `long double` (all
cv-unqualified floating-point types).

## What
Test and provide overloads as expected by the ISO C++ standard. The
classification/comparison function `isnormal` is defined since C++11
until C++23 as
```c++
bool isnormal( float num );
bool isnormal( double num );
bool isnormal( long double num );
```
and since C++23 as
```c++
constexpr bool isnormal( /* floating-point-type */ num );
```
for which "the library provides overloads for all cv-unqualified
floating-point types as the type of the parameter num". See §28.7.1/1 in
the [ISO C++
standard](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf)
or check
[cppreference](https://en.cppreference.com/w/cpp/numeric/math/isnormal).
2024-08-28 10:34:47 +02:00
Robin Caloudis
2fe59d5259
[libc++][math] Fix acceptance of convertible types in std::isnan() and std::isinf() (#98952)
Following up on https://github.com/llvm/llvm-project/pull/98841.

Changes:
- Properly test convertible types for `std::isnan()` and `std::inf()`
- Tighten conditional in `cmath.pass.cpp` (Find insights on `_LIBCPP_PREFERRED_OVERLOAD` below)
- Tighten preprocessor guard in `traits.h`

Insights into why `_LIBCPP_PREFERRED_OVERLOAD` is needed:

(i) When libc++ is layered on top of glibc on Linux, glibc's `math.h` is
    included. When compiling with `-std=c++03`, this header brings the
    function declaration of `isinf(double)` [1] and `isnan(double)` [2]
    into scope. This differs from the C99 Standard as only the macros
    `#define isnan(arg)` and `#define isinf(arg)` are expected.

    Therefore, libc++ needs to respect the presense of the `double` overload
    and cannot redefine it as it will conflict with the declaration already
    in scope. For `-std=c++11` and beyond this issue is fixed, as glibc
    guards both the `isinf` and `isnan` by preprocessor macros.

(ii) When libc++ is layered on top of Bionic's libc, `math.h` exposes a
     function prototype for `isinf(double)` with return type `int`. This
     function prototype in Bionic's libc is not guarded by any preprocessor
     macros [3].

`_LIBCPP_PREFERRED_OVERLOAD` specifies that a given overload is a better match
than an otherwise equally good function declaration. This is implemented in
modern versions of Clang via `__attribute__((__enable_if__))`, and not elsewhere.
See [4] for details. We use `_LIBCPP_PREFERRED_OVERLOAD` to define overloads in
the global namespace that displace the overloads provided by the C
libraries mentioned above.

[1]: fe94080875/math/bits/mathcalls.h (L185-L194)
[2]: fe94080875/math/bits/mathcalls.h (L222-L231)
[3]: https://cs.android.com/android/platform/superproject/+/master:bionic/libc/include/math.h;l=322-323;drc=master?hl=fr-BE%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22
[4]: 5fd17ab1b0
2024-08-16 11:18:49 -04:00
Robin Caloudis
7f2bd53b14
[libc++] Fix acceptance of convertible-to-{float,double,long double} in std::isfinite() (#98841)
Closes https://github.com/llvm/llvm-project/issues/98816.
2024-07-18 09:01:09 -04:00
Nikolas Klauser
83bc7b5771
[libc++] Remove _LIBCPP_DISABLE_NODISCARD_EXTENSIONS and refactor the tests (#87094)
This also adds a few tests that were missing.
2024-04-22 22:13:58 +02:00
Nikolas Klauser
dcdcc7c804 [libc++][NFC] Replace typedefs with using in the math headers
Reviewed By: #libc, Mordante, ldionne

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155382
2023-08-03 08:51:50 -07:00
Nikolas Klauser
f3589d25fe [libc++][NFC] Refactor the enable_ifs in the math headers
Reviewed By: #libc, Mordante

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155261
2023-08-02 10:03:32 -07:00
Nikolas Klauser
0e4d812f3e [libc++][NFC] Format math headers
Reviewed By: #libc, Mordante

Spies: arichardson, Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155260
2023-07-31 17:19:49 -07:00
Nikolas Klauser
404d31196f [libc++][NFC] Remove std:: qualifications from math headers
Reviewed By: #libc, Mordante

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155259
2023-07-31 17:19:44 -07:00
Nikolas Klauser
6553608aca [libc++] Granulaize math.h and move the functions to std::__math
Reviewed By: #libc, Mordante

Spies: Mordante, arichardson, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155258
2023-07-31 17:19:39 -07:00