diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h --- a/libcxx/include/__ranges/all.h +++ b/libcxx/include/__ranges/all.h @@ -39,6 +39,7 @@ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))) + -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t))) { return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp --- a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp @@ -49,6 +49,17 @@ static_assert(std::ranges::view>); static_assert(std::ranges::view>); +struct MoveOnlyView : std::ranges::view_base{ + MoveOnlyView() = default; + MoveOnlyView(const MoveOnlyView&) = delete; + MoveOnlyView& operator=(const MoveOnlyView&) = delete; + MoveOnlyView(MoveOnlyView&&) = default; + MoveOnlyView& operator=(MoveOnlyView&&) = default; + + int* begin() const; + int* end() const; +}; + struct Range { int start_; constexpr explicit Range(int start) noexcept : start_(start) {} @@ -139,6 +150,11 @@ { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + // `views::all(v)` is expression equivalent to `decay-copy(v)` if the decayed type + // of `v` models `view`. If `v` is an lvalue-reference to a move-only view, the + // expression should be ill-formed because `v` is not copyable + static_assert(!std::is_invocable_v); } // Test that std::views::all is a range adaptor