[libcxx-commits] [PATCH] D79555: [libc++] [P0415] [C++20] - Constexpr for std::complex.
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu May 7 11:20:47 PDT 2020
ldionne added a comment.
In D79555#2025500 <https://reviews.llvm.org/D79555#2025500>, @curdeius wrote:
> @ldionne, I'd appreciate if you (or somebody else) could tell me what you think about the way I test the constexpr. I wanted to avoid duplication but on a second thought, I think that run-time tests can actually go through compile-time (constexpr) branch and so leave the non-constexpr branch untested.
I think it's fine -- avoiding duplication is pretty important IMO. I don't think the compiler will try to evaluate this using the constexpr evaluator if it's not marked as `constexpr`. If we wanted to be really really sure, we could also make sure the values we use in the test are thought to be potentially-runtime by calling a function defined in a different TU. That would be somewhat more complicated, but imagine the following setup:
// in support.cpp
template <typename T>
T identity(T t) { return t; }
template int identity(int);
template float identity(float);
// etc...
Then, let's say you have a test that is potentially `constexpr` like this:
template <class T>
TEST_CONSTEXPR_CXX20 bool test(T zero) {
T lhs(1.5 + zero);
std::complex<T> rhs(3.5 + zero, 4.5);
std::complex<T> x(5.0 + zero, 4.5);
test(lhs, rhs, x);
}
You could now call it once at runtime and once at compile-time:
int main(int argc, char** argv) {
test<float>(identity<float>(0)); // runtime test
static_assert(test<float>(0)); // compile-time test
}
Since `identity` is defined in a different TU, the compiler would really have to generate code for the runtime tests. There's a few different ways to do this, another way I can think of is to piggy back on `argc` or just a (volatile?) global variable. But the idea is the same. If there's interest, we can look into setting this up more widely for amphibious (constexpr/not constexpr) tests.
> Another thing in which I'd need guidance is how to test the primary implementation (not specializations for float, double, long double). Is there another floating-point type I can use in tests? Maybe some sort of short float?
I'm seeing this on cppreference:
> The specializations `std::complex<float>`, `std::complex<double>`, and `std::complex<long double>` are `LiteralTypes` for representing and manipulating complex numbers. The effect of instantiating the template `complex` for any other type is unspecified.
I don't think we test other specializations in our other complex tests, do we? If not, I'd say it's OK to not test it... Maybe I'm not being imaginative enough?
> Oh, and should integral types be tested with `complex<T>`?
Like I said above, I don't think so. Please LMK if you disagree.
What *does* need to be tested however is the interaction between `std::complex<T>` and `U` where `T in {float, double, long double}` and `U` is an integral type. But you seem to be testing this correct (e.g. in `conj.pass.cpp`).
================
Comment at: libcxx/test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp:34
test(lhs, rhs, x);
- }
+ }
{
----------------
Nit: this spacing seems to have changed?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79555/new/
https://reviews.llvm.org/D79555
More information about the libcxx-commits
mailing list