Skip to content

Commit

Permalink
span: Implement resolution to LWG-3320
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
miscco committed Feb 26, 2020
1 parent b190cb5 commit 8366ac5
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 135 deletions.
65 changes: 11 additions & 54 deletions stl/inc/span
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ struct _Span_iterator {
using pointer = _Ty*;
using reference = _Ty&;

_NODISCARD constexpr operator _Span_iterator<const _Ty>() 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");
Expand Down Expand Up @@ -141,21 +133,13 @@ struct _Span_iterator {
return _Tmp;
}

// clang-format off
#ifdef __cpp_lib_concepts
template <class _Ty2>
requires same_as<remove_cv_t<_Ty2>, value_type>
#else // ^^^ use concepts / no concepts vvv
template <class _Ty2, enable_if_t<is_same_v<remove_cv_t<_Ty2>, 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);
Expand Down Expand Up @@ -359,18 +343,16 @@ struct _Is_span_compatible_range : bool_constant<conjunction_v<
template <class _Ty, size_t _Extent = dynamic_extent>
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<const _Ty>;
using reverse_iterator = _STD reverse_iterator<iterator>;
using const_reverse_iterator = _STD reverse_iterator<const_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<iterator>;

static constexpr size_type extent = _Extent;

Expand Down Expand Up @@ -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()};
}
Expand All @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,12 @@ language.support\support.limits\support.limits.general\string.version.pass.cpp
# Test bug. See LWG-3099 "is_assignable<Incomplete&, Incomplete&>"
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
Expand Down
66 changes: 1 addition & 65 deletions tests/std/tests/P0122R7_span/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,52 +61,20 @@ static_assert(is_same_v<span<const int, 3>::const_pointer, const int*>);
static_assert(is_same_v<span<const int, 3>::reference, const int&>);
static_assert(is_same_v<span<const int, 3>::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_traits<span<int>::iterator>::pointer, int*>);
static_assert(is_same_v<iterator_traits<span<int>::const_iterator>::pointer, const int*>);
static_assert(is_same_v<span<int>::reverse_iterator, reverse_iterator<span<int>::iterator>>);
static_assert(is_same_v<span<int>::const_reverse_iterator, reverse_iterator<span<int>::const_iterator>>);

static_assert(is_same_v<iterator_traits<span<int, 3>::iterator>::pointer, int*>);
static_assert(is_same_v<iterator_traits<span<int, 3>::const_iterator>::pointer, const int*>);
static_assert(is_same_v<span<int, 3>::reverse_iterator, reverse_iterator<span<int, 3>::iterator>>);
static_assert(is_same_v<span<int, 3>::const_reverse_iterator, reverse_iterator<span<int, 3>::const_iterator>>);

static_assert(is_same_v<iterator_traits<span<const int>::iterator>::pointer, const int*>);
static_assert(is_same_v<iterator_traits<span<const int>::const_iterator>::pointer, const int*>);
static_assert(is_same_v<span<const int>::reverse_iterator, reverse_iterator<span<const int>::iterator>>);
static_assert(is_same_v<span<const int>::const_reverse_iterator, reverse_iterator<span<const int>::const_iterator>>);

static_assert(is_same_v<iterator_traits<span<const int, 3>::iterator>::pointer, const int*>);
static_assert(is_same_v<iterator_traits<span<const int, 3>::const_iterator>::pointer, const int*>);
static_assert(is_same_v<span<const int, 3>::reverse_iterator, reverse_iterator<span<const int, 3>::iterator>>);
static_assert(
is_same_v<span<const int, 3>::const_reverse_iterator, reverse_iterator<span<const int, 3>::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<span<int>::iterator, span<int>::const_iterator>);
static_assert(sized_sentinel_for<span<int>::iterator, span<int>::const_iterator>);
static_assert(totally_ordered_with<span<const int>::iterator, span<const int>::const_iterator>);
static_assert(sized_sentinel_for<span<const int>::iterator, span<const int>::const_iterator>);
static_assert(totally_ordered_with<span<int, 3>::iterator, span<int, 3>::const_iterator>);
static_assert(sized_sentinel_for<span<int, 3>::iterator, span<int, 3>::const_iterator>);
static_assert(totally_ordered_with<span<const int, 3>::iterator, span<const int, 3>::const_iterator>);
static_assert(sized_sentinel_for<span<const int, 3>::iterator, span<const int, 3>::const_iterator>);

