Skip to content

Commit 8307b2d

Browse files
committed
Make __add_output_unless() a freestanding function, __set_intersection_add_output_unless(), because the lambda [tripped the "MacOS with C++03" test run](https://buildkite.com/llvm-project/libcxx-ci/builds/35055#018f173c-f155-4fbb-b6d7-a7aba01cec9e):
``` ```
1 parent 4aa4a82 commit 8307b2d

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

libcxx/include/__algorithm/set_intersection.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ struct __set_intersection_result {
4343
: __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
4444
};
4545

46+
// Helper for __set_intersection() with one-sided binary search: populate result and advance input iterators if they
47+
// haven't advanced in the last 2 calls. This function is very intimately related to the way it is used and doesn't
48+
// attempt to abstract that, it's not appropriate for general usage outside of its context. It would be a lambda of
49+
// __set_intersection() if that hadn't stumped the compiler in c++03 mode in some platforms.
50+
template <class _InForwardIter1, class _InForwardIter2, class _OutIter>
51+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_intersection_add_output_unless(
52+
bool __advanced, _InForwardIter1& __first1, _InForwardIter2& __first2, _OutIter& __result, bool& __prev_advanced) {
53+
if (__advanced | __prev_advanced) {
54+
__prev_advanced = __advanced;
55+
} else {
56+
*__result = *__first1;
57+
++__result;
58+
++__first1;
59+
++__first2;
60+
__prev_advanced = true;
61+
}
62+
}
63+
4664
// With forward iterators we can make multiple passes over the data, allowing the use of one-sided binary search to
4765
// reduce best-case complexity to log(N). Understanding how we can use binary search and still respect complexity
4866
// guarantees is _not_ straightforward: the guarantee is "at most 2*(N+M)-1 comparisons", and one-sided binary search
@@ -76,30 +94,18 @@ __set_intersection(
7694
_LIBCPP_CONSTEXPR std::__identity __proj;
7795
bool __prev_advanced = true;
7896

79-
auto __add_output_unless = [&](bool __advanced) {
80-
if (__advanced | __prev_advanced) {
81-
__prev_advanced = __advanced;
82-
} else {
83-
*__result = *__first1;
84-
++__result;
85-
++__first1;
86-
++__first2;
87-
__prev_advanced = true;
88-
}
89-
};
90-
9197
while (__first2 != __last2) {
9298
_InForwardIter1 __first1_next =
9399
std::__lower_bound_onesided<_AlgPolicy>(__first1, __last1, *__first2, __comp, __proj);
94100
std::swap(__first1_next, __first1);
95-
__add_output_unless(__first1 != __first1_next);
101+
std::__set_intersection_add_output_unless(__first1 != __first1_next, __first1, __first2, __result, __prev_advanced);
96102
if (__first1 == __last1)
97103
break;
98104

99105
_InForwardIter2 __first2_next =
100106
std::__lower_bound_onesided<_AlgPolicy>(__first2, __last2, *__first1, __comp, __proj);
101107
std::swap(__first2_next, __first2);
102-
__add_output_unless(__first2 != __first2_next);
108+
std::__set_intersection_add_output_unless(__first2 != __first2_next, __first1, __first2, __result, __prev_advanced);
103109
}
104110
return __set_intersection_result<_InForwardIter1, _InForwardIter2, _OutIter>(
105111
_IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),

0 commit comments

Comments
 (0)