@@ -14,6 +14,12 @@ template <class I>
14
14
concept Countable = requires { typename iter_difference_t <remove_cvref_t <I>>; }
15
15
&& requires(I&& i, iter_difference_t <remove_cvref_t <I>> n) { views::counted (forward<I>(i), n); };
16
16
17
+ template <class I >
18
+ concept CanConstructCountedSubrange = requires { typename iter_difference_t <remove_cvref_t <I>>; }
19
+ && requires(I&& i, iter_difference_t <remove_cvref_t <I>> n) {
20
+ ranges::subrange (counted_iterator (forward<I>(i), n), default_sentinel);
21
+ };
22
+
17
23
template <input_or_output_iterator Iter>
18
24
struct convertible_difference {
19
25
constexpr convertible_difference (const int _val_) noexcept : _val(_val_) {}
@@ -31,8 +37,7 @@ struct instantiator {
31
37
32
38
template <input_or_output_iterator Iter>
33
39
static constexpr void call () {
34
- using ranges::contiguous_range, ranges::equal, ranges::iterator_t , ranges::random_access_range, ranges::size,
35
- ranges::subrange;
40
+ using ranges::equal, ranges::size, ranges::subrange;
36
41
int input[] = {13 , 42 , 1729 , -1 , -1 };
37
42
38
43
static_assert (Countable<Iter>);
@@ -41,6 +46,10 @@ struct instantiator {
41
46
auto result = ranges::views::counted (Iter{input}, convertible_difference<Iter>{3 });
42
47
if constexpr (contiguous_iterator<Iter>) {
43
48
static_assert (same_as<decltype (result), span<remove_reference_t <iter_reference_t <Iter>>, dynamic_extent>>);
49
+
50
+ const test::redifference_iterator<_Signed128, Iter> rediff_it{Iter{input}};
51
+ ranges::contiguous_range auto rediff_result = ranges::views::counted (rediff_it, _Signed128{4 });
52
+ assert (size (rediff_result) == 4 );
44
53
} else if constexpr (random_access_iterator<Iter>) {
45
54
static_assert (same_as<decltype (result), subrange<Iter, Iter>>);
46
55
} else {
@@ -53,6 +62,37 @@ struct instantiator {
53
62
}
54
63
};
55
64
65
+ // Also test GH-5183: "<ranges>: views::counted::_Choose() misses difference casting for contiguous_iterator case"
66
+ struct ExplicitCopyCtorIter {
67
+ using difference_type = int ;
68
+
69
+ ExplicitCopyCtorIter () = default ;
70
+ ExplicitCopyCtorIter (ExplicitCopyCtorIter&&) = default ;
71
+ ExplicitCopyCtorIter& operator =(ExplicitCopyCtorIter&&) = default ;
72
+ explicit ExplicitCopyCtorIter (const ExplicitCopyCtorIter&) = default;
73
+ int operator *();
74
+ ExplicitCopyCtorIter& operator ++();
75
+ void operator ++(int );
76
+ };
77
+ static_assert (!Countable<ExplicitCopyCtorIter&>);
78
+ static_assert (!CanConstructCountedSubrange<ExplicitCopyCtorIter&>);
79
+
80
+ struct ImplicitCopyOnlyIter {
81
+ using difference_type = int ;
82
+
83
+ ImplicitCopyOnlyIter () = default ;
84
+ ImplicitCopyOnlyIter (ImplicitCopyOnlyIter&&) = default ;
85
+ ImplicitCopyOnlyIter& operator =(ImplicitCopyOnlyIter&&) = default ;
86
+ explicit ImplicitCopyOnlyIter (const ImplicitCopyOnlyIter&) = delete;
87
+ template <int = 0 >
88
+ ImplicitCopyOnlyIter (const ImplicitCopyOnlyIter&);
89
+ int operator *();
90
+ ImplicitCopyOnlyIter& operator ++();
91
+ void operator ++(int );
92
+ };
93
+ static_assert (Countable<ImplicitCopyOnlyIter&>);
94
+ static_assert (CanConstructCountedSubrange<ImplicitCopyOnlyIter&>);
95
+
56
96
int main () {
57
97
static_assert (with_writable_iterators<instantiator, int >::call ());
58
98
with_writable_iterators<instantiator, int >::call ();
0 commit comments