#if _ITERATOR_DEBUG_LEVEL >= 1
static_assert(_Range_verifiable_v<span<int>::iterator, span<int>::const_iterator>);
static_assert(_Range_verifiable_v<span<int>::const_iterator, span<int>::iterator>);
static_assert(_Range_verifiable_v<span<const int>::iterator, span<const int>::const_iterator>);
static_assert(_Range_verifiable_v<span<const int>::const_iterator, span<const int>::iterator>);
static_assert(_Range_verifiable_v<span<int, 3>::iterator, span<int, 3>::const_iterator>);
static_assert(_Range_verifiable_v<span<int, 3>::const_iterator, span<int, 3>::iterator>);
static_assert(_Range_verifiable_v<span<const int, 3>::iterator, span<const int, 3>::const_iterator>);
static_assert(_Range_verifiable_v<span<const int, 3>::const_iterator, span<const int, 3>::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<span<int>>);
static_assert(ranges::enable_safe_range<span<int, 3>>);
#endif // __cpp_lib_concepts
Expand All @@ -124,16 +92,12 @@ static_assert(is_same_v<tuple_element_t<2, const span<const int, 3>>, const int>
// that span and its iterator types are trivially copyable.
static_assert(is_trivially_copyable_v<span<int>>);
static_assert(is_trivially_copyable_v<span<int>::iterator>);
static_assert(is_trivially_copyable_v<span<int>::const_iterator>);
static_assert(is_trivially_copyable_v<span<int, 3>>);
static_assert(is_trivially_copyable_v<span<int, 3>::iterator>);
static_assert(is_trivially_copyable_v<span<int, 3>::const_iterator>);
static_assert(is_trivially_copyable_v<span<const int>>);
static_assert(is_trivially_copyable_v<span<const int>::iterator>);
static_assert(is_trivially_copyable_v<span<const int>::const_iterator>);
static_assert(is_trivially_copyable_v<span<const int, 3>>);
static_assert(is_trivially_copyable_v<span<const int, 3>::iterator>);
static_assert(is_trivially_copyable_v<span<const int, 3>::const_iterator>);

struct Base {};
struct Derived : Base {};
Expand Down Expand Up @@ -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()));
Expand All @@ -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);
Expand Down Expand Up @@ -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<decltype(sp_dyn.begin()), span<int>::iterator>);
static_assert(is_same_v<decltype(sp_nine.begin()), span<int, 9>::iterator>);
static_assert(is_same_v<decltype(sp_dyn.end()), span<int>::iterator>);
static_assert(is_same_v<decltype(sp_nine.end()), span<int, 9>::iterator>);
static_assert(is_same_v<decltype(sp_dyn.cbegin()), span<int>::const_iterator>);
static_assert(is_same_v<decltype(sp_nine.cbegin()), span<int, 9>::const_iterator>);
static_assert(is_same_v<decltype(sp_dyn.cend()), span<int>::const_iterator>);
static_assert(is_same_v<decltype(sp_nine.cend()), span<int, 9>::const_iterator>);
static_assert(is_same_v<decltype(sp_dyn.rbegin()), span<int>::reverse_iterator>);
static_assert(is_same_v<decltype(sp_nine.rbegin()), span<int, 9>::reverse_iterator>);
static_assert(is_same_v<decltype(sp_dyn.rend()), span<int>::reverse_iterator>);
static_assert(is_same_v<decltype(sp_nine.rend()), span<int, 9>::reverse_iterator>);
static_assert(is_same_v<decltype(sp_dyn.crbegin()), span<int>::const_reverse_iterator>);
static_assert(is_same_v<decltype(sp_nine.crbegin()), span<int, 9>::const_reverse_iterator>);
static_assert(is_same_v<decltype(sp_dyn.crend()), span<int>::const_reverse_iterator>);
static_assert(is_same_v<decltype(sp_nine.crend()), span<int, 9>::const_reverse_iterator>);

