Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[range.cartesian.view]

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 = // exposition only(random_access_range<maybe-const<Const, First>> && ... &&(random_access_range<maybe-const<Const, Vs>>&& sized_range<maybe-const<Const, Vs>>)); templateconcept cartesian-product-common-arg = // exposition onlycommon_range || (sized_range && random_access_range); template<bool Const, class First, class... Vs>concept cartesian-product-is-bidirectional = // exposition only(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 = // exposition onlycartesian-product-common-arg; template<class... Vs>concept cartesian-product-is-sized = // exposition only(sized_range && ...); template<bool Const, template class FirstSent, class First, class... Vs>concept cartesian-is-sized-sentinel = // exposition only(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) { // exposition onlyif constexpr (common_range) {return ranges::end(r); } else {return ranges::begin(r) + ranges::distance(r); }}template<input_range First, forward_range... Vs>requires (view && ... && view)class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> {private: tuple<First, Vs...> bases_; // exposition only// [range.cartesian.iterator], class template cartesian_product_view::iteratortemplate class iterator; // exposition onlypublic:constexpr cartesian_product_view() = default; constexpr explicit cartesian_product_view(First first_base, Vs... bases); constexpr iterator begin()requires (simple-view || ... || simple-view); constexpr iterator begin() constrequires (range && ... && range); constexpr iterator end()requires ((simple-view || ... || simple-view) &&cartesian-product-is-common<First, Vs...>); constexpr iterator end() constrequires 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() constrequires cartesian-product-is-sized<const First, const Vs...>; }; template<class... Vs> cartesian_product_view(Vs&&...) -> cartesian_product_view<views::all_t...>;}

🔗

constexpr explicit cartesian_product_view(First first_base, Vs... bases);

1

#

Effects: Initializes bases_ with std::move(first_base), std::move(bases)....

🔗

constexpr iterator<false> begin() requires (![simple-view](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<First> || ... || ![simple-view](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<Vs>);

2

#

Effects: Equivalent to:return iterator(*this, tuple-transform(ranges::begin, bases_));

🔗

constexpr iterator<true> begin() const requires ([range](range.range#concept:range "25.4.2Ranges[range.range]")<const First> && ... && [range](range.range#concept:range "25.4.2Ranges[range.range]")<const Vs>);

3

#

Effects: Equivalent to:return iterator(*this, tuple-transform(ranges::begin, bases_));

🔗

constexpr iterator<false> end() requires ((![simple-view](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<First> || ... || ![simple-view](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<Vs>) && [cartesian-product-is-common](#concept:cartesian-product-is-common "25.7.33.2Class 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.2Class template cartesian_­product_­view[range.cartesian.view]")<const First, const Vs...>;

4

#

Let:

is-const be true for the const-qualified overload, andfalse otherwise;

is-empty be true if the expression ranges::empty(rng) is true for any rng among the underlying ranges except the first one andfalse otherwise; and

begin-or-first-end(rng) be expression-equivalent tois-empty ? ranges::begin(rng) : cartesian-common-arg-end(rng) if rng is the first underlying range andranges::begin(rng) otherwise.

5

#

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;

6

#

Returns: default_sentinel.

🔗

constexpr see below size() requires [cartesian-product-is-sized](#concept:cartesian-product-is-sized "25.7.33.2Class 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.2Class template cartesian_­product_­view[range.cartesian.view]")<const First, const Vs...>;

7

#

The return type is an implementation-defined unsigned-integer-like type.

8

#

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.

9

#

Let p be the product of the sizes of all the ranges in bases_.

10

#

Preconditions: p can be represented by the return type.

11

#

Returns: p.