diff --git a/stl/inc/ranges b/stl/inc/ranges index 88488143a5d..225afba439f 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -6171,6 +6171,26 @@ namespace ranges { inline constexpr _Slide_fn slide; } // namespace views + template + struct _Negated_pred { + template + _NODISCARD constexpr bool operator()(_Ty1&& _Left, _Ty2&& _Right) { + return !_STD invoke(_Pred, _STD forward<_Ty1>(_Left), _STD forward<_Ty2>(_Right)); + } + + _Pr& _Pred; + }; + + template + struct _Backward_negated_pred { + template + _NODISCARD constexpr bool operator()(_Ty1&& _Left, _Ty2&& _Right) { + return !_STD invoke(_Pred, _STD forward<_Ty2>(_Right), _STD forward<_Ty1>(_Left)); + } + + _Pr& _Pred; + }; + template , iterator_t<_Vw>> _Pr> requires view<_Vw> && is_object_v<_Pr> class chunk_by_view : public _Cached_position<_Vw, chunk_by_view<_Vw, _Pr>> { @@ -6255,10 +6275,7 @@ namespace ranges { _STL_VERIFY(_Pred, "cannot increment a chunk_by_view iterator whose parent view has no predicate"); #endif // _ITERATOR_DEBUG_LEVEL != 0 - const auto _Not_pred = [&_Orig_pred = *_Pred](_Ty1&& _Left, _Ty2&& _Right) { - return !_STD invoke(_Orig_pred, _STD forward<_Ty1>(_Left), _STD forward<_Ty2>(_Right)); - }; - const auto _Before_next = _RANGES adjacent_find(_It, _RANGES end(_Range), _Not_pred); + const auto _Before_next = _RANGES adjacent_find(_It, _RANGES end(_Range), _Negated_pred<_Pr>{*_Pred}); return _RANGES next(_Before_next, 1, _RANGES end(_Range)); } @@ -6269,10 +6286,7 @@ namespace ranges { #endif // _ITERATOR_DEBUG_LEVEL != 0 reverse_view _Rv{subrange{_RANGES begin(_Range), _It}}; - const auto _Rev_not_pred = [&_Orig_pred = *_Pred](_Ty1&& _Left, _Ty2&& _Right) { - return !_STD invoke(_Orig_pred, _STD forward<_Ty2>(_Right), _STD forward<_Ty1>(_Left)); - }; - const auto _After_prev = _RANGES adjacent_find(_Rv, _Rev_not_pred); + const auto _After_prev = _RANGES adjacent_find(_Rv, _Backward_negated_pred<_Pr>{*_Pred}); return _RANGES prev(_After_prev.base(), 1, _RANGES begin(_Range)); } diff --git a/stl/inc/xutility b/stl/inc/xutility index c88fbe7274e..a7c0ea49d86 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -640,30 +640,14 @@ template using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Its>...>; // clang-format on -#pragma warning(push) -#pragma warning(disable : 5046) // '%s': Symbol involving type with internal linkage not defined -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundefined-internal" // function '%s' has internal linkage but is not defined -#endif // __clang__ - template _Proj> struct projected { using value_type = remove_cvref_t>; -#if defined(__clang__) || defined(__EDG__) - indirect_result_t<_Proj&, _It> operator*() const; -#else // ^^^ no workaround / workaround vvv indirect_result_t<_Proj&, _It> operator*() const { - _CSTD abort(); // TRANSITION, VSO-1308657 + _CSTD abort(); } -#endif // ^^^ workaround ^^^ }; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif // __clang__ -#pragma warning(pop) - template struct incrementable_traits> { using difference_type = iter_difference_t<_It>; diff --git a/tests/std/tests/P2443R1_views_chunk_by/test.cpp b/tests/std/tests/P2443R1_views_chunk_by/test.cpp index d52d5058b7d..db69d0a4bf7 100644 --- a/tests/std/tests/P2443R1_views_chunk_by/test.cpp +++ b/tests/std/tests/P2443R1_views_chunk_by/test.cpp @@ -231,6 +231,24 @@ constexpr void instantiation_test() { #endif // TEST_EVERYTHING } +void test_gh_2889() { // COMPILE-ONLY + // GH-2889 : chunk_by_view's helper lambda does not specify return type + struct Bool { // NB: poor model of boolean-testable; don't use in runtime code. + Bool() = default; + Bool(const Bool&) = delete; + Bool& operator!() { + return *this; + } + operator bool() { + return true; + } + }; + + Bool x[3]; + auto r = x | views::chunk_by([](Bool& b, Bool&) -> Bool& { return b; }); + (void) r.begin(); +} + template > using move_only_view = test::range},