mclow.lists created this revision.
This patch implements most of https://wg21.link/P0451r1 - the notable exception
being division.
The current implementation of complex division in libc++ uses `logb`, `fmax`,
and a couple of other primitives that are not constexpr. The paper has some
approaches for dealing with this, but I haven't implemented those yet. I wanted
to get all the mechanical bits out first.
Note that there are tests for division being constexpr; they currently fail.
https://reviews.llvm.org/D40651
Files:
include/complex
test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp
test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp
test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp
test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp
test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp
test/std/numerics/complex.number/complex.members/real_imag.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp
test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp
test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp
test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp
test/std/numerics/complex.number/complex.value.ops/conj.pass.cpp
test/std/numerics/complex.number/complex.value.ops/imag.pass.cpp
test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
Index: test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
@@ -12,16 +12,30 @@
// template<class T>
// T
// real(const complex<T>& x);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test()
+{
+ std::complex<T> z(1.5, 2.5);
+ return real(z) == 1.5;
+}
+
+template <class T>
void
test()
{
std::complex<T> z(1.5, 2.5);
assert(real(z) == 1.5);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test<T>(), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
@@ -12,13 +12,24 @@
// template<class T>
// complex<T>
// proj(const complex<T>& x);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
#include "../cases.h"
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T> &z, std::complex<T> x)
+{
+ return proj(z) == x;
+}
+
+
+template <class T>
void
test(const std::complex<T>& z, std::complex<T> x)
{
@@ -29,10 +40,24 @@
void
test()
{
- test(std::complex<T>(1, 2), std::complex<T>(1, 2));
- test(std::complex<T>(-1, 2), std::complex<T>(-1, 2));
- test(std::complex<T>(1, -2), std::complex<T>(1, -2));
- test(std::complex<T>(-1, -2), std::complex<T>(-1, -2));
+ typedef std::complex<T> C;
+
+ TEST_CONSTEXPR C v12 ( 1, 2);
+ TEST_CONSTEXPR C v1_2 ( 1, -2);
+ TEST_CONSTEXPR C v_12 (-1, 2);
+ TEST_CONSTEXPR C v_1_2(-1, -2);
+
+ test(v12, v12);
+ test(v_12, v_12);
+ test(v1_2, v1_2);
+ test(v_1_2, v_1_2);
+
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(v12, v12), "");
+ static_assert(constexpr_test(v_12, v_12), "");
+ static_assert(constexpr_test(v1_2, v1_2), "");
+ static_assert(constexpr_test(v_1_2, v_1_2), "");
+#endif
}
void test_edges()
Index: test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
@@ -12,18 +12,31 @@
// template<class T>
// T
// norm(const complex<T>& x);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
#include "../cases.h"
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T> &z, T expected)
+{
+ return norm(z) == expected;
+}
+
+template <class T>
void
test()
{
- std::complex<T> z(3, 4);
+ TEST_CONSTEXPR std::complex<T> z(3, 4);
assert(norm(z) == 25);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test<T>(z, 25), "");
+#endif
}
void test_edges()
Index: test/std/numerics/complex.number/complex.value.ops/imag.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.value.ops/imag.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/imag.pass.cpp
@@ -12,16 +12,30 @@
// template<class T>
// T
// imag(const complex<T>& x);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test()
+{
+ std::complex<T> z(1.5, 2.5);
+ return imag(z) == 2.5;
+}
+
+template <class T>
void
test()
{
std::complex<T> z(1.5, 2.5);
assert(imag(z) == 2.5);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test<T>(), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.value.ops/conj.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.value.ops/conj.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/conj.pass.cpp
@@ -12,11 +12,21 @@
// template<class T>
// complex<T>
// conj(const complex<T>& x);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T> &z, std::complex<T> x)
+{
+ return conj(z) == x;
+}
+
+template <class T>
void
test(const std::complex<T>& z, std::complex<T> x)
{
@@ -27,10 +37,25 @@
void
test()
{
- test(std::complex<T>(1, 2), std::complex<T>(1, -2));
- test(std::complex<T>(-1, 2), std::complex<T>(-1, -2));
- test(std::complex<T>(1, -2), std::complex<T>(1, 2));
- test(std::complex<T>(-1, -2), std::complex<T>(-1, 2));
+ typedef std::complex<T> C;
+
+ TEST_CONSTEXPR C v12 ( 1, 2);
+ TEST_CONSTEXPR C v1_2 ( 1, -2);
+ TEST_CONSTEXPR C v_12 (-1, 2);
+ TEST_CONSTEXPR C v_1_2(-1, -2);
+
+ test(v12, v1_2);
+ test(v_12, v_1_2);
+ test(v1_2, v12);
+ test(v_1_2, v_12);
+
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(v12, v1_2 ), "");
+ static_assert(constexpr_test(v_12, v_1_2), "");
+ static_assert(constexpr_test(v1_2, v12 ), "");
+ static_assert(constexpr_test(v_1_2, v_12 ), "");
+#endif
+
}
int main()
Index: test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp
@@ -12,20 +12,34 @@
// template<class T>
// complex<T>
// operator+(const complex<T>&);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T> &z)
+{
+ std::complex<T> c = +z;
+ return c.real() == z.real() && c.imag() == z.imag();
+}
+
+template <class T>
void
test()
{
- std::complex<T> z(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> z(1.5, 2.5);
assert(z.real() == 1.5);
assert(z.imag() == 2.5);
- std::complex<T> c = +z;
+ TEST_CONSTEXPR std::complex<T> c = +z;
assert(c.real() == 1.5);
assert(c.imag() == 2.5);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(z), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp
@@ -12,20 +12,34 @@
// template<class T>
// complex<T>
// operator-(const complex<T>& lhs);
+// constexpr in c++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T> &z)
+{
+ std::complex<T> c = -z;
+ return c.real() == -z.real() && c.imag() == -z.imag();
+}
+
+template <class T>
void
test()
{
- std::complex<T> z(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> z(1.5, 2.5);
assert(z.real() == 1.5);
assert(z.imag() == 2.5);
- std::complex<T> c = -z;
+ TEST_CONSTEXPR std::complex<T> c = -z;
assert(c.real() == -1.5);
assert(c.imag() == -2.5);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(z), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator*(const T& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,13 +27,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs * rhs == x;
+}
+
+template <class T>
void
test()
{
- T lhs(1.5);
- std::complex<T> rhs(1.5, 2.5);
- std::complex<T> x(2.25, 3.75);
+ TEST_CONSTEXPR T lhs(1.5);
+ TEST_CONSTEXPR std::complex<T> rhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> x(2.25, 3.75);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator+(const T& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,20 +27,33 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs + rhs == x;
+}
+
+template <class T>
void
test()
{
{
- T lhs(1.5);
- std::complex<T> rhs(3.5, 4.5);
- std::complex<T> x(5.0, 4.5);
+ TEST_CONSTEXPR T lhs(1.5);
+ TEST_CONSTEXPR std::complex<T> rhs(3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(5.0, 4.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
{
- T lhs(1.5);
- std::complex<T> rhs(-3.5, 4.5);
- std::complex<T> x(-2.0, 4.5);
+ TEST_CONSTEXPR T lhs(1.5);
+ TEST_CONSTEXPR std::complex<T> rhs(-3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(-2.0, 4.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
}
Index: test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator-(const T& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,20 +27,33 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs - rhs == x;
+}
+
+template <class T>
void
test()
{
{
- T lhs(1.5);
- std::complex<T> rhs(3.5, 4.5);
- std::complex<T> x(-2.0, -4.5);
+ TEST_CONSTEXPR T lhs(1.5);
+ TEST_CONSTEXPR std::complex<T> rhs(3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(-2.0, -4.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
{
- T lhs(1.5);
- std::complex<T> rhs(-3.5, 4.5);
- std::complex<T> x(5.0, -4.5);
+ TEST_CONSTEXPR T lhs(1.5);
+ TEST_CONSTEXPR std::complex<T> rhs(-3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(5.0, -4.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
}
Index: test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator/(const T& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,13 +27,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const T& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs / rhs == x;
+}
+
+template <class T>
void
test()
{
- T lhs(-8.5);
- std::complex<T> rhs(1.5, 2.5);
- std::complex<T> x(-1.5, 2.5);
+ TEST_CONSTEXPR T lhs(-8.5);
+ TEST_CONSTEXPR std::complex<T> rhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> x(-1.5, 2.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator*(const complex<T>& lhs, const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
@@ -24,13 +27,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
+{
+ return lhs * rhs == x;
+}
+
+template <class T>
void
test()
{
- std::complex<T> lhs(1.5, 2.5);
- T rhs(1.5);
- std::complex<T> x(2.25, 3.75);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, 2.5);
+ TEST_CONSTEXPR T rhs(1.5);
+ TEST_CONSTEXPR std::complex<T> x(2.25, 3.75);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator*(const complex<T>& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
#include "../cases.h"
template <class T>
@@ -26,13 +29,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs * rhs == x;
+}
+
+template <class T>
void
test()
{
- std::complex<T> lhs(1.5, 2.5);
- std::complex<T> rhs(1.5, 2.5);
- std::complex<T> x(-4.0, 7.5);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> rhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> x(-4.0, 7.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
// test edges
Index: test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator+(const complex<T>& lhs, const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
@@ -24,20 +27,33 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
+{
+ return lhs + rhs == x;
+}
+
+template <class T>
void
test()
{
{
- std::complex<T> lhs(1.5, 2.5);
- T rhs(3.5);
- std::complex<T> x(5.0, 2.5);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, 2.5);
+ TEST_CONSTEXPR T rhs(3.5);
+ TEST_CONSTEXPR std::complex<T> x(5.0, 2.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
{
- std::complex<T> lhs(1.5, -2.5);
- T rhs(-3.5);
- std::complex<T> x(-2.0, -2.5);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, -2.5);
+ TEST_CONSTEXPR T rhs(-3.5);
+ TEST_CONSTEXPR std::complex<T> x(-2.0, -2.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
}
Index: test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator+(const complex<T>& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,20 +27,33 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs + rhs == x;
+}
+
+template <class T>
void
test()
{
{
- std::complex<T> lhs(1.5, 2.5);
- std::complex<T> rhs(3.5, 4.5);
- std::complex<T> x(5.0, 7.0);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> rhs(3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(5.0, 7.0);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
{
- std::complex<T> lhs(1.5, -2.5);
- std::complex<T> rhs(-3.5, 4.5);
- std::complex<T> x(-2.0, 2.0);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, -2.5);
+ TEST_CONSTEXPR std::complex<T> rhs(-3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(-2.0, 2.0);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
}
Index: test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator-(const complex<T>& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
@@ -24,20 +27,33 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs - rhs == x;
+}
+
+template <class T>
void
test()
{
{
- std::complex<T> lhs(1.5, 2.5);
- std::complex<T> rhs(3.5, 4.5);
- std::complex<T> x(-2.0, -2.0);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> rhs(3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(-2.0, -2.0);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
{
- std::complex<T> lhs(1.5, -2.5);
- std::complex<T> rhs(-3.5, 4.5);
- std::complex<T> x(5.0, -7.0);
+ TEST_CONSTEXPR std::complex<T> lhs(1.5, -2.5);
+ TEST_CONSTEXPR std::complex<T> rhs(-3.5, 4.5);
+ TEST_CONSTEXPR std::complex<T> x(5.0, -7.0);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
}
Index: test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator/(const complex<T>& lhs, const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
@@ -24,13 +27,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test (const std::complex<T>& lhs, const T& rhs, std::complex<T> x)
+{
+ return lhs / rhs == x;
+}
+
+template <class T>
void
test()
{
- std::complex<T> lhs(-4.0, 7.5);
- T rhs(2);
- std::complex<T> x(-2, 3.75);
+ TEST_CONSTEXPR std::complex<T> lhs(-4.0, 7.5);
+ TEST_CONSTEXPR T rhs(2);
+ TEST_CONSTEXPR std::complex<T> x(-2, 3.75);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
+++ test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
@@ -12,10 +12,13 @@
// template<class T>
// complex<T>
// operator/(const complex<T>& lhs, const complex<T>& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
#include "../cases.h"
template <class T>
@@ -26,13 +29,23 @@
}
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex<T>& lhs, const std::complex<T>& rhs, std::complex<T> x)
+{
+ return lhs / rhs == x;
+}
+
+template <class T>
void
test()
{
- std::complex<T> lhs(-4.0, 7.5);
- std::complex<T> rhs(1.5, 2.5);
- std::complex<T> x(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> lhs(-4.0, 7.5);
+ TEST_CONSTEXPR std::complex<T> rhs(1.5, 2.5);
+ TEST_CONSTEXPR std::complex<T> x(1.5, 2.5);
test(lhs, rhs, x);
+#if TEST_STD_VER > 17
+ static_assert(constexpr_test(lhs, rhs, x), "");
+#endif
}
void test_edges()
Index: test/std/numerics/complex.number/complex.members/real_imag.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.members/real_imag.pass.cpp
+++ test/std/numerics/complex.number/complex.members/real_imag.pass.cpp
@@ -18,6 +18,24 @@
#include "test_macros.h"
template <class T>
+TEST_CONSTEXPR bool
+constexpr_real(T val)
+{
+ std::complex<T> c1{};
+ c1.real(val);
+ return c1.real() == val;
+}
+
+template <class T>
+TEST_CONSTEXPR bool
+constexpr_imag(T val)
+{
+ std::complex<T> c1{};
+ c1.imag(val);
+ return c1.imag() == val;
+}
+
+template <class T>
void
test_constexpr()
{
@@ -32,6 +50,10 @@
static_assert(c3.real() == 3, "");
static_assert(c3.imag() == 4, "");
#endif
+#if TEST_STD_VER > 17
+ static_assert(constexpr_real<T>(T(4.7)), "" );
+ static_assert(constexpr_imag<T>(T(4.7)), "" );
+#endif
}
template <class T>
Index: test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp
@@ -10,11 +10,21 @@
// <complex>
// complex& operator*=(const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(std::complex<T> lhs, const T& rhs, const std::complex<T>& expected)
+{
+ return (lhs *= rhs) == expected;
+}
+
+template <class T>
void
test()
{
@@ -34,6 +44,12 @@
c *= 1.5;
assert(c.real() == -5.0625);
assert(c.imag() == 3);
+
+#if TEST_STD_VER > 17
+ TEST_CONSTEXPR std::complex<T> c1{4,-1};
+ TEST_CONSTEXPR std::complex<T> c2{8,-2};
+ static_assert(constexpr_test(c1, T(2), c2), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp
@@ -10,11 +10,21 @@
// <complex>
// complex& operator+=(const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(std::complex<T> lhs, const T& rhs, const std::complex<T>& expected)
+{
+ return (lhs += rhs) == expected;
+}
+
+template <class T>
void
test()
{
@@ -30,6 +40,12 @@
c += -1.5;
assert(c.real() == 1.5);
assert(c.imag() == 0);
+
+#if TEST_STD_VER > 17
+ TEST_CONSTEXPR std::complex<T> c1{4,-1};
+ TEST_CONSTEXPR std::complex<T> c2{6,-1};
+ static_assert(constexpr_test(c1, T(2), c2), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp
@@ -10,11 +10,21 @@
// <complex>
// complex& operator-=(const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(std::complex<T> lhs, const T& rhs, const std::complex<T>& expected)
+{
+ return (lhs -= rhs) == expected;
+}
+
+template <class T>
void
test()
{
@@ -30,6 +40,12 @@
c -= -1.5;
assert(c.real() == -1.5);
assert(c.imag() == 0);
+
+#if TEST_STD_VER > 17
+ TEST_CONSTEXPR std::complex<T> c1{6,-1};
+ TEST_CONSTEXPR std::complex<T> c2{4,-1};
+ static_assert(constexpr_test(c1, T(2), c2), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp
@@ -10,11 +10,21 @@
// <complex>
// complex& operator/=(const T& rhs);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(std::complex<T> lhs, const T& rhs, const std::complex<T>& expected)
+{
+ return (lhs /= rhs) == expected;
+}
+
+template <class T>
void
test()
{
@@ -34,6 +44,12 @@
c /= 0.5;
assert(c.real() == -16);
assert(c.imag() == 4);
+
+#if TEST_STD_VER > 17
+ TEST_CONSTEXPR std::complex<T> c1{8,-2};
+ TEST_CONSTEXPR std::complex<T> c2{4,-1};
+ static_assert(constexpr_test(c1, T(2), c2), "");
+#endif
}
int main()
Index: test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp
===================================================================
--- test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp
+++ test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp
@@ -10,11 +10,21 @@
// <complex>
// complex& operator= (const T&);
+// constexpr in C++20
#include <complex>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
+TEST_CONSTEXPR bool
+constexpr_test(std::complex<T> lhs, const T& rhs)
+{
+ return (lhs = rhs) == rhs;
+}
+
+template <class T>
void
test()
{
@@ -27,6 +37,11 @@
c = -1.5;
assert(c.real() == -1.5);
assert(c.imag() == 0);
+
+#if TEST_STD_VER > 17
+ TEST_CONSTEXPR std::complex<T> c1{8,-2};
+ static_assert(constexpr_test(c1, T(2)), "");
+#endif
}
int main()
Index: include/complex
===================================================================
--- include/complex
+++ include/complex
@@ -33,18 +33,18 @@
void real(T);
void imag(T);
- complex<T>& operator= (const T&);
- complex<T>& operator+=(const T&);
- complex<T>& operator-=(const T&);
- complex<T>& operator*=(const T&);
- complex<T>& operator/=(const T&);
+ complex<T>& operator= (const T&); // constexpr in C++2a
+ complex<T>& operator+=(const T&); // constexpr in C++2a
+ complex<T>& operator-=(const T&); // constexpr in C++2a
+ complex<T>& operator*=(const T&); // constexpr in C++2a
+ complex<T>& operator/=(const T&); // constexpr in C++2a
complex& operator=(const complex&);
- template<class X> complex<T>& operator= (const complex<X>&);
- template<class X> complex<T>& operator+=(const complex<X>&);
- template<class X> complex<T>& operator-=(const complex<X>&);
- template<class X> complex<T>& operator*=(const complex<X>&);
- template<class X> complex<T>& operator/=(const complex<X>&);
+ template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++2a
+ template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++2a
};
template<>
@@ -57,23 +57,23 @@
explicit constexpr complex(const complex<double>&);
explicit constexpr complex(const complex<long double>&);
- constexpr float real() const;
- void real(float);
- constexpr float imag() const;
- void imag(float);
+ constexpr float real() const; // constexpr in C++14
+ void real(float); // constexpr in C++2a
+ constexpr float imag() const; // constexpr in C++14
+ void imag(float); // constexpr in C++2a
- complex<float>& operator= (float);
- complex<float>& operator+=(float);
- complex<float>& operator-=(float);
- complex<float>& operator*=(float);
- complex<float>& operator/=(float);
+ complex<float>& operator= (float); // constexpr in C++2a
+ complex<float>& operator+=(float); // constexpr in C++2a
+ complex<float>& operator-=(float); // constexpr in C++2a
+ complex<float>& operator*=(float); // constexpr in C++2a
+ complex<float>& operator/=(float); // constexpr in C++2a
complex<float>& operator=(const complex<float>&);
- template<class X> complex<float>& operator= (const complex<X>&);
- template<class X> complex<float>& operator+=(const complex<X>&);
- template<class X> complex<float>& operator-=(const complex<X>&);
- template<class X> complex<float>& operator*=(const complex<X>&);
- template<class X> complex<float>& operator/=(const complex<X>&);
+ template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++2a
+ template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++2a
};
template<>
@@ -86,23 +86,23 @@
constexpr complex(const complex<float>&);
explicit constexpr complex(const complex<long double>&);
- constexpr double real() const;
- void real(double);
- constexpr double imag() const;
- void imag(double);
+ constexpr double real() const; // constexpr in C++14
+ void real(double); // constexpr in C++2a
+ constexpr double imag() const; // constexpr in C++14
+ void imag(double); // constexpr in C++2a
- complex<double>& operator= (double);
- complex<double>& operator+=(double);
- complex<double>& operator-=(double);
- complex<double>& operator*=(double);
- complex<double>& operator/=(double);
+ complex<double>& operator= (double); // constexpr in C++2a
+ complex<double>& operator+=(double); // constexpr in C++2a
+ complex<double>& operator-=(double); // constexpr in C++2a
+ complex<double>& operator*=(double); // constexpr in C++2a
+ complex<double>& operator/=(double); // constexpr in C++2a
complex<double>& operator=(const complex<double>&);
- template<class X> complex<double>& operator= (const complex<X>&);
- template<class X> complex<double>& operator+=(const complex<X>&);
- template<class X> complex<double>& operator-=(const complex<X>&);
- template<class X> complex<double>& operator*=(const complex<X>&);
- template<class X> complex<double>& operator/=(const complex<X>&);
+ template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++2a
+ template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++2a
};
template<>
@@ -115,46 +115,46 @@
constexpr complex(const complex<float>&);
constexpr complex(const complex<double>&);
- constexpr long double real() const;
- void real(long double);
- constexpr long double imag() const;
- void imag(long double);
+ constexpr long double real() const; // constexpr in C++14
+ void real(long double); // constexpr in C++2a
+ constexpr long double imag() const; // constexpr in C++14
+ void imag(double); // constexpr in C++2a
+ complex<long double>& operator= (long double); // constexpr in C++2a
+ complex<long double>& operator+=(long double); // constexpr in C++2a
+ complex<long double>& operator-=(long double); // constexpr in C++2a
+ complex<long double>& operator*=(long double); // constexpr in C++2a
+ complex<long double>& operator/=(long double); // constexpr in C++2a
complex<long double>& operator=(const complex<long double>&);
- complex<long double>& operator= (long double);
- complex<long double>& operator+=(long double);
- complex<long double>& operator-=(long double);
- complex<long double>& operator*=(long double);
- complex<long double>& operator/=(long double);
- template<class X> complex<long double>& operator= (const complex<X>&);
- template<class X> complex<long double>& operator+=(const complex<X>&);
- template<class X> complex<long double>& operator-=(const complex<X>&);
- template<class X> complex<long double>& operator*=(const complex<X>&);
- template<class X> complex<long double>& operator/=(const complex<X>&);
+ template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++2a
+ template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++2a
+ template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++2a
};
// 26.3.6 operators:
-template<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator+(const complex<T>&, const T&);
-template<class T> complex<T> operator+(const T&, const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&, const T&);
-template<class T> complex<T> operator-(const T&, const complex<T>&);
-template<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator*(const complex<T>&, const T&);
-template<class T> complex<T> operator*(const T&, const complex<T>&);
-template<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator/(const complex<T>&, const T&);
-template<class T> complex<T> operator/(const T&, const complex<T>&);
-template<class T> complex<T> operator+(const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&);
-template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
-template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
-template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
-template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
+template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator+(const complex<T>&, const T&); // constexpr in C++2a
+template<class T> complex<T> operator+(const T&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator-(const complex<T>&, const T&); // constexpr in C++2a
+template<class T> complex<T> operator-(const T&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator*(const complex<T>&, const T&); // constexpr in C++2a
+template<class T> complex<T> operator*(const T&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator/(const complex<T>&, const T&); // constexpr in C++2a
+template<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator+(const complex<T>&); // constexpr in C++2a
+template<class T> complex<T> operator-(const complex<T>&); // constexpr in C++2a
+template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
template<class T, class charT, class traits>
basic_istream<charT, traits>&
@@ -185,19 +185,19 @@
template<Integral T> double arg(T);
float arg(float);
-template<class T> T norm(const complex<T>&);
+template<class T> T norm(const complex<T>&); // constexpr in C++2a
long double norm(long double);
double norm(double);
template<Integral T> double norm(T);
float norm(float);
-template<class T> complex<T> conj(const complex<T>&);
+template<class T> complex<T> conj(const complex<T>&); // constexpr in C++2a
complex<long double> conj(long double);
complex<double> conj(double);
template<Integral T> complex<double> conj(T);
complex<float> conj(float);
-template<class T> complex<T> proj(const complex<T>&);
+template<class T> complex<T> proj(const complex<T>&); // constexpr in C++2a
complex<long double> proj(long double);
complex<double> proj(double);
template<Integral T> complex<double> proj(T);
@@ -254,7 +254,7 @@
template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
-template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
+template<class _Tp> _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
template<class _Tp>
@@ -276,40 +276,58 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
- {__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (const value_type& __re) {__re_ = __re; __im_ = value_type(); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -337,40 +355,56 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
- {__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (float __re) {__re_ = __re; __im_ = value_type(); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(float __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(float __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -395,40 +429,58 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
- {__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (double __re) {__re_ = __re; __im_ = value_type(); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(double __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(double __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -453,40 +505,58 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY void _LIBCPP_CONSTEXPR_AFTER_CXX17 real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY void _LIBCPP_CONSTEXPR_AFTER_CXX17 imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
- {__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (long double __re) {__re_ = __re; __im_ = value_type(); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(long double __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(long double __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+
+ template<class _Xp>
+ _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
+ complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -526,7 +596,7 @@
// 26.3.6 operators:
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
@@ -536,7 +606,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator+(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -546,7 +616,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator+(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -556,7 +626,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
@@ -566,7 +636,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator-(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -576,7 +646,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator-(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -586,6 +656,7 @@
}
template<class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
{
@@ -645,7 +716,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator*(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -655,7 +726,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator*(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -665,6 +736,7 @@
}
template<class _Tp>
+// _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
{
@@ -709,7 +781,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator/(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -717,7 +789,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY // _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator/(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -727,7 +799,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator+(const complex<_Tp>& __x)
{
@@ -735,7 +807,7 @@
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
operator-(const complex<_Tp>& __x)
{
@@ -906,7 +978,7 @@
// norm
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_Tp
norm(const complex<_Tp>& __c)
{
@@ -918,7 +990,7 @@
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename __libcpp_complex_overload_traits<_Tp>::_ValueType
norm(_Tp __re)
{
@@ -929,7 +1001,7 @@
// conj
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
conj(const complex<_Tp>& __c)
{
@@ -937,7 +1009,7 @@
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
conj(_Tp __re)
{
@@ -950,7 +1022,7 @@
// proj
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
complex<_Tp>
proj(const complex<_Tp>& __c)
{
@@ -961,7 +1033,7 @@
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename enable_if
<
is_floating_point<_Tp>::value,
@@ -975,7 +1047,7 @@
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename enable_if
<
is_integral<_Tp>::value,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits