Skip to content

[libcxx][NFC] Consolidate testing concept CanBePiped #80154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 8, 2024

Conversation

hawkinsw
Copy link
Contributor

Almost every test needed a CanBePiped concept and each implemented it separately, but identically. Consolidate all implementations into test_range.h.

@hawkinsw hawkinsw requested review from var-const and cjdb January 31, 2024 15:55
@hawkinsw hawkinsw self-assigned this Jan 31, 2024
@hawkinsw hawkinsw requested a review from a team as a code owner January 31, 2024 15:55
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 31, 2024
@hawkinsw
Copy link
Contributor Author

I hope that this consolidation is helpful!

@llvmbot
Copy link
Member

llvmbot commented Jan 31, 2024

@llvm/pr-subscribers-libcxx

Author: Will Hawkins (hawkinsw)

Changes

Almost every test needed a CanBePiped concept and each implemented it separately, but identically. Consolidate all implementations into test_range.h.


Full diff: https://github.com/llvm/llvm-project/pull/80154.diff

15 Files Affected:

  • (modified) libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp (+2-6)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.drop.while/adaptor.pass.cpp (+2-6)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.drop/adaptor.pass.cpp (+2-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp (+2-6)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp (-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp (+1-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp (-6)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp (+2-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp (-5)
  • (modified) libcxx/test/support/test_range.h (+5)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
index d90a25d93e345..d31373fcad78b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
@@ -17,8 +17,9 @@
 #include <type_traits>
 #include <utility>
 
-#include "test_macros.h"
 #include "test_iterators.h"
+#include "test_macros.h"
+#include "test_range.h"
 
 int globalBuff[8];
 
@@ -82,11 +83,6 @@ struct RandomAccessRange {
 template<>
 inline constexpr bool std::ranges::enable_borrowed_range<RandomAccessRange> = true;
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 constexpr bool test() {
   {
     ASSERT_SAME_TYPE(decltype(std::views::all(View<true>())), View<true>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp
index 423c481127e20..697085a1d5c55 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp
@@ -22,11 +22,7 @@
 #include <utility>
 
 #include "test_iterators.h"
-
-template <class View, class T>
-concept CanBePiped = requires(View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
+#include "test_range.h"
 
 struct Pred {
   constexpr bool operator()(int x, int y) const { return x != -y; }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp
index 143f7df1d3724..b0e72e9e79148 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp
@@ -18,13 +18,9 @@
 #include <utility>
 
 #include "test_iterators.h"
+#include "test_range.h"
 #include "types.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 constexpr bool test() {
   int buf[] = {1, 2, 3};
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.drop.while/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.drop.while/adaptor.pass.cpp
index 409b400f7f87f..c41d4172f1990 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.drop.while/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.drop.while/adaptor.pass.cpp
@@ -16,6 +16,8 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_range.h"
+
 struct Pred {
   constexpr bool operator()(int i) const { return i < 3; }
 };
@@ -51,12 +53,6 @@ static_assert(std::is_invocable_v<decltype((std::views::drop_while)), int (&)[2]
 static_assert(!std::is_invocable_v<decltype((std::views::drop_while)), Foo (&)[2], Pred>);
 static_assert(std::is_invocable_v<decltype((std::views::drop_while)), MoveOnlyView, Pred>);
 
-template <class View, class T>
-concept CanBePiped =
-    requires(View&& view, T&& t) {
-      { std::forward<View>(view) | std::forward<T>(t) };
-    };
-
 static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::drop_while)>);
 static_assert(CanBePiped<MoveOnlyView, decltype(std::views::drop_while(Pred{}))>);
 static_assert(!CanBePiped<int, decltype(std::views::drop_while(Pred{}))>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.drop/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.drop/adaptor.pass.cpp
index 457b137c80457..d07fe9ac0ea72 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.drop/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.drop/adaptor.pass.cpp
@@ -18,12 +18,9 @@
 #include <span>
 #include <string_view>
 #include <utility>
-#include "test_iterators.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
+#include "test_iterators.h"
+#include "test_range.h"
 
 struct SizedView : std::ranges::view_base {
   int* begin_ = nullptr;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp
index d68d6e57e2ed5..35589c96e4b77 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp
@@ -19,6 +19,8 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_range.h"
+
 template <class T>
 struct View : std::ranges::view_base {
   T* begin() const;
@@ -41,12 +43,6 @@ static_assert(!std::is_invocable_v<decltype((std::views::values)), View<int>>);
 static_assert(std::is_invocable_v<decltype((std::views::values)), View<std::pair<int, int>>>);
 static_assert(!std::is_invocable_v<decltype((std::views::values)), View<std::tuple<int>>>);
 
-template <class View, class T>
-concept CanBePiped =
-    requires(View&& view, T&& t) {
-      { std::forward<View>(view) | std::forward<T>(t) };
-    };
-
 static_assert(!CanBePiped<View<int>, decltype((std::views::elements<0>))>);
 static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::elements<0>))>);
 static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<0>))>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.filter/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.filter/adaptor.pass.cpp
index 1adf1b4630b87..a44e96e1d4bde 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.filter/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.filter/adaptor.pass.cpp
@@ -19,11 +19,7 @@
 #include <utility>
 
 #include "test_iterators.h"
-
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
+#include "test_range.h"
 
 struct NonCopyablePredicate {
   NonCopyablePredicate(NonCopyablePredicate const&) = delete;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
index 9beb3d282a27c..54d95edf510f4 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
@@ -32,11 +32,6 @@ struct Foo {
   constexpr Foo(int ii) : i(ii) {}
 };
 
-template <class View, class T>
-concept CanBePiped = requires(View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 constexpr bool test() {
   int buffer1[3] = {1, 2, 3};
   int buffer2[2] = {4, 5};
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp
index 6bfa0ab487ba1..7bb7e95b02dab 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp
@@ -19,13 +19,9 @@
 #include <utility>
 
 #include "test_iterators.h"
+#include "test_range.h"
 #include "types.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 struct SomeView : std::ranges::view_base {
   const std::string_view* v_;
   constexpr SomeView(const std::string_view& v) : v_(&v) {}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp
index 5e0a0a3ce3fbc..26c9ac08d338b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp
@@ -17,13 +17,9 @@
 #include <iterator>
 #include <utility>
 
+#include "test_range.h"
 #include "types.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 constexpr bool test() {
   int buf[] = {1, 2, 3};
 
diff --git a/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp
index 85d13ac5c29df..34c0f15ce3463 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp
@@ -19,11 +19,7 @@
 #include <utility>
 
 #include "test_iterators.h"
-
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
+#include "test_range.h"
 
 struct SomeView : std::ranges::view_base {
   const std::string_view* v_;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp
index 8796f9df63cee..42814014ce884 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take.while/adaptor.pass.cpp
@@ -42,12 +42,6 @@ static_assert(std::is_invocable_v<decltype((std::views::take_while)), int (&)[2]
 static_assert(!std::is_invocable_v<decltype((std::views::take_while)), Foo (&)[2], Pred>);
 static_assert(std::is_invocable_v<decltype((std::views::take_while)), MoveOnlyView, Pred>);
 
-template <class View, class T>
-concept CanBePiped =
-    requires(View&& view, T&& t) {
-      { std::forward<View>(view) | std::forward<T>(t) };
-    };
-
 static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::take_while)>);
 static_assert(CanBePiped<MoveOnlyView, decltype(std::views::take_while(Pred{}))>);
 static_assert(!CanBePiped<int, decltype(std::views::take_while(Pred{}))>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
index bb5b5f5ff4909..b30c4fbe3fd96 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
@@ -17,12 +17,9 @@
 #include <span>
 #include <string_view>
 #include <utility>
-#include "test_iterators.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
+#include "test_iterators.h"
+#include "test_range.h"
 
 struct SizedView : std::ranges::view_base {
   int* begin_ = nullptr;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp
index 59dd85bf28bc3..91eedc5d36a96 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp
@@ -20,11 +20,6 @@
 #include "test_macros.h"
 #include "types.h"
 
-template <class View, class T>
-concept CanBePiped = requires (View&& view, T&& t) {
-  { std::forward<View>(view) | std::forward<T>(t) };
-};
-
 struct NonCopyableFunction {
   NonCopyableFunction(NonCopyableFunction const&) = delete;
   template <class T>
diff --git a/libcxx/test/support/test_range.h b/libcxx/test/support/test_range.h
index 6061f710a2636..c5eeb25bb59eb 100644
--- a/libcxx/test/support/test_range.h
+++ b/libcxx/test/support/test_range.h
@@ -89,4 +89,9 @@ concept simple_view =
     std::same_as<std::ranges::iterator_t<Range>, std::ranges::iterator_t<const Range>> &&
     std::same_as<std::ranges::sentinel_t<Range>, std::ranges::sentinel_t<const Range>>;
 
+template <class View, class T>
+concept CanBePiped = requires(View&& view, T&& t) {
+  { std::forward<View>(view) | std::forward<T>(t) };
+};
+
 #endif // LIBCXX_TEST_SUPPORT_TEST_RANGE_H

@hawkinsw
Copy link
Contributor Author

hawkinsw commented Feb 6, 2024

@cjdb I hope that this is something that is helpful!

@hawkinsw
Copy link
Contributor Author

Hello! Let me know if there is anything else I can do to get this into shape! cc @cjdb @var-const

Copy link
Member

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is a nice refactoring! Just wanted to double-check whether a couple of these files need to include test_range.h now (or perhaps they aren't actually using CanBePiped?). Other than that, LGTM.

@@ -20,11 +20,6 @@
#include "test_macros.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to include "test_range.h" here? Otherwise, this file is probably relying on a transitive include (unless CanBePiped is not used here?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great eyes! In these cases, I was relying on the fact that the implementers of the adapters created their own header files (types.h) and those file includes the test_range.h. I have adjusted the patch to make direct inclusion of the test_ranges.h file but I am more than happy to go back to the old version if that is our standard.

Thanks for the sharp feedback!

requires(View&& view, T&& t) {
{ std::forward<View>(view) | std::forward<T>(t) };
};

static_assert(!CanBePiped<MoveOnlyView, decltype(std::views::take_while)>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include "test_range.h"? (or is it not used in this file?)

concept CanBePiped = requires(View&& view, T&& t) {
{ std::forward<View>(view) | std::forward<T>(t) };
};

constexpr bool test() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include "test_range.h"? (or is it not used in this file?)

Almost every test needed a CanBePiped concept and each implemented it
separately, but identically. Consolidate all implementations into
test_range.h.
Directly import test_range.h in several places.
@hawkinsw
Copy link
Contributor Author

Just wanted to see if my replies addressed your comments! Thanks for everything!
Will

@hawkinsw
Copy link
Contributor Author

hawkinsw commented Mar 5, 2024

Just wanted to see if my replies addressed your comments! Thanks for everything! Will

Please let me know if there is anything else I can do to clean this up!

@var-const var-const self-assigned this Mar 8, 2024
@var-const var-const added the ranges Issues related to `<ranges>` label Mar 8, 2024
Copy link
Member

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the delay! LGTM.

@ldionne ldionne merged commit ba2236d into llvm:main Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. ranges Issues related to `<ranges>`
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants