[libcxx-commits] [libcxx] [libc++][test] Avoid C++23 Core features that MSVC lacks (PR #73438)

Stephan T. Lavavej via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 26 03:01:29 PST 2023


https://github.com/StephanTLavavej created https://github.com/llvm/llvm-project/pull/73438

Found while running libc++'s test suite with MSVC's STL, where we use both Clang and MSVC's compiler.

libc++'s test suite has started using some C++23 Core Language features that MSVC hasn't implemented yet. When avoiding these features costs just a tiny bit of syntax, I would like to ask libc++ to consider making that change in the interest of practical portability, at least until MSVC catches up. If there's no desire to do so, then I could skip the affected tests, but that would make me a slightly sad kitty.

Two commits here:

* MSVC hasn't implemented [P1102R2](https://wg21.link/P1102R2) "Make `()` more optional for lambdas" yet.
* MSVC hasn't implemented [P1938R3](https://wg21.link/P1938R3) "`if consteval`" yet.
  + Each of these files already directly includes `<type_traits>`.

>From 54d7ea16e2aff4de205200386e8cc54b6a495938 Mon Sep 17 00:00:00 2001
From: "Stephan T. Lavavej" <stl at nuwen.net>
Date: Sat, 18 Nov 2023 19:28:16 -0800
Subject: [PATCH 1/2] MSVC hasn't implemented P1102R2 "Make () more optional
 for lambdas" yet.

---
 .../observers/has_value.pass.cpp                 |  4 ++--
 .../expected.void/monadic/and_then.pass.cpp      | 16 ++++++++--------
 .../expected.void/monadic/transform.pass.cpp     | 16 ++++++++--------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
index 2b24b0ac24ddb8f..8e39986893e5449 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
@@ -57,9 +57,9 @@ constexpr bool test() {
   //
   // See https://github.com/llvm/llvm-project/issues/68552 and the linked PR.
   {
-    auto f1 = [] -> std::expected<std::optional<int>, long> { return 0; };
+    auto f1 = []() -> std::expected<std::optional<int>, long> { return 0; };
 
-    auto f2 = [&f1] -> std::expected<std::optional<int>, int> {
+    auto f2 = [&f1]() -> std::expected<std::optional<int>, int> {
       return f1().transform_error([](auto) { return 0; });
     };
 
diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp
index f60002c67ebc09b..e4a384ae2594e8a 100644
--- a/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp
@@ -58,7 +58,7 @@ static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&&, in
 constexpr void test_val_types() {
   // Test & overload
   {
-    auto l = [] -> std::expected<int, int> { return 2; };
+    auto l = []() -> std::expected<int, int> { return 2; };
     std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = v.and_then(l);
     assert(val == 2);
@@ -66,7 +66,7 @@ constexpr void test_val_types() {
 
   // Test const& overload
   {
-    auto l = [] -> std::expected<int, int> { return 2; };
+    auto l = []() -> std::expected<int, int> { return 2; };
     const std::expected<void, int> v;
     assert(v.and_then(l).value() == 2);
     static_assert(std::is_same_v< decltype(v.and_then(l)), std::expected<int, int>>);
@@ -74,7 +74,7 @@ constexpr void test_val_types() {
 
   // Test && overload
   {
-    auto l = [] -> std::expected<int, int> { return 2; };
+    auto l = []() -> std::expected<int, int> { return 2; };
     std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(l);
     assert(val == 2);
@@ -82,7 +82,7 @@ constexpr void test_val_types() {
 
   // Test const&& overload
   {
-    auto l = [] -> std::expected<int, int> { return 2; };
+    auto l = []() -> std::expected<int, int> { return 2; };
     const std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(l);
     assert(val == 2);
@@ -92,7 +92,7 @@ constexpr void test_val_types() {
 constexpr void test_fail() {
   // Test & overload
   {
-    auto f = [] -> std::expected<int, int> {
+    auto f = []() -> std::expected<int, int> {
       assert(false);
       return 0;
     };
@@ -103,7 +103,7 @@ constexpr void test_fail() {
 
   // Test const& overload
   {
-    auto f = [] -> std::expected<int, int> {
+    auto f = []() -> std::expected<int, int> {
       assert(false);
       return 0;
     };
@@ -114,7 +114,7 @@ constexpr void test_fail() {
 
   // Test && overload
   {
-    auto f = [] -> std::expected<int, int> {
+    auto f = []() -> std::expected<int, int> {
       assert(false);
       return 0;
     };
@@ -125,7 +125,7 @@ constexpr void test_fail() {
 
   // Test const&& overload
   {
-    auto f = [] -> std::expected<int, int> {
+    auto f = []() -> std::expected<int, int> {
       assert(false);
       return 0;
     };
diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp
index ea90006e3199ed1..2cdeb8505a8a3ee 100644
--- a/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp
@@ -35,7 +35,7 @@ static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&&, i
 constexpr void test_val_types() {
   // Test & overload
   {
-    auto l = [] -> int { return 1; };
+    auto l = []() -> int { return 1; };
     std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
     assert(val == 1);
@@ -43,7 +43,7 @@ constexpr void test_val_types() {
 
   // Test const& overload
   {
-    auto l = [] -> int { return 1; };
+    auto l = []() -> int { return 1; };
     const std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
     assert(val == 1);
@@ -51,7 +51,7 @@ constexpr void test_val_types() {
 
   // Test && overload
   {
-    auto l = [] -> int { return 1; };
+    auto l = []() -> int { return 1; };
     std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
     assert(val == 1);
@@ -59,7 +59,7 @@ constexpr void test_val_types() {
 
   // Test const&& overload
   {
-    auto l = [] -> int { return 1; };
+    auto l = []() -> int { return 1; };
     const std::expected<void, int> v;
     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
     assert(val == 1);
@@ -69,7 +69,7 @@ constexpr void test_val_types() {
 constexpr void test_fail() {
   // Test & overload
   {
-    auto l = [] -> int {
+    auto l = []() -> int {
       assert(false);
       return 0;
     };
@@ -80,7 +80,7 @@ constexpr void test_fail() {
 
   // Test const& overload
   {
-    auto l = [] -> int {
+    auto l = []() -> int {
       assert(false);
       return 0;
     };
@@ -91,7 +91,7 @@ constexpr void test_fail() {
 
   // Test && overload
   {
-    auto l = [] -> int {
+    auto l = []() -> int {
       assert(false);
       return 0;
     };
@@ -102,7 +102,7 @@ constexpr void test_fail() {
 
   // Test const&& overload
   {
-    auto l = [] -> int {
+    auto l = []() -> int {
       assert(false);
       return 0;
     };

>From 122aa8cea5f67bae747eb8f65bb32dad839d2e0e Mon Sep 17 00:00:00 2001
From: "Stephan T. Lavavej" <stl at nuwen.net>
Date: Fri, 24 Nov 2023 12:15:22 -0800
Subject: [PATCH 2/2] MSVC hasn't implemented P1938R3 "if consteval" yet.

Each of these files already directly includes `<type_traits>`.
---
 libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h   | 4 ++--
 .../std/containers/views/mdspan/mdspan/CustomTestAccessors.h  | 2 +-
 .../std/containers/views/mdspan/mdspan/ctor.dh_array.pass.cpp | 4 ++--
 .../containers/views/mdspan/mdspan/ctor.dh_extents.pass.cpp   | 4 ++--
 .../containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp  | 4 ++--
 .../std/containers/views/mdspan/mdspan/ctor.dh_map.pass.cpp   | 4 ++--
 .../containers/views/mdspan/mdspan/ctor.dh_map_acc.pass.cpp   | 4 ++--
 .../std/containers/views/mdspan/mdspan/ctor.dh_span.pass.cpp  | 4 ++--
 libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp  | 2 +-
 9 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h b/libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h
index 302eb2f5edd0193..ee0b36cc52c6f26 100644
--- a/libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h
+++ b/libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h
@@ -176,7 +176,7 @@ class layout_wrapping_integral<WrapArg>::mapping {
 
   friend constexpr void swap(mapping& x, mapping& y) noexcept {
     swap(x.extents_, y.extents_);
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       swap_counter()++;
     }
   }
@@ -317,7 +317,7 @@ class always_convertible_layout::mapping {
 
   friend constexpr void swap(mapping& x, mapping& y) noexcept {
     swap(x.extents_, y.extents_);
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       swap_counter()++;
     }
   }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/CustomTestAccessors.h b/libcxx/test/std/containers/views/mdspan/mdspan/CustomTestAccessors.h
index 346f4977ca142e8..d0023f44df5cace 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/CustomTestAccessors.h
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/CustomTestAccessors.h
@@ -53,7 +53,7 @@ struct move_counted_handle {
   constexpr move_counted_handle(const move_counted_handle<OtherT>& other) : ptr(other.ptr){};
   constexpr move_counted_handle(move_counted_handle&& other) {
     ptr = other.ptr;
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       move_counter()++;
     }
   }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_array.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_array.pass.cpp
index e4f88d6035049f6..3c8797c023e1b57 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_array.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_array.pass.cpp
@@ -55,11 +55,11 @@ template <class H, class M, class A, size_t N>
 constexpr void
 test_mdspan_ctor_array(const H& handle, const M& map, const A&, std::array<typename M::index_type, N> exts) {
   using MDS = std::mdspan<typename A::element_type, typename M::extents_type, typename M::layout_type, A>;
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     move_counted_handle<typename MDS::element_type>::move_counter() = 0;
   }
   MDS m(handle, exts);
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
       assert((H::move_counter() == 1));
     }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_extents.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_extents.pass.cpp
index c15d1dc47ad9703..37ee8bdc2e1af4e 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_extents.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_extents.pass.cpp
@@ -41,12 +41,12 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) {
   static_assert(mec == std::is_constructible_v<M, const typename M::extents_type&>);
   static_assert(ac == std::is_default_constructible_v<A>);
   if constexpr (mec && ac) {
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       move_counted_handle<typename MDS::element_type>::move_counter() = 0;
     }
     // use formulation of constructor which tests that its not explicit
     MDS m = {handle, map.extents()};
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
         assert((H::move_counter() == 1));
       }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp
index 0288e63106522df..f4a3e8adc40d8ea 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp
@@ -52,11 +52,11 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&, Idxs..
   static_assert(ac == std::is_default_constructible_v<A>);
 
   if constexpr (mec && ac) {
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       move_counted_handle<typename MDS::element_type>::move_counter() = 0;
     }
     MDS m(handle, idxs...);
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
         assert((H::move_counter() == 1));
       }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map.pass.cpp
index 9fe79ad460ccb05..995bc5d6d118198 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map.pass.cpp
@@ -38,12 +38,12 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) {
 
   static_assert(ac == std::is_default_constructible_v<A>);
   if constexpr (ac) {
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       move_counted_handle<typename MDS::element_type>::move_counter() = 0;
     }
     // use formulation of constructor which tests that it is not explicit
     MDS m = {handle, map};
-    if !consteval {
+    if (!std::is_constant_evaluated()) {
       if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
         assert((H::move_counter() == 1));
       }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map_acc.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map_acc.pass.cpp
index 3be47ae92072395..c2d76a47b2ee1aa 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map_acc.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_map_acc.pass.cpp
@@ -33,12 +33,12 @@ template <class H, class M, class A>
 constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) {
   using MDS = std::mdspan<typename A::element_type, typename M::extents_type, typename M::layout_type, A>;
 
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     move_counted_handle<typename MDS::element_type>::move_counter() = 0;
   }
   // use formulation of constructor which tests that it is not explicit
   MDS m = {handle, map, acc};
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
       assert((H::move_counter() == 1));
     }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_span.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_span.pass.cpp
index 30876abea5005bb..7084e626171d43a 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_span.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/ctor.dh_span.pass.cpp
@@ -55,11 +55,11 @@ template <class H, class M, class A, size_t N>
 constexpr void
 test_mdspan_ctor_span(const H& handle, const M& map, const A&, std::span<typename M::index_type, N> exts) {
   using MDS = std::mdspan<typename A::element_type, typename M::extents_type, typename M::layout_type, A>;
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     move_counted_handle<typename MDS::element_type>::move_counter() = 0;
   }
   MDS m(handle, exts);
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     if constexpr (std::is_same_v<H, move_counted_handle<typename MDS::element_type>>) {
       assert((H::move_counter() == 1));
     }
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp b/libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp
index 9b54da3252d47ea..983a789cb310278 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp
@@ -43,7 +43,7 @@ constexpr void test_swap(MDS a, MDS b) {
   }
   // This check uses a side effect of layout_wrapping_integral::swap to make sure
   // mdspan calls the underlying components' swap via ADL
-  if !consteval {
+  if (!std::is_constant_evaluated()) {
     if constexpr (std::is_same_v<typename MDS::layout_type, layout_wrapping_integral<4>>) {
       assert(MDS::mapping_type::swap_counter() > 0);
     }



More information about the libcxx-commits mailing list