148 detail::cartesian_product_cardinality<Views...>::value>
153 CPP_assert(
sizeof...(Views) != 0);
155 static constexpr auto my_cardinality =
156 detail::cartesian_product_cardinality<Views...>::value;
158 std::tuple<Views...> views_;
160 template<
bool IsConst_>
167 using constify_if = meta::const_if_c<IsConst_, T>;
168 using difference_type =
169 common_type_t<std::intmax_t, range_difference_t<Views>...>;
171 constify_if<cartesian_product_view> *
view_;
172 std::tuple<iterator_t<constify_if<Views>>...> its_;
176 auto & v = std::get<0>(
view_->views_);
177 auto & i = std::get<0>(its_);
178 auto const last = ranges::end(v);
179 RANGES_EXPECT(i != last);
182 template<std::
size_t N>
185 auto & v = std::get<N - 1>(
view_->views_);
186 auto & i = std::get<N - 1>(its_);
187 auto const last = ranges::end(v);
188 RANGES_EXPECT(i != last);
191 i = ranges::begin(v);
197 RANGES_EXPECT(
false);
199 template<std::
size_t N>
202 auto & v = std::get<N - 1>(
view_->views_);
203 auto & i = std::get<N - 1>(its_);
204 if(i == ranges::begin(v))
209 ranges::advance(i, ranges::end(v));
218 template<std::
size_t N>
221 return std::get<N - 1>(its_) == std::get<N - 1>(that.its_) &&
226 return difference_type{std::get<0>(that.its_) - std::get<0>(its_)};
228 template<std::
size_t N>
232 auto const scale = ranges::distance(std::get<N - 1>(
view_->views_));
233 auto const increment = std::get<N - 1>(that.its_) - std::get<N - 1>(its_);
234 return difference_type{d * scale + increment};
238 RANGES_EXPECT(
false);
240 RANGES_DIAGNOSTIC_PUSH
241 RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
242 template<std::
size_t N>
248 auto & i = std::get<N - 1>(its_);
249 auto const my_size =
static_cast<difference_type
>(
250 ranges::size(std::get<N - 1>(
view_->views_)));
251 auto const first = ranges::begin(std::get<N - 1>(
view_->views_));
253 auto const idx =
static_cast<difference_type
>(i - first);
254 RANGES_EXPECT(0 <= idx);
255 RANGES_EXPECT(idx < my_size || (N == 1 && idx == my_size && n < 0));
256 RANGES_EXPECT(n < INTMAX_MAX - idx);
259 auto n_div = n / my_size;
260 auto n_mod = n % my_size;
262 if(RANGES_CONSTEXPR_IF(N != 1))
271 RANGES_EXPECT(0 <= n_mod && n_mod < my_size);
273 if(RANGES_CONSTEXPR_IF(N == 1))
277 RANGES_EXPECT(n_div == 1);
278 RANGES_EXPECT(n_mod == 0);
283 RANGES_EXPECT(n_div == -1);
284 RANGES_EXPECT(n_mod == 0);
288 using D = iter_difference_t<
decltype(first)>;
289 i = first +
static_cast<D
>(n_mod);
291 RANGES_DIAGNOSTIC_POP
295 ranges::advance(std::get<0>(its_),
296 ranges::end(std::get<0>(
view_->views_)));
298 template<std::
size_t N>
301 return check_at_end_(
303 at_end || bool(std::get<N - 1>(its_) ==
304 ranges::end(std::get<N - 1>(
view_->views_))));
306 cursor(
end_tag, constify_if<cartesian_product_view> * view,
312 std::get<0>(its_) = ranges::end(std::get<0>(view->views_));
314 cursor(
end_tag, constify_if<cartesian_product_view> * view,
321 std::get<0>(its_) += ranges::distance(std::get<0>(view->views_));
325 using value_type = std::tuple<range_value_t<Views>...>;
328 explicit cursor(
begin_tag, constify_if<cartesian_product_view> * view)
330 , its_(tuple_transform(view->views_, ranges::begin))
336 explicit cursor(
end_tag, constify_if<cartesian_product_view> * view)
342 template(
bool Other)(
343 requires IsConst_ AND CPP_NOT(Other))
344 cursor(cursor<Other> that)
346 , its_(std::move(that.its_))
350 return tuple_transform(its_, detail::dereference_fn{});
358 return std::get<0>(its_) == ranges::end(std::get<0>(
view_->views_));
360 bool equal(cursor
const & that)
const
365 auto prev() -> CPP_ret(
void)(
371 auto CPP_fun(distance_to)(cursor
const & that)(
374 return distance_(that,
meta::size_t<
sizeof...(Views)>{});
377 auto advance(difference_type n)
384 cursor<false> begin_cursor()
389 auto begin_cursor()
const
390 -> CPP_ret(cursor<true>)(
397 -> CPP_ret(cursor<false>)(
400 return cursor<false>{
end_tag{},
this};
403 auto end_cursor()
const
404 -> CPP_ret(cursor<true>)(
407 return cursor<true>{
end_tag{},
this};
410 auto end_cursor()
const
420 : views_{detail::move(views)...}
422 template(
typename...)(
423 requires (my_cardinality >= 0))
424 static constexpr std::size_t size()
noexcept
426 return std::size_t{my_cardinality};
429 auto CPP_fun(size)()(
const
430 requires (my_cardinality < 0) &&
433 return tuple_foldl(views_, std::uintmax_t{1}, detail::cartesian_size_fn{});
436 auto CPP_fun(size)()(
437 requires (my_cardinality < 0) &&
440 return tuple_foldl(views_, std::uintmax_t{1}, detail::cartesian_size_fn{});