[range.cartesian.view] (original) (raw)
25 Ranges library [ranges]
25.7 Range adaptors [range.adaptors]
25.7.33 Cartesian product view [range.cartesian]
25.7.33.2 Class template cartesian_product_view [range.cartesian.view]
namespace std::ranges { template<bool Const, class First, class... Vs> concept cartesian-product-is-random-access = (random_access_range<_maybe-const_<Const, First>> && ... && (random_access_range<_maybe-const_<Const, Vs>> && sized_range<_maybe-const_<Const, Vs>>));template<class R> concept cartesian-product-common-arg = common_range<R> || (sized_range<R> && random_access_range<R>);template<bool Const, class First, class... Vs> concept cartesian-product-is-bidirectional = (bidirectional_range<_maybe-const_<Const, First>> && ... && (bidirectional_range<_maybe-const_<Const, Vs>> && cartesian-product-common-arg<_maybe-const_<Const, Vs>>));template<class First, class...> concept cartesian-product-is-common = cartesian-product-common-arg<First>;template<class... Vs> concept cartesian-product-is-sized = (sized_range<Vs> && ...);template<bool Const, template<class> class FirstSent, class First, class... Vs> concept cartesian-is-sized-sentinel = (sized_sentinel_for<FirstSent<_maybe-const_<Const, First>>, iterator_t<_maybe-const_<Const, First>>> && ... && (sized_range<_maybe-const_<Const, Vs>> && sized_sentinel_for<iterator_t<_maybe-const_<Const, Vs>>, iterator_t<_maybe-const_<Const, Vs>>>));template<cartesian-product-common-arg R> constexpr auto cartesian-common-arg-end(R& r) { if constexpr (common_range<R>) { return ranges::end(r);} else { return ranges::begin(r) + ranges::distance(r);} } template<input_range First, forward_range... Vs> requires (view<First> && ... && view<Vs>) class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> { private: tuple<First, Vs...> bases_; template<bool Const> class iterator; public: constexpr cartesian_product_view() = default;constexpr explicit cartesian_product_view(First first_base, Vs... bases);constexpr iterator<false> begin() requires (<First> || ... ||
<Vs>);constexpr iterator<true> begin() const requires (range<const First> && ... && range<const Vs>);constexpr iterator<false> end() requires ((
<First> || ... ||
<Vs>) && cartesian-product-is-common<First, Vs...>);constexpr iterator<true> end() const requires cartesian-product-is-common<const First, const Vs...>;constexpr default_sentinel_t end() const noexcept;constexpr see below size() requires cartesian-product-is-sized<First, Vs...>;constexpr see below size() const requires cartesian-product-is-sized<const First, const Vs...>;};template<class... Vs> cartesian_product_view(Vs&&...) -> cartesian_product_view<views::all_t<Vs>...>;}
constexpr explicit cartesian_product_view(First first_base, Vs... bases);
Effects: Initializes _bases__with std::move(first_base), std::move(bases)....
Effects: Equivalent to:return iterator<false>(*this, tuple-transform(ranges::begin, bases_));
constexpr _iterator_<true> begin() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const First> && ... && [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Vs>);
Effects: Equivalent to:return iterator<true>(*this, tuple-transform(ranges::begin, bases_));
constexpr _iterator_<false> end() requires ((<First> || ... || <Vs>) && [_cartesian-product-is-common_](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>);constexpr _iterator_<true> end() const requires [_cartesian-product-is-common_](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>;
Let:
- is-const be true for the const-qualified overload, andfalse otherwise;
- is-empty be trueif the expression ranges::empty(rng) is truefor any rng among the underlying ranges except the first one andfalse otherwise; and
- begin-or-first-end(rng) be expression-equivalent to_is-empty_ ? ranges::begin(rng) : cartesian-common-arg-end(rng)if rng is the first underlying range andranges::begin(rng) otherwise.
Effects: Equivalent to:iterator<_is-const_> it(*this, tuple-transform( [](auto& rng){ return begin-or-first-end(rng); }, bases_));return it;
constexpr default_sentinel_t end() const noexcept;
Returns: default_sentinel.
constexpr _see below_ size() requires [_cartesian-product-is-sized_](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>;constexpr _see below_ size() const requires [_cartesian-product-is-sized_](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>;
The return type is an implementation-defined unsigned-integer-like type.
Recommended practice: The return type should be the smallest unsigned-integer-like type that is sufficiently wide to store the product of the maximum sizes of all the underlying ranges, if such a type exists.
Let p be the product of the sizes of all the ranges in bases_.
Preconditions: p can be represented by the return type.