[libcxx-commits] [libcxx] Implementation of adjacent_difference on top of a binary transform (PR #207585)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jul 5 06:19:34 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Michael G. Kazakov (mikekazakov)
<details>
<summary>Changes</summary>
---
Patch is 21.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/207585.diff
8 Files Affected:
- (modified) libcxx/include/__numeric/pstl.h (+39)
- (modified) libcxx/include/__pstl/backend_fwd.h (+7)
- (modified) libcxx/include/__pstl/backends/default.h (+32-3)
- (modified) libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp (+11)
- (modified) libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp (+5)
- (modified) libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp (+15-1)
- (added) libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference.pass.cpp (+171)
- (added) libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference_op.pass.cpp (+181)
``````````diff
diff --git a/libcxx/include/__numeric/pstl.h b/libcxx/include/__numeric/pstl.h
index ecbc9f5348333..0b85cfb8c2327 100644
--- a/libcxx/include/__numeric/pstl.h
+++ b/libcxx/include/__numeric/pstl.h
@@ -165,6 +165,45 @@ template <class _ExecutionPolicy,
std::move(__transform));
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator2 adjacent_difference(
+ _ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "adjacent_difference requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "adjacent_difference requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__adjacent_difference, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first1), std::move(__last1), std::move(__first2), minus{});
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator2 adjacent_difference(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _BinaryOperation __op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "adjacent_difference requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "adjacent_difference requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__adjacent_difference, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__op));
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index a52e6db954d0c..e4fd78850ec37 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -303,6 +303,13 @@ struct __is_sorted;
// optional<bool>
// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Comp&& __comp) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __adjacent_difference;
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+// optional<_ForwardIterator2>
+// operator()(_Policy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
+// _ForwardIterator2 __first2, _BinaryOperation &&__op) const noexcept;
+
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index be90715af13b5..05018c23c37e3 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -87,11 +87,12 @@ namespace __pstl {
//
// transform and transform_binary family
// -------------------------------------
-// - replace_copy_if
-// - replace_copy
-// - move
+// - adjacent_difference
// - copy
// - copy_n
+// - move
+// - replace_copy
+// - replace_copy_if
// - rotate_copy
//
@@ -529,6 +530,34 @@ struct __rotate_copy<__default_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __adjacent_difference<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _BinaryOperation&& __op) const noexcept {
+ using _TransformBinary = __dispatch<__transform_binary, __current_configuration, _ExecutionPolicy>;
+ if (__first1 == __last1)
+ return __first2; // edge case: empty input range, just return the output iterator
+ *__first2 = *__first1;
+ ++__first2;
+ _ForwardIterator1 __first_left = std::next(__first1);
+ if (__first_left == __last1)
+ return __first2; // edge case: not enough elements to perform adjacent difference, just return the output iterator
+ // Process as a binary transform of two iterator ranges: [__first1 + 1, __last1) and [__first1, __last1 - 1)
+ return _TransformBinary()(
+ __policy,
+ std::move(__first_left),
+ std::move(__last1),
+ std::move(__first1),
+ std::move(__first2),
+ std::forward<_BinaryOperation>(__op));
+ }
+};
+
} // 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 e5bd7e764c59b..82615719fba7d 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -190,4 +190,15 @@ void f(non_forward_iterator non_fwd, non_output_iterator non_output, std::execut
(void)std::transform_reduce(
pol, non_fwd, non_fwd, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
}
+
+ {
+ (void)std::adjacent_difference(
+ pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: adjacent_difference}}
+ (void)std::adjacent_difference(
+ pol, it, it, non_fwd, func); // expected-error@*:* {{static assertion failed: adjacent_difference}}
+ (void)std::adjacent_difference(
+ pol, non_fwd, non_fwd, it); // expected-error@*:* {{static assertion failed: adjacent_difference}}
+ (void)std::adjacent_difference(
+ pol, non_fwd, non_fwd, it, func); // expected-error@*:* {{static assertion failed: adjacent_difference}}
+ }
}
diff --git a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
index b6554cef6f32a..9f486c320067f 100644
--- a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
@@ -15,6 +15,7 @@
#include <algorithm>
#include <execution>
#include <iterator>
+#include <numeric>
void test() {
int a[] = {1};
@@ -52,4 +53,8 @@ void test() {
std::is_sorted(std::execution::par, std::begin(a), std::end(a));
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_sorted(std::execution::par, std::begin(a), std::end(a), pred2);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::adjacent_difference(std::execution::par, std::begin(a), std::end(a), std::begin(b));
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::adjacent_difference(std::execution::par, std::begin(a), std::end(a), std::begin(b), pred2);
}
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
index a3db159289393..16f4db5c97f1c 100644
--- a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -85,7 +85,7 @@ int main(int, char**) {
auto last1 = util::throw_on_move_iterator(std::end(a), tokens[1].active() ? 1 : -1);
auto first2 = util::throw_on_move_iterator(std::begin(b), tokens[2].active() ? 1 : -1);
auto last2 = util::throw_on_move_iterator(std::end(b), tokens[3].active() ? 1 : -1);
- auto dest = util::throw_on_move_iterator(std::end(storage), tokens[4].active() ? 1 : -1);
+ auto dest = util::throw_on_move_iterator(std::begin(storage), tokens[4].active() ? 1 : -1);
auto maybe_throw = [](ThrowToken const& token, auto f) {
return [&token, f](auto... args) {
if (token.active())
@@ -343,6 +343,20 @@ int main(int, char**) {
(void)std::reduce(policy, std::move(first1), std::move(last1), init, reduction);
});
}
+
+ {
+ auto op = maybe_throw(tokens[5], [](int x, int y) -> int { return x + y; });
+
+ // adjacent_difference(first, last, dest)
+ assert_non_throwing([=, &policy] {
+ (void)std::adjacent_difference(policy, std::move(first1), std::move(last1), std::move(dest));
+ });
+
+ // adjacent_difference(first, last, dest, op)
+ assert_non_throwing([=, &policy] {
+ (void)std::adjacent_difference(policy, std::move(first1), std::move(last1), std::move(dest), op);
+ });
+ }
}
});
}
diff --git a/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference.pass.cpp
new file mode 100644
index 0000000000000..bb98004c1c62a
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 ForwardIterator1,
+// class ForwardIterator2>
+// ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec,
+// ForwardIterator1 first1,
+// ForwardIterator1 last1,
+// ForwardIterator2 first2);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+
+EXECUTION_POLICY_SFINAE_TEST(adjacent_difference);
+
+static_assert(sfinae_test_adjacent_difference<int, int*, int*, int*>);
+static_assert(!sfinae_test_adjacent_difference<std::execution::parallel_policy, int*, int*, int*>);
+
+template <class Callable>
+void runway_sample(size_t size, Callable callable) {
+ constexpr size_t affix = 16;
+ // 0, 1, 2, ..., 15, 16, 50, 157, 493, 1548, ...
+ for (size_t i = 0; i < size; i = i < affix ? i + 1 : size_t(3.1415 * i)) {
+ callable(i);
+ }
+ if (size <= affix)
+ return;
+ // size - 16, size - 15, ..., size - 1
+ for (size_t i = size - affix; i < size; ++i) {
+ callable(i);
+ }
+}
+
+class X {
+ int i_;
+
+ X& operator=(const X&);
+
+public:
+ explicit X(int i) : i_(i) {}
+ X(const X& x) : i_(x.i_) {}
+ X& operator=(X&& x) {
+ i_ = x.i_;
+ x.i_ = -1;
+ return *this;
+ }
+
+ friend X operator-(const X& x, const X& y) { return X(x.i_ - y.i_); }
+
+ friend class Y;
+};
+
+class Y {
+ int i_;
+
+ Y& operator=(const Y&);
+
+public:
+ explicit Y(int i) : i_(i) {}
+ Y(const Y& y) : i_(y.i_) {}
+ void operator=(const X& x) { i_ = x.i_; }
+ bool operator==(const Y& y) const { return i_ == y.i_; }
+};
+
+template <class Iter1, class Iter2>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ int ia[] = {10};
+ int ir[] = {42};
+ int ib[] = {42};
+ Iter2 r = std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::begin(ia)), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::begin(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {10};
+ int ir[] = {10};
+ int ib[] = {42};
+ Iter2 r = std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {10, 30};
+ int ir[] = {10, 20};
+ int ib[std::size(ia)] = {0};
+ Iter2 r = std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {15, 10, 6, 3, 1};
+ int ir[] = {15, -5, -4, -3, -2};
+ int ib[std::size(ia)] = {0};
+ Iter2 r = std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[1073];
+ int ib[1073];
+ std::iota(std::begin(ia), std::end(ia), 1);
+ runway_sample(std::size(ia), [&](size_t i) {
+ Iter2 r =
+ std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::begin(ia) + i), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::begin(ib) + i));
+ assert(std::all_of(std::begin(ib), std::begin(ib) + i, [](int x) { return x == 1; }));
+ });
+ }
+ }
+};
+
+template <class Iter1, class Iter2>
+struct TestCustomTypes {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ X ia[3] = {X(1), X(5), X(7)};
+ Y ir[3] = {Y(1), Y(4), Y(2)};
+ Y ib[3] = {Y(0), Y(0), Y(0)};
+ Iter2 r = std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)));
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(
+ types::concatenate_t<types::forward_iterator_list<int*>, 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>{});
+ }});
+ types::for_each(
+ types::concatenate_t<types::forward_iterator_list<X*>, types::forward_iterator_list<const X*>>{},
+ types::apply_type_identity{[](auto v) {
+ using Iter = typename decltype(v)::type;
+ types::for_each(
+ types::forward_iterator_list<Y*>{},
+ TestIteratorWithPolicies<types::partial_instantiation<TestCustomTypes, Iter>::template apply>{});
+ }});
+ return 0;
+}
diff --git a/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference_op.pass.cpp
new file mode 100644
index 0000000000000..26d65f9a77c10
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/pstl.adjacent_difference_op.pass.cpp
@@ -0,0 +1,181 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 ForwardIterator1,
+// class ForwardIterator2,
+// class BinaryOperation>
+// ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec,
+// ForwardIterator1 first1,
+// ForwardIterator1 last1,
+// ForwardIterator2 first2,
+// BinaryOperation op);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+
+EXECUTION_POLICY_SFINAE_TEST(adjacent_difference);
+
+static_assert(sfinae_test_adjacent_difference<int, int*, int*, int*, int (*)(int, int)>);
+static_assert(!sfinae_test_adjacent_difference<std::execution::parallel_policy, int*, int*, int*, int (*)(int, int)>);
+
+template <class Callable>
+void runway_sample(size_t size, Callable callable) {
+ constexpr size_t affix = 16;
+ // 0, 1, 2, ..., 15, 16, 50, 157, 493, 1548, ...
+ for (size_t i = 0; i < size; i = i < affix ? i + 1 : size_t(3.1415 * i)) {
+ callable(i);
+ }
+ if (size <= affix)
+ return;
+ // size - 16, size - 15, ..., size - 1
+ for (size_t i = size - affix; i < size; ++i) {
+ callable(i);
+ }
+}
+
+class X {
+ int i_;
+ X& operator=(const X&);
+
+public:
+ explicit X(int i) : i_(i) {}
+ X(const X& x) : i_(x.i_) {}
+ X& operator=(X&& x) {
+ i_ = x.i_;
+ x.i_ = -1;
+ return *this;
+ }
+ friend class Y;
+ friend struct Op;
+};
+
+class Y {
+ int i_;
+ Y& operator=(const Y&);
+
+public:
+ explicit Y(int i) : i_(i) {}
+ Y(const Y& y) : i_(y.i_) {}
+ void operator=(const X& x) { i_ = x.i_; }
+ bool operator==(const Y& y) const { return i_ == y.i_; }
+};
+
+// ensures that the predicate is not equivalent to std::minus
+struct Op {
+ int operator()(int l, int r) const { return l * 2 - r; }
+ X operator()(const X& l, const X& r) const { return X(l.i_ * 2 - r.i_); }
+};
+
+template <class Iter1, class Iter2>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ int ia[] = {10};
+ int ir[] = {42};
+ int ib[] = {42};
+ Iter2 r =
+ std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::begin(ia)), Iter2(std::begin(ib)), Op{});
+ assert(r == Iter2(std::begin(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {10};
+ int ir[] = {10};
+ int ib[] = {42};
+ Iter2 r =
+ std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)), Op{});
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {10, 30};
+ int ir[] = {10, 50};
+ int ib[std::size(ia)] = {0};
+ Iter2 r =
+ std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)), Op{});
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[] = {15, 10, 6, 3, 1};
+ int ir[] = {15, 5, 2, 0, -1};
+ int ib[std::size(ia)] = {0};
+ Iter2 r =
+ std::adjacent_difference(policy, Iter1(std::begin(ia)), Iter1(std::end(ia)), Iter2(std::begin(ib)), Op{});
+ assert(r == Iter2(std::end(ib)));
+ for (size_t i = 0; i < std::size(ia); ++i)
+ assert(ib[i] == ir[i]);
+ }
+ {
+ int ia[1073];
+ int ib[1073];
+ std::iota(std::begin(ia), std::end(ia), 1);
+ runway_sample(std::size(ia), [&](size_t i) {
+ Iter2 r = std::adjacent_difference(
+ policy, Iter1(std::begin(ia)), Iter1(std::begin(ia) + i), Iter2(std::begin(ib)), Op{});
+ assert(r == Iter2(std::begin(ib) + i));
+ for (size_t j...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/207585
More information about the libcxx-commits
mailing list