[libcxx-commits] [PATCH] D79555: [libc++] [P0415] [C++20] - Constexpr for std::complex.
Marek Kurdej via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Nov 7 12:53:37 PST 2020
curdeius updated this revision to Diff 303663.
curdeius added a comment.
Fix edge cases. Fix operator* and operator/.
Use "shortcuts" to avoid NaN in constexpr evaluation (disallowed).
One remaining problem.
2 tests:
- complex_divides_complex.pass.cpp
- complex_times_complex.pass.cpp
do not pass on clang unless additional parameter `--param=compile_flags='-fconstexpr-steps=4000000'` is given.
That's because they test all the edge cases and each pair thereof and clang has too low a limit for the maximum number of constexpr execution steps.
I thought about splitting these tests somehow but given their (combinatoric) nature, it's pretty awkward.
I don't know how I should pass this compile flag only for these tests and only for clang (I know of ADDITIONAL_COMPILE_FLAGS but I cannot exclude gcc with that).
TODO:
- Test (at least locally) a different floating-point type (e.g. float128) to catch missing constexpr markers in the default implementation (non-specialization).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79555/new/
https://reviews.llvm.org/D79555
Files:
libcxx/include/complex
Index: libcxx/include/complex
===================================================================
--- libcxx/include/complex
+++ libcxx/include/complex
@@ -881,6 +881,45 @@
__d = scalbn(__d, -__ilogbw);
}
}
+ if (__libcpp_is_constant_evaluated()) {
+ bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
+ bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
+ bool __z_inf = __libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b);
+ bool __w_inf = __libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d);
+ bool __z_nan = !__z_inf && (
+ (__libcpp_isnan_or_builtin(__a) && __libcpp_isnan_or_builtin(__b))
+ || (__libcpp_isnan_or_builtin(__a) && __b == _Tp(0))
+ || (__a == _Tp(0) && __libcpp_isnan_or_builtin(__b))
+ );
+ bool __w_nan = !__w_inf && (
+ (__libcpp_isnan_or_builtin(__c) && __libcpp_isnan_or_builtin(__d))
+ || (__libcpp_isnan_or_builtin(__c) && __d == _Tp(0))
+ || (__c == _Tp(0) && __libcpp_isnan_or_builtin(__d))
+ );
+ if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) {
+ return complex<_Tp>(_Tp(NAN), _Tp(0));
+ }
+ bool __z_nonzero_nan = !__z_inf && !__z_nan && (__libcpp_isnan_or_builtin(__a) || __libcpp_isnan_or_builtin(__b));
+ bool __w_nonzero_nan = !__w_inf && !__w_nan && (__libcpp_isnan_or_builtin(__c) || __libcpp_isnan_or_builtin(__d));
+ if (__z_nonzero_nan || __w_nonzero_nan) {
+ if (__w_zero) {
+ return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY));
+ }
+ return complex<_Tp>(_Tp(NAN), _Tp(0));
+ }
+ if (__w_inf) {
+ return complex<_Tp>(_Tp(0), _Tp(0));
+ }
+ if (__z_inf) {
+ return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY));
+ }
+ if (__w_zero) {
+ if (__z_zero) {
+ return complex<_Tp>(_Tp(NAN), _Tp(0));
+ }
+ return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY));
+ }
+ }
_Tp __denom = __c * __c + __d * __d;
_Tp __x{};
_Tp __y{};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79555.303663.patch
Type: text/x-patch
Size: 2160 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20201107/794f3ebd/attachment.bin>
More information about the libcxx-commits
mailing list