[libcxx-commits] [libcxx] [libc++][pstl] Implementation of parallel std::reverse() based on parallel for_each (PR #213487)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 3 06:02:30 PDT 2026
================
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class BidirectionalIterator>
+// void reverse(ExecutionPolicy&& exec,
+// BidirectionalIterator first,
+// BidirectionalIterator last);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <numeric>
+#include <type_traits>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(reverse);
+
+static_assert(sfinae_test_reverse<int, int*, int*>);
+static_assert(!sfinae_test_reverse<std::execution::parallel_policy, int*, int*>);
+
+template <class Iter>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ { // Check the return type
+ static_assert(std::is_same_v<
+ void,
+ decltype(std::reverse(
+ std::declval<std::execution::parallel_policy>(), std::declval<Iter>(), std::declval<Iter>()))>);
+ }
+ { // Empty range
+ int a[] = {0};
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::begin(a)));
+ }
+ { // Single element
+ int a[] = {0};
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::end(a)));
+ assert(a[0] == 0);
+ }
+ { // Two elements
+ int a[] = {0, 1};
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::end(a)));
+ assert(a[0] == 1);
+ assert(a[1] == 0);
+ }
+ { // Three elements
+ int a[] = {0, 1, 2};
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::end(a)));
+ assert(a[0] == 2);
+ assert(a[1] == 1);
+ assert(a[2] == 0);
+ }
+ { // Four elements
+ int a[] = {0, 1, 2, 3};
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::end(a)));
+ assert(a[0] == 3);
+ assert(a[1] == 2);
+ assert(a[2] == 1);
+ assert(a[3] == 0);
+ }
+ { // Many iotaed elements, reverse up to a sampled position, check and reverse back
+ int a[1073];
+ std::iota(std::begin(a), std::end(a), 1);
+ runway_sample(std::size(a) + 1, [&](size_t i) {
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::begin(a) + i));
+ for (size_t j = 0; j < i; ++j) {
+ assert(a[j] == static_cast<int>(i - j));
+ }
+ std::reverse(policy, Iter(std::begin(a)), Iter(std::begin(a) + i));
+ });
+ }
+ }
+};
+
+int main(int, char**) { types::for_each(types::bidirectional_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{}); }
----------------
ldionne wrote:
```suggestion
int main(int, char**) {
types::for_each(types::bidirectional_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
return 0;
}
```
We always need to `return 0;` from main. In freestanding mode, `main` is not a special function so it doesn't return `0` implicitly. This is a nitpick, but worth knowing.
https://github.com/llvm/llvm-project/pull/213487
More information about the libcxx-commits
mailing list