From 4635e5e08e6a12b2d724e48326c2c6a9da42b015 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 26 Feb 2020 08:30:19 +0100 Subject: [PATCH 1/2] 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 ++ .../test.cpp | 16 ----- .../test.cpp | 1 - tests/std/tests/P0122R7_span/test.cpp | 66 +------------------ 5 files changed, 18 insertions(+), 136 deletions(-) diff --git a/stl/inc/span b/stl/inc/span index ae635c77d2..346d726bd9 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 633e6aada2..12567f0b4f 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/Dev10_709168_marking_iterators_as_checked/test.cpp b/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.cpp index c30fc5e456..a1a12d3bdd 100644 --- a/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.cpp +++ b/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.cpp @@ -108,9 +108,7 @@ STATIC_ASSERT(stl_checked == _Range_verifiable_v::iterator>); -STATIC_ASSERT(stl_checked == _Range_verifiable_v::const_iterator>); STATIC_ASSERT(stl_checked == _Range_verifiable_v::reverse_iterator>); -STATIC_ASSERT(stl_checked == _Range_verifiable_v::const_reverse_iterator>); #endif // _HAS_CXX20 STATIC_ASSERT(_Range_verifiable_v>); @@ -185,9 +183,7 @@ STATIC_ASSERT(!_Range_verifiable_v<::DerivedFrom::iterator>>); -STATIC_ASSERT(!_Range_verifiable_v<::DerivedFrom::const_iterator>>); STATIC_ASSERT(!_Range_verifiable_v<::DerivedFrom::reverse_iterator>>); -STATIC_ASSERT(!_Range_verifiable_v<::DerivedFrom::const_reverse_iterator>>); #endif // _HAS_CXX20 STATIC_ASSERT(!_Range_verifiable_v<::DerivedFrom>>); @@ -403,9 +399,7 @@ STATIC_ASSERT(test_unwrappable_for_unverified::iterator, !stl_checked>()); -STATIC_ASSERT(test_unwrappable_for_unverified::const_iterator, !stl_checked>()); STATIC_ASSERT(test_unwrappable_for_unverified::reverse_iterator, !stl_checked>()); -STATIC_ASSERT(test_unwrappable_for_unverified::const_reverse_iterator, !stl_checked>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable_for_unverified, false>()); @@ -481,9 +475,7 @@ STATIC_ASSERT(test_unwrappable()); #if _HAS_CXX20 STATIC_ASSERT(test_unwrappable::iterator, true>()); -STATIC_ASSERT(test_unwrappable::const_iterator, true>()); STATIC_ASSERT(test_unwrappable::reverse_iterator, true>()); -STATIC_ASSERT(test_unwrappable::const_reverse_iterator, true>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable, true>()); @@ -559,9 +551,7 @@ STATIC_ASSERT(test_unwrappable_for_offset::iterator, true>()); -STATIC_ASSERT(test_unwrappable_for_offset::const_iterator, true>()); STATIC_ASSERT(test_unwrappable_for_offset::reverse_iterator, true>()); -STATIC_ASSERT(test_unwrappable_for_offset::const_reverse_iterator, true>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable_for_offset, true>()); @@ -636,9 +626,7 @@ STATIC_ASSERT(test_unwrappable_for_unverified<::DerivedFrom::iterator>, false>()); -STATIC_ASSERT(test_unwrappable_for_unverified<::DerivedFrom::const_iterator>, false>()); STATIC_ASSERT(test_unwrappable_for_unverified<::DerivedFrom::reverse_iterator>, false>()); -STATIC_ASSERT(test_unwrappable_for_unverified<::DerivedFrom::const_reverse_iterator>, false>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable_for_unverified<::DerivedFrom>, false>()); @@ -713,9 +701,7 @@ STATIC_ASSERT(test_unwrappable<::DerivedFrom::iterator>, false>()); -STATIC_ASSERT(test_unwrappable<::DerivedFrom::const_iterator>, false>()); STATIC_ASSERT(test_unwrappable<::DerivedFrom::reverse_iterator>, false>()); -STATIC_ASSERT(test_unwrappable<::DerivedFrom::const_reverse_iterator>, false>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable<::DerivedFrom>, false>()); @@ -790,9 +776,7 @@ STATIC_ASSERT(test_unwrappable_for_offset<::DerivedFrom::iterator>, false>()); -STATIC_ASSERT(test_unwrappable_for_offset<::DerivedFrom::const_iterator>, false>()); STATIC_ASSERT(test_unwrappable_for_offset<::DerivedFrom::reverse_iterator>, false>()); -STATIC_ASSERT(test_unwrappable_for_offset<::DerivedFrom::const_reverse_iterator>, false>()); #endif // _HAS_CXX20 STATIC_ASSERT(test_unwrappable_for_offset<::DerivedFrom>, false>()); diff --git a/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp b/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp index c69ee30ee8..b4765400c7 100644 --- a/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp +++ b/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp @@ -166,7 +166,6 @@ int main() { #if _HAS_CXX20 test_iterator::iterator>(); - test_iterator::const_iterator>(); #endif // _HAS_CXX20 test_iterator(); diff --git a/tests/std/tests/P0122R7_span/test.cpp b/tests/std/tests/P0122R7_span/test.cpp index b9318fae00..6743d84cb8 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); From de01d6f9324c802ca1d5ae095b6fc44a243dcce7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 29 Feb 2020 01:08:52 -0800 Subject: [PATCH 2/2] Update tests/libcxx/skipped_tests.txt. --- tests/libcxx/skipped_tests.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 12567f0b4f..785b6ca1ca 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -663,15 +663,12 @@ utilities\smartptr\unique.ptr\unique.ptr.class\unique.ptr.asgn\move.pass.cpp # Test bug after LWG-3257 "Missing feature testing macro update from P0858" was accepted. language.support\support.limits\support.limits.general\string.version.pass.cpp +# Test needs to be updated for LWG-3320 removing span::const_iterator. +containers\views\types.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