static_assert(noexcept(get<5>(sp_nine)));
assert(get<5>(sp_nine) == 60);
Expand Down
16 changes: 0 additions & 16 deletions tests/std/tests/P0896R4_ranges_range_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,12 +968,8 @@ STATIC_ASSERT(!ranges::view<std::string_view const&>);

STATIC_ASSERT(test_begin<std::span<int>, std::span<int>::iterator>());
STATIC_ASSERT(test_end<std::span<int>, std::span<int>::iterator>());
STATIC_ASSERT(test_cbegin<std::span<int>, std::span<int>::iterator>());
STATIC_ASSERT(test_cend<std::span<int>, std::span<int>::iterator>());
STATIC_ASSERT(test_rbegin<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_rend<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crbegin<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crend<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_size<std::span<int>, std::size_t>());
STATIC_ASSERT(test_empty<std::span<int>, true>());
STATIC_ASSERT(test_data<std::span<int>, int*>());
Expand All @@ -983,12 +979,8 @@ STATIC_ASSERT(ranges::view<std::span<int>>);

STATIC_ASSERT(test_begin<std::span<int> const, std::span<int>::iterator>());
STATIC_ASSERT(test_end<std::span<int> const, std::span<int>::iterator>());
STATIC_ASSERT(test_cbegin<std::span<int> const, std::span<int>::iterator>());
STATIC_ASSERT(test_cend<std::span<int> const, std::span<int>::iterator>());
STATIC_ASSERT(test_rbegin<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_rend<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crbegin<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crend<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_size<std::span<int> const, std::size_t>());
STATIC_ASSERT(test_empty<std::span<int> const, true>());
STATIC_ASSERT(test_data<std::span<int> const, int*>());
Expand All @@ -998,12 +990,8 @@ STATIC_ASSERT(!ranges::view<std::span<int> const>);

STATIC_ASSERT(test_begin<std::span<int>&, std::span<int>::iterator>());
STATIC_ASSERT(test_end<std::span<int>&, std::span<int>::iterator>());
STATIC_ASSERT(test_cbegin<std::span<int>&, std::span<int>::iterator>());
STATIC_ASSERT(test_cend<std::span<int>&, std::span<int>::iterator>());
STATIC_ASSERT(test_rbegin<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_rend<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crbegin<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crend<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_size<std::span<int>&, std::size_t>());
STATIC_ASSERT(test_empty<std::span<int>&, true>());
STATIC_ASSERT(test_data<std::span<int>&, int*>());
Expand All @@ -1013,12 +1001,8 @@ STATIC_ASSERT(!ranges::view<std::span<int>&>);

STATIC_ASSERT(test_begin<std::span<int> const&, std::span<int>::iterator>());
STATIC_ASSERT(test_end<std::span<int> const&, std::span<int>::iterator>());
STATIC_ASSERT(test_cbegin<std::span<int> const&, std::span<int>::iterator>());
STATIC_ASSERT(test_cend<std::span<int> const&, std::span<int>::iterator>());
STATIC_ASSERT(test_rbegin<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_rend<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crbegin<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_crend<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
STATIC_ASSERT(test_size<std::span<int> const&, std::size_t>());
STATIC_ASSERT(test_empty<std::span<int> const&, true>());
STATIC_ASSERT(test_data<std::span<int> const&, int*>());
Expand Down

0 comments on commit 8366ac5

Please sign in to comment.