Skip to content

Commit c261d69

Browse files
committed
fixup! WIP: [libc++][ranges] Implement ranges::stride_view.
Clean up the iterator increment tests. Signed-off-by: Will Hawkins <[email protected]>
1 parent 4b8c86f commit c261d69

File tree

3 files changed

+98
-9
lines changed

3 files changed

+98
-9
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// constexpr __iterator& operator--()
12+
// constexpr __iterator operator--(int)
13+
14+
#include <ranges>
15+
#include <vector>
16+
17+
#include "../types.h"
18+
19+
template <class T>
20+
concept CanPostDecrement = std::is_same_v<T, decltype(std::declval<T>()--)> && requires(T& t) { t--; };
21+
template <class T>
22+
concept CanPreDecrement = std::is_same_v<T, decltype(--(std::declval<T>()))> && requires(T& t) { --t; };
23+
24+
// What operators are valid for an iterator derived from a stride view
25+
// over an input view.
26+
using InputView = BasicTestView<cpp17_input_iterator<int*>, sized_sentinel<cpp17_input_iterator<int*>>>;
27+
using StrideViewOverInputViewIterator = std::ranges::iterator_t<std::ranges::stride_view<InputView>>;
28+
29+
static_assert(!std::ranges::bidirectional_range<InputView>);
30+
static_assert(!CanPostDecrement<StrideViewOverInputViewIterator>);
31+
static_assert(!CanPreDecrement<StrideViewOverInputViewIterator>);
32+
33+
// What operators are valid for an iterator derived from a stride view
34+
// over a forward view.
35+
using ForwardView = BasicTestView<forward_iterator<int*>, sized_sentinel<forward_iterator<int*>>>;
36+
using StrideViewOverForwardViewIterator = std::ranges::iterator_t<std::ranges::stride_view<ForwardView>>;
37+
38+
static_assert(!std::ranges::bidirectional_range<ForwardView>);
39+
static_assert(!CanPostDecrement<StrideViewOverForwardViewIterator>);
40+
static_assert(!CanPostDecrement<StrideViewOverForwardViewIterator>);
41+
42+
// What operators are valid for an iterator derived from a stride view
43+
// over a bidirectional view.
44+
using BidirectionalView = BasicTestView<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>;
45+
using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t<std::ranges::stride_view<BidirectionalView>>;
46+
47+
static_assert(std::ranges::bidirectional_range<BidirectionalView>);
48+
static_assert(CanPostDecrement<StrideViewOverBidirectionalViewIterator>);
49+
static_assert(CanPostDecrement<StrideViewOverBidirectionalViewIterator>);
50+
51+
// What operators are valid for an iterator derived from a stride view
52+
// over a random access view.
53+
using RandomAccessView = BasicTestView<random_access_iterator<int*>>;
54+
using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t<std::ranges::stride_view<RandomAccessView>>;
55+
56+
static_assert(std::ranges::bidirectional_range<RandomAccessView>);
57+
static_assert(CanPostDecrement<StrideViewOverRandomAccessViewIterator>);
58+
static_assert(CanPostDecrement<StrideViewOverRandomAccessViewIterator>);
59+
60+
template <typename Iter, typename Difference>
61+
requires(std::bidirectional_iterator<Iter>)
62+
constexpr bool test_operator_decrement(Iter begin, Iter end, Difference delta) {
63+
using Base = BasicTestView<Iter, Iter>;
64+
65+
auto base_view_offset_zero = Base(begin, end);
66+
// Because of the requires on the Iter template type, we are sure
67+
// that the type of sv_incr_one is a bidirectional range.
68+
auto sv_incr_diff = std::ranges::stride_view(base_view_offset_zero, delta);
69+
auto sv_incr_end = sv_incr_diff.end();
70+
71+
// Recreate the "missing" calculation here -- to make sure that it matches.
72+
auto missing = delta - (std::ranges::distance(base_view_offset_zero) % delta) % delta;
73+
74+
auto sought = end + (missing - delta);
75+
76+
assert(*sought == *(--sv_incr_end));
77+
assert(*sought == *(sv_incr_end));
78+
79+
sv_incr_end = sv_incr_diff.end();
80+
sv_incr_end--;
81+
assert(*(end + (missing - delta)) == *(sv_incr_end));
82+
83+
return true;
84+
}
85+
86+
int main(int, char**) {
87+
constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
88+
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
89+
test_operator_decrement(vec.begin(), vec.end(), 3);
90+
test_operator_decrement(arr, arr + 11, 3);
91+
92+
return 0;
93+
}

libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <vector>
1717

1818
#include "../types.h"
19-
#include "test_iterators.h"
2019

2120
template <class T>
2221
concept CanPostIncrementVoid = std::is_same_v<void, decltype(std::declval<T>()++)> && requires(T& t) { t++; };
@@ -43,9 +42,6 @@ template <typename Iter>
4342
requires std::sized_sentinel_for<Iter, Iter> && (!std::forward_iterator<Iter>)
4443
constexpr bool test_non_forward_operator_increment(Iter zero_begin, Iter three_begin, Iter end) {
4544
using Base = BasicTestView<Iter, Iter>;
46-
using StrideViewIterator = std::ranges::iterator_t<std::ranges::stride_view<Base>>;
47-
static_assert(std::weakly_incrementable<StrideViewIterator>);
48-
static_assert(!std::ranges::forward_range<Base>);
4945

5046
auto base_view_offset_zero = Base(zero_begin, end);
5147
auto base_view_offset_three = Base(three_begin, end);

libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static_assert(!std::three_way_comparable<UnEqualableView>);
235235

236236
template <typename Iter>
237237
requires std::sized_sentinel_for<Iter, Iter> && (!std::forward_iterator<Iter>)
238-
constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) {
238+
constexpr bool test_non_forward_operator_plus(Iter zero_begin, Iter one_begin, Iter end) {
239239
using Base = BasicTestView<Iter, Iter>;
240240
// Test the non-forward-range operator- between two iterators (i.e., ceil) and an
241241
// iterator and a default sentinel.
@@ -311,7 +311,7 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin,
311311
}
312312

313313
template <std::forward_iterator Iter, typename difference_type>
314-
constexpr bool test_forward_operator_minus(Iter begin, Iter end, difference_type distance) {
314+
constexpr bool test_forward_operator_plus(Iter begin, Iter end, difference_type distance) {
315315
// Test the forward-range operator- between two iterators (i.e., no ceil) and
316316
// an iterator and a default sentinel.
317317
using Base = BasicTestView<Iter, Iter>;
@@ -420,13 +420,13 @@ int main(int, char**) {
420420
{
421421
constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
422422
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
423-
test_forward_operator_minus(arr, arr + 11, 4);
424-
test_forward_operator_minus(vec.begin(), vec.end(), 4);
423+
test_forward_operator_plus(arr, arr + 11, 4);
424+
test_forward_operator_plus(vec.begin(), vec.end(), 4);
425425
}
426426

427427
{
428428
int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
429-
test_non_forward_operator_minus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10));
429+
test_non_forward_operator_plus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10));
430430
}
431431

432432
test_properly_handling_missing();

0 commit comments

Comments
 (0)