Skip to content

Commit 59d7c14

Browse files
committed
iterator: operator-(iterator, iterator); concept
1 parent 0e92ed3 commit 59d7c14

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

libcxx/include/__ranges/cartesian_product_view.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ concept cartesian_product_is_bidirectional =
4646
(bidirectional_range<__maybe_const<Const, First>> && ... &&
4747
(bidirectional_range<__maybe_const<Const, Vs>> && cartesian_product_common_arg<__maybe_const<Const, Vs>>));
4848

49+
template <class... Vs>
50+
concept cartesian_product_is_sized = (sized_range<Vs> && ...);
51+
52+
template <bool Const, template <class> class FirstSent, class First, class... Vs>
53+
concept cartesian_is_sized_sentinel =
54+
(sized_sentinel_for<FirstSent<__maybe_const<Const, First>>, iterator_t<__maybe_const<Const, First>>> && ... &&
55+
(sized_range<__maybe_const<Const, Vs>> &&
56+
sized_sentinel_for<iterator_t<__maybe_const<Const, Vs>>, iterator_t<__maybe_const<Const, Vs>>>));
57+
4958
template <cartesian_product_common_arg R>
5059
constexpr auto cartesian_common_arg_end(R& r) {
5160
if constexpr (common_range<R>) {
@@ -203,6 +212,12 @@ class cartesian_product_view<First, Vs...>::iterator {
203212
return iterator(x) -= y;
204213
}
205214

215+
friend constexpr iterator operator-(const iterator& x, const iterator& y)
216+
requires cartesian_product_is_random_access<Const, First, Vs...>
217+
{
218+
return x.distance_from(y.current_);
219+
}
220+
206221
private:
207222
using Parent = __maybe_const<Const, cartesian_product_view>;
208223
Parent* parent_ = nullptr;
@@ -279,6 +294,27 @@ class cartesian_product_view<First, Vs...>::iterator {
279294
return at_end<N - 1>();
280295
return false;
281296
}
297+
298+
template <class Tuple>
299+
constexpr difference_type distance_from(const Tuple& t) const {
300+
constexpr auto seq = std::make_integer_sequence<int, sizeof...(Vs) + 1>{};
301+
constexpr auto scaled_sum = [&t, this]<int... Ints>(std::integer_sequence<int, Ints...>) -> difference_type {
302+
return (scaled_distance<Ints>(t) + ...);
303+
};
304+
return scaled_sum(seq);
305+
}
306+
307+
template <auto N>
308+
constexpr difference_type scaled_size() const {
309+
if constexpr (N <= sizeof...(Vs))
310+
return static_cast<difference_type>(ranges::size(std::get<N>(parent_->bases_))) * scaled_size<N + 1>();
311+
return static_cast<difference_type>(1);
312+
}
313+
314+
template <auto N, class Tuple>
315+
constexpr difference_type scaled_distance(const Tuple& t) const {
316+
return static_cast<difference_type>(std::get<N>(current_) - std::get<N>(t)) * scaled_size<N + 1>();
317+
}
282318
};
283319

284320
} // namespace ranges

0 commit comments

Comments
 (0)