From c45f382a12fc8ccc7324baad121ba5d262aab214 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Tue, 13 Dec 2022 07:07:26 +0700 Subject: [PATCH] Implement LWG-3646 std::ranges::view_interface::size returns a signed type Reviewed By: Mordante, philnik, #libc Differential Revision: https://reviews.llvm.org/D139791 --- libcxx/docs/Status/Cxx2bIssues.csv | 2 ++ libcxx/include/__ranges/view_interface.h | 4 ++-- .../std/ranges/range.utility/view.interface/view.interface.pass.cpp | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index 756c686..c648938 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -186,6 +186,8 @@ "`3721 `__","Allow an ``arg-id`` with a value of zero for ``width`` in ``std-format-spec``","July 2022","|Complete|","16.0","|format|" "`3724 `__","``decay-copy`` should be constrained","July 2022","|Complete|","14.0" "","","","","" +"`3646 `__","``std::ranges::view_interface::size`` returns a signed type","November 2022","|Complete|","16.0" +"","","","","" "`3629 `__","``make_error_code`` and ``make_error_condition`` are customization points","Not voted in","|Complete|","16.0","" "`3631 `__","``basic_format_arg(T&&)`` should use ``remove_cvref_t`` throughout","Not voted in","|Complete|","15.0","" "`3645 `__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0","" diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h index b89ee99..b706c8d 100644 --- a/libcxx/include/__ranges/view_interface.h +++ b/libcxx/include/__ranges/view_interface.h @@ -100,7 +100,7 @@ public: constexpr auto size() requires forward_range<_D2> && sized_sentinel_for, iterator_t<_D2>> { - return ranges::end(__derived()) - ranges::begin(__derived()); + return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); } template @@ -108,7 +108,7 @@ public: constexpr auto size() const requires forward_range && sized_sentinel_for, iterator_t> { - return ranges::end(__derived()) - ranges::begin(__derived()); + return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); } template diff --git a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp index 2c1c504..830f3f7 100644 --- a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp +++ b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp @@ -233,12 +233,18 @@ constexpr bool testSize() { static_assert(!SizeInvocable); static_assert( SizeInvocable); + using SignedSize = std::common_type_t>; ForwardRange forwardRange; assert(forwardRange.size() == 8); assert(static_cast(forwardRange).size() == 8); assert(std::ranges::size(forwardRange) == 8); + static_assert(std::same_as())), std::size_t>); + static_assert(std::same_as())), SignedSize>); + assert(std::ranges::size(static_cast(forwardRange)) == 8); + static_assert(std::same_as())), std::size_t>); + static_assert(std::same_as())), SignedSize>); SizeIsTen sizeTen; assert(sizeTen.size() == 10); -- 2.7.4