`chunk_by_view`'s helper lambda returns `bool` (#2890)

Co-authored-by: Casey Carter <Casey@Carter.net>
This commit is contained in:
S. B. Tam 2022-08-06 07:16:38 +08:00 коммит произвёл GitHub
Родитель 1a418ba4e9
Коммит 9ed0e6bd89
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 41 добавлений и 25 удалений

Просмотреть файл

@ -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>},