Index: libcxx/docs/Status/Cxx2bIssues.csv =================================================================== --- libcxx/docs/Status/Cxx2bIssues.csv +++ libcxx/docs/Status/Cxx2bIssues.csv @@ -81,7 +81,7 @@ `3529 `__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","","" `3530 `__,"``BUILTIN-PTR-MEOW`` should not opt the type out of syntactic checks","June 2021","","" `3532 `__,"``split_view::inner-iterator::operator++(int)`` should depend on ``Base``","June 2021","","","|ranges|" -`3533 `__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","","","|ranges|" +`3533 `__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","|Complete|","14.0","|ranges|" `3536 `__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","","","|chrono|" `3539 `__,"``format_to`` must not copy models of ``output_iterator``","June 2021","","","|format|" `3540 `__,"ยง[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","","","|format|" @@ -138,4 +138,4 @@ `3595 `__,"Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","October 2021","","","|ranges|" "","","","","" `3645 `__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0","" -"","","","","" \ No newline at end of file +"","","","","" Index: libcxx/include/__iterator/counted_iterator.h =================================================================== --- libcxx/include/__iterator/counted_iterator.h +++ libcxx/include/__iterator/counted_iterator.h @@ -96,7 +96,7 @@ } _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& { return __current_; } + constexpr const _Iter& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return _VSTD::move(__current_); } Index: libcxx/include/__ranges/transform_view.h =================================================================== --- libcxx/include/__ranges/transform_view.h +++ libcxx/include/__ranges/transform_view.h @@ -195,9 +195,7 @@ : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {} _LIBCPP_HIDE_FROM_ABI - constexpr iterator_t<_Base> base() const& - requires copyable> - { + constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } Index: libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp =================================================================== --- libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp +++ libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp @@ -32,17 +32,18 @@ { std::counted_iterator iter(cpp20_input_iterator{buffer}, 8); - assert(iter.base().base() == buffer); - assert(std::move(iter).base().base() == buffer); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); + ASSERT_NOEXCEPT(iter.base()); ASSERT_SAME_TYPE(decltype(iter.base()), const cpp20_input_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), cpp20_input_iterator); } { std::counted_iterator iter(forward_iterator{buffer}, 8); - assert(iter.base() == forward_iterator{buffer}); - assert(std::move(iter).base() == forward_iterator{buffer}); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); ASSERT_SAME_TYPE(decltype(iter.base()), const forward_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), forward_iterator); @@ -50,8 +51,8 @@ { std::counted_iterator iter(contiguous_iterator{buffer}, 8); - assert(iter.base() == contiguous_iterator{buffer}); - assert(std::move(iter).base() == contiguous_iterator{buffer}); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); ASSERT_SAME_TYPE(decltype(iter.base()), const contiguous_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), contiguous_iterator); @@ -68,8 +69,8 @@ { const std::counted_iterator iter(cpp20_input_iterator{buffer}, 8); - assert(iter.base().base() == buffer); - assert(std::move(iter).base().base() == buffer); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); ASSERT_SAME_TYPE(decltype(iter.base()), const cpp20_input_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), const cpp20_input_iterator&); @@ -77,8 +78,8 @@ { const std::counted_iterator iter(forward_iterator{buffer}, 7); - assert(iter.base() == forward_iterator{buffer}); - assert(std::move(iter).base() == forward_iterator{buffer}); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); ASSERT_SAME_TYPE(decltype(iter.base()), const forward_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), const forward_iterator&); @@ -86,8 +87,8 @@ { const std::counted_iterator iter(contiguous_iterator{buffer}, 6); - assert(iter.base() == contiguous_iterator{buffer}); - assert(std::move(iter).base() == contiguous_iterator{buffer}); + assert(base(iter.base()) == buffer); + assert(base(std::move(iter).base()) == buffer); ASSERT_SAME_TYPE(decltype(iter.base()), const contiguous_iterator&); ASSERT_SAME_TYPE(decltype(std::move(iter).base()), const contiguous_iterator&); Index: libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp @@ -32,50 +32,87 @@ using TransformView = std::ranges::transform_view; static_assert(std::ranges::common_range); TransformView tv; - auto end = tv.end(); - ASSERT_SAME_TYPE(decltype(end.base()), std::ranges::sentinel_t); - assert(base(end.base()) == globalBuff + 8); + auto it = tv.end(); + using It = decltype(it); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const forward_iterator&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), forward_iterator); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const forward_iterator&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const forward_iterator&); + assert(base(it.base()) == globalBuff + 8); + assert(base(std::move(it).base()) == globalBuff + 8); static_assert(!HasConstQualifiedEnd); } { using TransformView = std::ranges::transform_view; static_assert(!std::ranges::common_range); TransformView tv; - auto end = tv.end(); - ASSERT_SAME_TYPE(decltype(end.base()), std::ranges::sentinel_t); - assert(base(base(end.base())) == globalBuff + 8); + auto sent = tv.end(); + using Sent = decltype(sent); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + assert(base(base(sent.base())) == globalBuff + 8); + assert(base(base(std::move(sent).base())) == globalBuff + 8); static_assert(!HasConstQualifiedEnd); } { using TransformView = std::ranges::transform_view; static_assert(!std::ranges::common_range); TransformView tv; - auto end = tv.end(); - ASSERT_SAME_TYPE(decltype(end.base()), std::ranges::sentinel_t); - assert(base(base(end.base())) == globalBuff + 8); - auto cend = std::as_const(tv).end(); - ASSERT_SAME_TYPE(decltype(cend.base()), std::ranges::sentinel_t); - assert(base(base(cend.base())) == globalBuff + 8); + auto sent = tv.end(); + using Sent = decltype(sent); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(sent).base()), sentinel_wrapper>); + assert(base(base(sent.base())) == globalBuff + 8); + assert(base(base(std::move(sent).base())) == globalBuff + 8); + + auto csent = std::as_const(tv).end(); + using CSent = decltype(csent); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), sentinel_wrapper>); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), sentinel_wrapper>); + assert(base(base(csent.base())) == globalBuff + 8); + assert(base(base(std::move(csent).base())) == globalBuff + 8); } { using TransformView = std::ranges::transform_view; static_assert(std::ranges::common_range); TransformView tv; - auto end = tv.end(); - ASSERT_SAME_TYPE(decltype(end.base()), std::ranges::sentinel_t); - assert(end.base() == globalBuff + 8); + auto it = tv.end(); + using It = decltype(it); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int*); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + assert(base(it.base()) == globalBuff + 8); + assert(base(std::move(it).base()) == globalBuff + 8); static_assert(!HasConstQualifiedEnd); } { using TransformView = std::ranges::transform_view; static_assert(std::ranges::common_range); TransformView tv; - auto end = tv.end(); - ASSERT_SAME_TYPE(decltype(end.base()), std::ranges::sentinel_t); - assert(end.base() == globalBuff + 8); - auto cend = std::as_const(tv).end(); - ASSERT_SAME_TYPE(decltype(cend.base()), std::ranges::sentinel_t); - assert(cend.base() == globalBuff + 8); + auto it = tv.end(); + using It = decltype(it); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int*); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + assert(base(it.base()) == globalBuff + 8); + assert(base(std::move(it).base()) == globalBuff + 8); + + auto csent = std::as_const(tv).end(); + using CSent = decltype(csent); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), int*); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(csent).base()), int* const&); + assert(base(base(csent.base())) == globalBuff + 8); + assert(base(base(std::move(csent).base())) == globalBuff + 8); } return true; } Index: libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp +++ libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp @@ -17,31 +17,32 @@ #include "test_macros.h" #include "../types.h" -template -concept HasBase = requires(It it) { - static_cast(it).base(); -}; - constexpr bool test() { { using TransformView = std::ranges::transform_view; TransformView tv; - auto begin = tv.begin(); - ASSERT_SAME_TYPE(decltype(begin.base()), int*); - assert(begin.base() == globalBuff); - ASSERT_SAME_TYPE(decltype(std::move(begin).base()), int*); - assert(std::move(begin).base() == globalBuff); + auto it = tv.begin(); + using It = decltype(it); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int*); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), int* const&); + ASSERT_NOEXCEPT(it.base()); + assert(base(it.base()) == globalBuff); + assert(base(std::move(it).base()) == globalBuff); } { using TransformView = std::ranges::transform_view; TransformView tv; - auto begin = tv.begin(); - static_assert(!HasBase); - static_assert(HasBase); - static_assert(!HasBase); - static_assert(!HasBase); - std::same_as> auto it = std::move(begin).base(); - assert(base(it) == globalBuff); + auto it = tv.begin(); + using It = decltype(it); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const cpp20_input_iterator&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), cpp20_input_iterator); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const cpp20_input_iterator&); + ASSERT_SAME_TYPE(decltype(static_cast(it).base()), const cpp20_input_iterator&); + ASSERT_NOEXCEPT(it.base()); + assert(base(it.base()) == globalBuff); + assert(base(std::move(it).base()) == globalBuff); } return true; } Index: libcxx/test/std/ranges/range.adaptors/range.transform/types.h =================================================================== --- libcxx/test/std/ranges/range.adaptors/range.transform/types.h +++ libcxx/test/std/ranges/range.adaptors/range.transform/types.h @@ -46,8 +46,8 @@ constexpr explicit ForwardView(int* ptr = globalBuff) : ptr_(ptr) {} constexpr ForwardView(ForwardView&&) = default; constexpr ForwardView& operator=(ForwardView&&) = default; - constexpr auto begin() const { return ForwardIter(ptr_); } - constexpr auto end() const { return ForwardIter(ptr_ + 8); } + constexpr auto begin() const { return forward_iterator(ptr_); } + constexpr auto end() const { return forward_iterator(ptr_ + 8); } }; static_assert(std::ranges::view); static_assert(std::ranges::forward_range);