diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index eb99414c48be1..30a059f8a3df2 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -59,8 +59,8 @@ "`4038 `__","``std::text_encoding::aliases_view`` should have constexpr iterators","Tokyo March 2024","","","" "`4043 `__","""ASCII"" is not a registered character encoding","Tokyo March 2024","|Nothing To Do|","","" "`4045 `__","``tuple`` can create dangling references from ``tuple-like``","Tokyo March 2024","","","" -"`4053 `__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","","","|ranges|" -"`4054 `__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","","","|ranges|" +"`4053 `__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","|Complete|","19.0","|ranges|" +"`4054 `__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","|Complete|","19.0","|ranges|" "","","","","","" "`3343 `__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0","" "XXXX","","The sys_info range should be affected by save","Not Yet Adopted","|Complete|","19.0" diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 0941770f0eef8..53e4beb270ad0 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -22,6 +22,7 @@ #include <__ranges/iota_view.h> #include <__ranges/movable_box.h> #include <__ranges/view_interface.h> +#include <__type_traits/decay.h> #include <__type_traits/is_object.h> #include <__type_traits/make_unsigned.h> #include <__type_traits/remove_cv.h> @@ -127,8 +128,8 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface -repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>; +template +repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>; // [range.repeat.iterator] template @@ -230,9 +231,9 @@ namespace __repeat { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) - noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value)))) - -> decltype( ranges::repeat_view(std::forward<_Tp>(__value))) - { return ranges::repeat_view(std::forward<_Tp>(__value)); } + noexcept(noexcept(ranges::repeat_view>(std::forward<_Tp>(__value)))) + -> decltype( ranges::repeat_view>(std::forward<_Tp>(__value))) + { return ranges::repeat_view>(std::forward<_Tp>(__value)); } template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp index 454bac6e03e51..97b74289619dd 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp @@ -24,4 +24,10 @@ static_assert(std::same_as>); static_assert(std::same_as>); static_assert(std::same_as>); + +using RPV = std::ranges::repeat_view; +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4053 +static_assert(std::same_as); // OK // clang-format on diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp index 9cbe505621b98..5d913fa197f5a 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp @@ -60,6 +60,18 @@ static_assert(!std::is_invocable_v); // Tp is move_constructible static_assert(std::is_invocable_v); +// Test LWG4054 "Repeating a repeat_view should repeat the view" +static_assert(std::is_same_v>>); + +// These cases are from LWG4053, but they are actually covered by the resolution of LWG4054, +// and the resolution of LWG4053 only affects CTAD. +using RPV = std::ranges::repeat_view; +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4054 +static_assert(std::same_as); // OK + constexpr bool test() { assert(*std::views::repeat(33).begin() == 33); assert(*std::views::repeat(33, 10).begin() == 33);