[libcxx-commits] [libcxx] [libc++][pstl] Add serial implementations of partitioning algorithms to PSTL (PR #234598)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Oct 26 03:06:25 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Michael G. Kazakov (mikekazakov)
<details>
<summary>Changes</summary>
This PR adds serial implementations of the partitioning algorithms to PSTL.
They are added to the serial backend only, such that any other backend can fall back to these implementations.
Currently there's no intent to provide parallel versions of these algorithms, but later they can be added as well.
These are the added algorithms:
- `std::partition`
- `std::stable_partition`
- `std::partition_copy`
Included tests check that:
- Semantics of the functions is correct.
- The functions correctly SFINAE out when the first argument is not an execution policy.
- The `nodiscard` policy is followed.
- The `noexcept` policy is followed.
- `static_assert` verifies iterators' categories.
Part of #<!-- -->99938.
---
Patch is 27.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/234598.diff
9 Files Affected:
- (modified) libcxx/include/__algorithm/pstl.h (+56)
- (modified) libcxx/include/__pstl/backend_fwd.h (+22)
- (modified) libcxx/include/__pstl/backends/serial.h (+40)
- (modified) libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp (+12)
- (modified) libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp (+7)
- (added) libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition.pass.cpp (+127)
- (added) libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition_copy.pass.cpp (+89)
- (added) libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.stable_partition.pass.cpp (+180)
- (modified) libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp (+14)
``````````diff
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index dc0e5d5a946b19..47503a45f348ec 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -718,6 +718,62 @@ is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIt
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _ForwardIterator
+partition(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "partition requires ForwardIterators");
+ using _Implementation = __pstl::__dispatch<__pstl::__partition, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _BidirectionalIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _BidirectionalIterator stable_partition(
+ _ExecutionPolicy&& __policy, _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(
+ _BidirectionalIterator, "stable_partition requires BidirectionalIterators");
+ using _Implementation = __pstl::__dispatch<__pstl::__stable_partition, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator1,
+ class _ForwardOutIterator2,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] pair<_ForwardOutIterator1, _ForwardOutIterator2> partition_copy(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator1 __out_true,
+ _ForwardOutIterator2 __out_false,
+ _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "partition_copy requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator1, decltype(*__first), "partition_copy requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator2, decltype(*__first), "partition_copy requires an OutputIterator");
+ using _Implementation = __pstl::__dispatch<__pstl::__partition_copy, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out_true),
+ std::move(__out_false),
+ std::move(__pred));
+}
+
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index fbc6f9920bdedd..e846edf63202a3 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -315,6 +315,21 @@ struct __none_of;
// optional<bool>
// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __partition;
+// template <class _Policy, class _ForwardIterator, class _Predicate>
+// optional<_ForwardIterator>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __partition_copy;
+// template <class _Policy, class _ForwardIterator,
+// class _ForwardOutIterator1, class _ForwardOutIterator2, class _Predicate>
+// optional<pair<_ForwardOutIterator1, _ForwardOutIterator2>>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last,
+// _ForwardOutIterator1 __out_true, _ForwardOutIterator2 __out_false,
+// _Predicate __pred) const noexcept;
+
template <class _Backend, class _ExecutionPolicy>
struct __reduce;
// template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
@@ -430,6 +445,13 @@ struct __sort;
// optional<__empty>
// operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __stable_partition;
+// template <class _Policy, class _BidirectionalIterator, class _Predicate>
+// optional<_BidirectionalIterator>
+// operator()(_Policy&& __policy, _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred)
+// const noexcept;
+
template <class _Backend, class _ExecutionPolicy>
struct __stable_sort;
// template <class _Policy, class _RandomAccessIterator, class _Comp>
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
index 294927cbb70276..3b29e214287147 100644
--- a/libcxx/include/__pstl/backends/serial.h
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -19,6 +19,8 @@
#include <__algorithm/min_element.h>
#include <__algorithm/minmax_element.h>
#include <__algorithm/mismatch.h>
+#include <__algorithm/partition.h>
+#include <__algorithm/partition_copy.h>
#include <__algorithm/reverse.h>
#include <__algorithm/search.h>
#include <__algorithm/search_n.h>
@@ -26,6 +28,7 @@
#include <__algorithm/set_intersection.h>
#include <__algorithm/set_symmetric_difference.h>
#include <__algorithm/set_union.h>
+#include <__algorithm/stable_partition.h>
#include <__algorithm/stable_sort.h>
#include <__algorithm/swap_ranges.h>
#include <__algorithm/transform.h>
@@ -417,6 +420,43 @@ struct __set_intersection<__serial_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __partition<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Predicate>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept {
+ return std::partition(std::move(__first), std::move(__last), std::move(__pred));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __stable_partition<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _BidirectionalIterator, class _Predicate>
+ optional<_BidirectionalIterator> operator()(
+ _Policy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred) const noexcept {
+ return std::stable_partition(std::move(__first), std::move(__last), std::move(__pred));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __partition_copy<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator,
+ class _ForwardOutIterator1,
+ class _ForwardOutIterator2,
+ class _Predicate>
+ optional<pair<_ForwardOutIterator1, _ForwardOutIterator2>>
+ operator()(_Policy&&,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator1 __out_true,
+ _ForwardOutIterator2 __out_false,
+ _Predicate __pred) const noexcept {
+ return std::partition_copy(
+ std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), std::move(__pred));
+ }
+};
+
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
index 7a006be5af72b1..31aa01a0080c3b 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -163,6 +163,18 @@ void f(non_forward_iterator non_fwd,
pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_partitioned}}
}
+ {
+ (void)std::partition(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: partition}}
+ (void)std::stable_partition(
+ pol, non_bidir, non_bidir, pred); // expected-error@*:* {{static assertion failed: stable_partition}}
+ (void)std::partition_copy(
+ pol, non_fwd, non_fwd, it, it, pred); // expected-error@*:* {{static assertion failed: partition_copy}}
+ (void)std::partition_copy(
+ pol, it, it, non_output, it, pred); // expected-error@*:* {{static assertion failed: partition_copy}}
+ (void)std::partition_copy(
+ pol, it, it, it, non_output, pred); // expected-error@*:* {{static assertion failed: partition_copy}}
+ }
+
{
(void)std::is_heap(pol, non_random, non_random); // expected-error@*:* {{static assertion failed: is_heap}}
(void)std::is_heap(pol, non_random, non_random, pred); // expected-error@*:* {{static assertion failed: is_heap}}
diff --git a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
index 03e324e502a4df..39d74d67af88eb 100644
--- a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
@@ -20,6 +20,7 @@
void test() {
int a[] = {1};
int b[] = {1};
+ int c[] = {1};
auto pred = [](auto) { return false; };
auto pred2 = [](auto, auto) { return false; };
@@ -139,4 +140,10 @@ void test() {
std::set_union(std::execution::par, std::begin(a), std::end(a), std::begin(a), std::end(a), std::begin(b));
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::set_union(std::execution::par, std::begin(a), std::end(a), std::begin(a), std::end(a), std::begin(b), pred2);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::partition(std::execution::par, std::begin(a), std::end(a), pred);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stable_partition(std::execution::par, std::begin(a), std::end(a), pred);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::partition_copy(std::execution::par, std::begin(a), std::end(a), std::begin(b), std::begin(c), pred);
}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition.pass.cpp
new file mode 100644
index 00000000000000..1a22cc00effea4
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition.pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class Predicate>
+// ForwardIterator partition(ExecutionPolicy&& exec,
+// ForwardIterator first,
+// ForwardIterator last,
+// Predicate pred);
+
+#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"
+
+EXECUTION_POLICY_SFINAE_TEST(partition);
+
+static_assert(sfinae_test_partition<int, int*, int*, bool (*)(int, int)>);
+static_assert(!sfinae_test_partition<std::execution::parallel_policy, int*, int*, bool (*)(int, int)>);
+
+template <class Iter>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ auto is_odd = [](int i) { return i % 2 == 1; };
+ { // Check the return type
+ int a[] = {0};
+ auto r = std::partition(policy, Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ static_assert(std::is_same_v<decltype(r), Iter>);
+ }
+ { // Check mixed
+ int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::begin(a) + 5));
+ for (auto i = Iter(std::begin(a)); i != r; ++i)
+ assert(is_odd(*i));
+ for (auto i = r; i != Iter(std::end(a)); ++i)
+ assert(!is_odd(*i));
+ }
+ { // Check empty
+ int a[] = {0};
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::begin(a)), is_odd);
+ assert(r == Iter(std::begin(a)));
+ }
+ { // Check all false
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 2 * v++; });
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::begin(a)));
+ }
+ { // Check all true
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 1 + 2 * v++; });
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::end(a)));
+ }
+ { // Check all true but last
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 1 + 2 * v++; });
+ a[std::size(a) - 1] = 10;
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::end(a) - 1));
+ for (auto i = Iter(std::begin(a)); i != r; ++i)
+ assert(is_odd(*i));
+ for (auto i = r; i != Iter(std::end(a)); ++i)
+ assert(!is_odd(*i));
+ }
+ { // Check all true but first
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 1 + 2 * v++; });
+ a[0] = 10;
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::end(a) - 1));
+ for (auto i = Iter(std::begin(a)); i != r; ++i)
+ assert(is_odd(*i));
+ for (auto i = r; i != Iter(std::end(a)); ++i)
+ assert(!is_odd(*i));
+ }
+ { // Check all false but last
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 2 * v++; });
+ a[std::size(a) - 1] = 11;
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::begin(a) + 1));
+ for (auto i = Iter(std::begin(a)); i != r; ++i)
+ assert(is_odd(*i));
+ for (auto i = r; i != Iter(std::end(a)); ++i)
+ assert(!is_odd(*i));
+ }
+ { // Check all false but first
+ int a[10] = {0};
+ std::generate(std::begin(a), std::end(a), [v = 0]() mutable { return 2 * v++; });
+ a[0] = 11;
+ auto r = std::partition(Iter(std::begin(a)), Iter(std::end(a)), is_odd);
+ assert(r == Iter(std::begin(a) + 1));
+ for (auto i = Iter(std::begin(a)); i != r; ++i)
+ assert(is_odd(*i));
+ for (auto i = r; i != Iter(std::end(a)); ++i)
+ assert(!is_odd(*i));
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
+ return 0;
+}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition_copy.pass.cpp
new file mode 100644
index 00000000000000..91721e815c5f86
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.partition_copy.pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class ForwardOutIterator1,
+// class ForwardOutIterator2,
+// class Predicate>
+// pair<ForwardOutIterator1, ForwardOutIterator2>
+// partition_copy(ExecutionPolicy&& exec,
+// ForwardIterator first,
+// ForwardIterator last,
+// ForwardOutIterator1 out_true,
+// ForwardOutIterator2 out_false,
+// Predicate pred);
+
+#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"
+
+EXECUTION_POLICY_SFINAE_TEST(partition_copy);
+
+static_assert(sfinae_test_partition_copy<int, int*, int*, int*, int*, bool (*)(int, int)>);
+static_assert(!sfinae_test_partition_copy<std::execution::parallel_policy, int*, int*, int*, int*, bool (*)(int, int)>);
+
+template <class Iter1, class Iter2>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ auto is_odd = [](int i) { return i % 2 == 1; };
+ { // Check the return type
+ int a[] = {0};
+ int t[std::size(a)] = {0};
+ int f[std::size(a)] = {0};
+ auto r = std::partition_copy(
+ policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::begin(t)), Iter2(std::begin(f)), is_odd);
+ static_assert(std::is_same_v<decltype(r), std::pair<Iter2, Iter2>>);
+ }
+ { // Equal sizes
+ int a[] = {1, 2, 3, 4, 6, 8, 5, 7};
+ int t[std::size(a)] = {0};
+ int f[std::size(a)] = {0};
+ auto r = std::partition_copy(
+ policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::begin(t)), Iter2(std::begin(f)), is_odd);
+ assert(r.first == Iter2(std::begin(t) + 4));
+ assert(t[0] == 1);
+ assert(t[1] == 3);
+ assert(t[2] == 5);
+ assert(t[3] == 7);
+ assert(r.second == Iter2(std::begin(f) + 4));
+ assert(f[0] == 2);
+ assert(f[1] == 4);
+ assert(f[2] == 6);
+ assert(f[3] == 8);
+ }
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<const int*>{}, types::apply_type_identity{[](auto v) {
+ using Iter = typename decltype(v)::type;
+ types::for_each(
+ types::forward_iterator_list<int*>{},
+ TestIteratorWithPolicies<types::partial_instantiation<Test, Iter>::template apply>{});
+ }});
+ return 0;
+}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.stable_partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.stable_partition.pass.cpp
new file mode 100644
index 00000000000000..dbb5c65bb4ed5f
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/pstl.stable_partition.pass.cpp
@@ -0,0 +1,180 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/234598
More information about the libcxx-commits
mailing list