зеркало из https://github.com/microsoft/STL.git
`chunk_by_view`'s helper lambda returns `bool` (#2890)
Co-authored-by: Casey Carter <Casey@Carter.net>
This commit is contained in:
Родитель
1a418ba4e9
Коммит
9ed0e6bd89
|
@ -6160,6 +6160,26 @@ namespace ranges {
|
|||
inline constexpr _Slide_fn slide;
|
||||
} // namespace views
|
||||
|
||||
template <class _Pr>
|
||||
struct _Negated_pred {
|
||||
template <class _Ty1, class _Ty2>
|
||||
_NODISCARD constexpr bool operator()(_Ty1&& _Left, _Ty2&& _Right) {
|
||||
return !_STD invoke(_Pred, _STD forward<_Ty1>(_Left), _STD forward<_Ty2>(_Right));
|
||||
}
|
||||
|
||||
_Pr& _Pred;
|
||||
};
|
||||
|
||||
template <class _Pr>
|
||||
struct _Backward_negated_pred {
|
||||
template <class _Ty1, class _Ty2>
|
||||
_NODISCARD constexpr bool operator()(_Ty1&& _Left, _Ty2&& _Right) {
|
||||
return !_STD invoke(_Pred, _STD forward<_Ty2>(_Right), _STD forward<_Ty1>(_Left));
|
||||
}
|
||||
|
||||
_Pr& _Pred;
|
||||
};
|
||||
|
||||
template <forward_range _Vw, indirect_binary_predicate<iterator_t<_Vw>, iterator_t<_Vw>> _Pr>
|
||||
requires view<_Vw> && is_object_v<_Pr>
|
||||
class chunk_by_view : public _Cached_position<_Vw, chunk_by_view<_Vw, _Pr>> {
|
||||
|
@ -6244,10 +6264,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]<class _Ty1, class _Ty2>(_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));
|
||||
}
|
||||
|
||||
|
@ -6258,10 +6275,7 @@ namespace ranges {
|
|||
#endif // _ITERATOR_DEBUG_LEVEL != 0
|
||||
|
||||
reverse_view _Rv{subrange{_RANGES begin(_Range), _It}};
|
||||
const auto _Rev_not_pred = [&_Orig_pred = *_Pred]<class _Ty1, class _Ty2>(_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));
|
||||
}
|
||||
|
||||
|
|
|
@ -640,30 +640,14 @@ template <class _Fn, class... _Its>
|
|||
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 <indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
|
||||
struct projected {
|
||||
using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
|
||||
#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 <weakly_incrementable _It, class _Proj>
|
||||
struct incrementable_traits<projected<_It, _Proj>> {
|
||||
using difference_type = iter_difference_t<_It>;
|
||||
|
|
|
@ -231,6 +231,24 @@ constexpr void instantiation_test() {
|
|||
#endif // TEST_EVERYTHING
|
||||
}
|
||||
|
||||
void test_gh_2889() { // COMPILE-ONLY
|
||||
// GH-2889 <ranges>: 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 <class Category, test::Common IsCommon, bool is_random = derived_from<Category, random_access_iterator_tag>>
|
||||
using move_only_view = test::range<Category, const char, test::Sized{is_random}, test::CanDifference{is_random},
|
||||
IsCommon, test::CanCompare{derived_from<Category, forward_iterator_tag>},
|
||||
|
|
Загрузка…
Ссылка в новой задаче