diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h --- a/libcxx/include/__iterator/counted_iterator.h +++ b/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_); } diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h --- a/libcxx/include/__ranges/transform_view.h +++ b/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_; } diff --git a/libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp b/libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp +++ b/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&); diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp --- a/libcxx/test/std/ranges/range.adaptors/range.transform/end.pass.cpp +++ b/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; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp --- a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp +++ b/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; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h --- a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h +++ b/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);