From 8366ac5d551ee87b463b93dd95a9f5d792cce1e2 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 26 Feb 2020 08:30:19 +0100 Subject: [PATCH] span: Implement resolution to LWG-3320 In the resolution of LWG-3320 the const_iterator and const_reverse_iterator typedefs were removed together with the respective methods c{r}begin() and c{r}end(). Adopt the tests accordingly and skip the tests from libc++ until they remove them. --- stl/inc/span | 65 ++++-------------- tests/libcxx/skipped_tests.txt | 6 ++ tests/std/tests/P0122R7_span/test.cpp | 66 +------------------ .../P0896R4_ranges_range_machinery/test.cpp | 16 ----- 4 files changed, 18 insertions(+), 135 deletions(-) diff --git a/stl/inc/span b/stl/inc/span index ae635c77d2a..346d726bd98 100644 --- a/stl/inc/span +++ b/stl/inc/span @@ -43,14 +43,6 @@ struct _Span_iterator { using pointer = _Ty*; using reference = _Ty&; - _NODISCARD constexpr operator _Span_iterator() const noexcept { -#if _ITERATOR_DEBUG_LEVEL >= 1 - return {_Myptr, _Mybegin, _Myend}; -#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv - return {_Myptr}; -#endif // _ITERATOR_DEBUG_LEVEL - } - _NODISCARD constexpr reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Mybegin, "cannot dereference value-initialized span iterator"); @@ -141,21 +133,13 @@ struct _Span_iterator { return _Tmp; } - // clang-format off -#ifdef __cpp_lib_concepts - template - requires same_as, value_type> -#else // ^^^ use concepts / no concepts vvv - template , value_type>, int> = 0> -#endif // __cpp_lib_concepts - _NODISCARD constexpr difference_type operator-(const _Span_iterator<_Ty2>& _Right) const noexcept { + _NODISCARD constexpr difference_type operator-(const _Span_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY( _Mybegin == _Right._Mybegin && _Myend == _Right._Myend, "cannot subtract incompatible span iterators"); #endif // _ITERATOR_DEBUG_LEVEL >= 1 return _Myptr - _Right._Myptr; } - // clang-format on _NODISCARD constexpr reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); @@ -359,18 +343,16 @@ struct _Is_span_compatible_range : bool_constant class span : public _Span_extent_type<_Extent> { public: - using element_type = _Ty; - using value_type = remove_cv_t<_Ty>; - using size_type = size_t; - using difference_type = ptrdiff_t; - using pointer = _Ty*; - using const_pointer = const _Ty*; - using reference = _Ty&; - using const_reference = const _Ty&; - using iterator = _Span_iterator<_Ty>; - using const_iterator = _Span_iterator; - using reverse_iterator = _STD reverse_iterator; - using const_reverse_iterator = _STD reverse_iterator; + using element_type = _Ty; + using value_type = remove_cv_t<_Ty>; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = _Ty*; + using const_pointer = const _Ty*; + using reference = _Ty&; + using const_reference = const _Ty&; + using iterator = _Span_iterator<_Ty>; + using reverse_iterator = _STD reverse_iterator; static constexpr size_type extent = _Extent; @@ -612,23 +594,6 @@ public: #endif // _ITERATOR_DEBUG_LEVEL } - _NODISCARD constexpr const_iterator cbegin() const noexcept { -#if _ITERATOR_DEBUG_LEVEL >= 1 - return {_Mydata, _Mydata, _Mydata + this->size()}; -#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv - return {_Mydata}; -#endif // _ITERATOR_DEBUG_LEVEL - } - - _NODISCARD constexpr const_iterator cend() const noexcept { - const auto _End = _Mydata + this->size(); -#if _ITERATOR_DEBUG_LEVEL >= 1 - return {_End, _Mydata, _End}; -#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv - return {_End}; -#endif // _ITERATOR_DEBUG_LEVEL - } - _NODISCARD constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } @@ -637,14 +602,6 @@ public: return reverse_iterator{begin()}; } - _NODISCARD constexpr const_reverse_iterator crbegin() const noexcept { - return const_reverse_iterator{cend()}; - } - - _NODISCARD constexpr const_reverse_iterator crend() const noexcept { - return const_reverse_iterator{cbegin()}; - } - _NODISCARD constexpr pointer _Unchecked_begin() const noexcept { return _Mydata; } diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 633e6aada21..12567f0b4ff 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -666,6 +666,12 @@ language.support\support.limits\support.limits.general\string.version.pass.cpp # Test bug. See LWG-3099 "is_assignable" utilities\utility\pairs\pairs.pair\assign_pair.pass.cpp +# Test bug after LWG-3320 "span::cbegin/cend methods produce different results than std::[ranges::]cbegin/cend" was accepted. +containers\views\span.iterators\cbegin.pass.cpp +containers\views\span.iterators\cend.pass.cpp +containers\views\span.iterators\crbegin.pass.cpp +containers\views\span.iterators\crend.pass.cpp + # Not yet analyzed, likely bogus tests. Appears to be timing assumptions. thread\futures\futures.async\async.pass.cpp thread\futures\futures.shared_future\wait_for.pass.cpp diff --git a/tests/std/tests/P0122R7_span/test.cpp b/tests/std/tests/P0122R7_span/test.cpp index b9318fae003..6743d84cb81 100644 --- a/tests/std/tests/P0122R7_span/test.cpp +++ b/tests/std/tests/P0122R7_span/test.cpp @@ -61,52 +61,20 @@ static_assert(is_same_v::const_pointer, const int*>); static_assert(is_same_v::reference, const int&>); static_assert(is_same_v::const_reference, const int&>); -// The iterators are thoroughly tested by P0896R4_ranges_range_machinery... +// The iterators are thoroughly tested by P0896R4_ranges_range_machinery static_assert(is_same_v::iterator>::pointer, int*>); -static_assert(is_same_v::const_iterator>::pointer, const int*>); static_assert(is_same_v::reverse_iterator, reverse_iterator::iterator>>); -static_assert(is_same_v::const_reverse_iterator, reverse_iterator::const_iterator>>); static_assert(is_same_v::iterator>::pointer, int*>); -static_assert(is_same_v::const_iterator>::pointer, const int*>); static_assert(is_same_v::reverse_iterator, reverse_iterator::iterator>>); -static_assert(is_same_v::const_reverse_iterator, reverse_iterator::const_iterator>>); static_assert(is_same_v::iterator>::pointer, const int*>); -static_assert(is_same_v::const_iterator>::pointer, const int*>); static_assert(is_same_v::reverse_iterator, reverse_iterator::iterator>>); -static_assert(is_same_v::const_reverse_iterator, reverse_iterator::const_iterator>>); static_assert(is_same_v::iterator>::pointer, const int*>); -static_assert(is_same_v::const_iterator>::pointer, const int*>); static_assert(is_same_v::reverse_iterator, reverse_iterator::iterator>>); -static_assert( - is_same_v::const_reverse_iterator, reverse_iterator::const_iterator>>); #ifdef __cpp_lib_concepts -#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L -// ... except for cross-type iterator operations. -static_assert(totally_ordered_with::iterator, span::const_iterator>); -static_assert(sized_sentinel_for::iterator, span::const_iterator>); -static_assert(totally_ordered_with::iterator, span::const_iterator>); -static_assert(sized_sentinel_for::iterator, span::const_iterator>); -static_assert(totally_ordered_with::iterator, span::const_iterator>); -static_assert(sized_sentinel_for::iterator, span::const_iterator>); -static_assert(totally_ordered_with::iterator, span::const_iterator>); -static_assert(sized_sentinel_for::iterator, span::const_iterator>); - -#if _ITERATOR_DEBUG_LEVEL >= 1 -static_assert(_Range_verifiable_v::iterator, span::const_iterator>); -static_assert(_Range_verifiable_v::const_iterator, span::iterator>); -static_assert(_Range_verifiable_v::iterator, span::const_iterator>); -static_assert(_Range_verifiable_v::const_iterator, span::iterator>); -static_assert(_Range_verifiable_v::iterator, span::const_iterator>); -static_assert(_Range_verifiable_v::const_iterator, span::iterator>); -static_assert(_Range_verifiable_v::iterator, span::const_iterator>); -static_assert(_Range_verifiable_v::const_iterator, span::iterator>); -#endif // _ITERATOR_DEBUG_LEVEL >= 1 -#endif // defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L - static_assert(ranges::enable_safe_range>); static_assert(ranges::enable_safe_range>); #endif // __cpp_lib_concepts @@ -124,16 +92,12 @@ static_assert(is_same_v>, const int> // that span and its iterator types are trivially copyable. static_assert(is_trivially_copyable_v>); static_assert(is_trivially_copyable_v::iterator>); -static_assert(is_trivially_copyable_v::const_iterator>); static_assert(is_trivially_copyable_v>); static_assert(is_trivially_copyable_v::iterator>); -static_assert(is_trivially_copyable_v::const_iterator>); static_assert(is_trivially_copyable_v>); static_assert(is_trivially_copyable_v::iterator>); -static_assert(is_trivially_copyable_v::const_iterator>); static_assert(is_trivially_copyable_v>); static_assert(is_trivially_copyable_v::iterator>); -static_assert(is_trivially_copyable_v::const_iterator>); struct Base {}; struct Derived : Base {}; @@ -937,12 +901,8 @@ constexpr bool test() { static_assert(noexcept(sp_dyn.data())); static_assert(noexcept(sp_dyn.begin())); static_assert(noexcept(sp_dyn.end())); - static_assert(noexcept(sp_dyn.cbegin())); - static_assert(noexcept(sp_dyn.cend())); static_assert(noexcept(sp_dyn.rbegin())); static_assert(noexcept(sp_dyn.rend())); - static_assert(noexcept(sp_dyn.crbegin())); - static_assert(noexcept(sp_dyn.crend())); static_assert(noexcept(sp_nine.size())); static_assert(noexcept(sp_nine.size_bytes())); @@ -953,12 +913,8 @@ constexpr bool test() { static_assert(noexcept(sp_nine.data())); static_assert(noexcept(sp_nine.begin())); static_assert(noexcept(sp_nine.end())); - static_assert(noexcept(sp_nine.cbegin())); - static_assert(noexcept(sp_nine.cend())); static_assert(noexcept(sp_nine.rbegin())); static_assert(noexcept(sp_nine.rend())); - static_assert(noexcept(sp_nine.crbegin())); - static_assert(noexcept(sp_nine.crend())); assert(sp_dyn.size() == 9); assert(sp_nine.size() == 9); @@ -996,40 +952,20 @@ constexpr bool test() { assert(sp_dyn.end()[-2] == 80); assert(sp_nine.end()[-2] == 80); - assert(*sp_dyn.cbegin() == 10); - assert(*sp_nine.cbegin() == 10); - - assert(sp_dyn.cend()[-2] == 80); - assert(sp_nine.cend()[-2] == 80); - assert(*sp_dyn.rbegin() == 90); assert(*sp_nine.rbegin() == 90); assert(sp_dyn.rend()[-2] == 20); assert(sp_nine.rend()[-2] == 20); - assert(*sp_dyn.crbegin() == 90); - assert(*sp_nine.crbegin() == 90); - - assert(sp_dyn.crend()[-2] == 20); - assert(sp_nine.crend()[-2] == 20); - static_assert(is_same_v::iterator>); static_assert(is_same_v::iterator>); static_assert(is_same_v::iterator>); static_assert(is_same_v::iterator>); - static_assert(is_same_v::const_iterator>); - static_assert(is_same_v::const_iterator>); - static_assert(is_same_v::const_iterator>); - static_assert(is_same_v::const_iterator>); static_assert(is_same_v::reverse_iterator>); static_assert(is_same_v::reverse_iterator>); static_assert(is_same_v::reverse_iterator>); static_assert(is_same_v::reverse_iterator>); - static_assert(is_same_v::const_reverse_iterator>); - static_assert(is_same_v::const_reverse_iterator>); - static_assert(is_same_v::const_reverse_iterator>); - static_assert(is_same_v::const_reverse_iterator>); static_assert(noexcept(get<5>(sp_nine))); assert(get<5>(sp_nine) == 60); diff --git a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp index 18a386fe6ec..f3ead629e17 100644 --- a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp @@ -968,12 +968,8 @@ STATIC_ASSERT(!ranges::view); STATIC_ASSERT(test_begin, std::span::iterator>()); STATIC_ASSERT(test_end, std::span::iterator>()); -STATIC_ASSERT(test_cbegin, std::span::iterator>()); -STATIC_ASSERT(test_cend, std::span::iterator>()); STATIC_ASSERT(test_rbegin, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_rend, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crbegin, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crend, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_size, std::size_t>()); STATIC_ASSERT(test_empty, true>()); STATIC_ASSERT(test_data, int*>()); @@ -983,12 +979,8 @@ STATIC_ASSERT(ranges::view>); STATIC_ASSERT(test_begin const, std::span::iterator>()); STATIC_ASSERT(test_end const, std::span::iterator>()); -STATIC_ASSERT(test_cbegin const, std::span::iterator>()); -STATIC_ASSERT(test_cend const, std::span::iterator>()); STATIC_ASSERT(test_rbegin const, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_rend const, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crbegin const, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crend const, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_size const, std::size_t>()); STATIC_ASSERT(test_empty const, true>()); STATIC_ASSERT(test_data const, int*>()); @@ -998,12 +990,8 @@ STATIC_ASSERT(!ranges::view const>); STATIC_ASSERT(test_begin&, std::span::iterator>()); STATIC_ASSERT(test_end&, std::span::iterator>()); -STATIC_ASSERT(test_cbegin&, std::span::iterator>()); -STATIC_ASSERT(test_cend&, std::span::iterator>()); STATIC_ASSERT(test_rbegin&, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_rend&, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crbegin&, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crend&, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_size&, std::size_t>()); STATIC_ASSERT(test_empty&, true>()); STATIC_ASSERT(test_data&, int*>()); @@ -1013,12 +1001,8 @@ STATIC_ASSERT(!ranges::view&>); STATIC_ASSERT(test_begin const&, std::span::iterator>()); STATIC_ASSERT(test_end const&, std::span::iterator>()); -STATIC_ASSERT(test_cbegin const&, std::span::iterator>()); -STATIC_ASSERT(test_cend const&, std::span::iterator>()); STATIC_ASSERT(test_rbegin const&, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_rend const&, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crbegin const&, std::reverse_iterator::iterator>>()); -STATIC_ASSERT(test_crend const&, std::reverse_iterator::iterator>>()); STATIC_ASSERT(test_size const&, std::size_t>()); STATIC_ASSERT(test_empty const&, true>()); STATIC_ASSERT(test_data const&, int*>());