[range.cartesian.iterator]

# 25 Ranges library [[ranges]](./#ranges)

## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.cartesian.iterator)

### 25.7.33 Cartesian product view [[range.cartesian]](range.cartesian#iterator)

#### 25.7.33.3 Class template cartesian_product_view​::​*iterator* [range.cartesian.iterator]

[ð](#lib:cartesian_product_view::iterator)

namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") First, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")... Vs>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<First> && ... && [view](range.view#concept:view "25.4.5 Views [range.view]")<Vs>)template<bool Const>class cartesian_product_view<First, Vs...>::*iterator* {public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using value_type = tuple<range_value_t<*maybe-const*<Const, First>>,
 range_value_t<*maybe-const*<Const, Vs>>...>; using reference = tuple<range_reference_t<*maybe-const*<Const, First>>,
 range_reference_t<*maybe-const*<Const, Vs>>...>; using difference_type = *see below*; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i) requires Const &&([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<iterator_t<First>, iterator_t<const First>> &&... && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<iterator_t<Vs>, iterator_t<const Vs>>); constexpr auto operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, First>>; constexpr *iterator*& operator--()requires [*cartesian-product-is-bidirectional*](range.cartesian.view#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator* operator--(int)requires [*cartesian-product-is-bidirectional*](range.cartesian.view#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator*& operator+=(difference_type x)requires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator*& operator-=(difference_type x)requires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; constexpr reference operator[](difference_type n) constrequires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<iterator_t<*maybe-const*<Const, First>>>; friend constexpr bool operator==(const *iterator*& x, default_sentinel_t); friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, First, Vs...>; friend constexpr *iterator* operator+(const *iterator*& x, difference_type y)requires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr *iterator* operator+(difference_type x, const *iterator*& y)requires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr *iterator* operator-(const *iterator*& x, difference_type y)requires [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires [*cartesian-is-sized-sentinel*](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, iterator_t, First, Vs...>; friend constexpr difference_type operator-(const *iterator*& i, default_sentinel_t)requires [*cartesian-is-sized-sentinel*](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>; friend constexpr difference_type operator-(default_sentinel_t, const *iterator*& i)requires [*cartesian-is-sized-sentinel*](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>; friend constexpr auto iter_move(const *iterator*& i) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& l, const *iterator*& r) noexcept(*see below*)requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, First>>> && ... &&[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, Vs>>>); private:using *Parent* = *maybe-const*<Const, cartesian_product_view>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only* tuple<iterator_t<*maybe-const*<Const, First>>,
 iterator_t<*maybe-const*<Const, Vs>>...> *current_*; // *exposition only*template<size_t N = sizeof...(Vs)>constexpr void *next*(); // *exposition only*template<size_t N = sizeof...(Vs)>constexpr void *prev*(); // *exposition only*template<class Tuple>constexpr difference_type *distance-from*(const Tuple& t) const; // *exposition only*constexpr *iterator*(*Parent*& parent, tuple<iterator_t<*maybe-const*<Const, First>>,
 iterator_t<*maybe-const*<Const, Vs>>...> current); // *exposition only*};}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16891)

*iterator*​::​iterator_concept is defined as follows:

- [(1.1)](#1.1)

  If [*cartesian-product-is-random-access*](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...> is modeled,
then iterator_concept denotes random_access_iterator_tag[.](#1.1.sentence-1)

- [(1.2)](#1.2)

  Otherwise,
if [*cartesian-product-is-bidirectional*](range.cartesian.view#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...> is modeled,
then iterator_concept denotes bidirectional_iterator_tag[.](#1.2.sentence-1)

- [(1.3)](#1.3)

  Otherwise,
if *maybe-const*<Const, First> models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
then iterator_concept denotes forward_iterator_tag[.](#1.3.sentence-1)

- [(1.4)](#1.4)

  Otherwise, iterator_concept denotes input_iterator_tag[.](#1.4.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16911)

*iterator*​::​difference_type is
an implementation-defined
signed-integer-like type[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16916)

*Recommended practice*: *iterator*​::​difference_type should be
the smallest signed-integer-like type
that is sufficiently wide to store
the product of the maximum sizes of all underlying ranges
if such a type exists[.](#3.sentence-1)

[ð](#lib:next,cartesian_product_view)

`template<size_t N = sizeof...(Vs)>
  constexpr void next();
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16931)

*Effects*: Equivalent to:auto& it = std::get<N>(*current_*);++it;if constexpr (N > 0) {if (it == ranges::end(std::get<N>(*parent_*->*bases_*))) { it = ranges::begin(std::get<N>(*parent_*->*bases_*)); *next*<N - 1>(); }}

[ð](#lib:prev,cartesian_product_view)

`template<size_t N = sizeof...(Vs)>
  constexpr void prev();
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16953)

*Effects*: Equivalent to:auto& it = std::get<N>(*current_*);if constexpr (N > 0) {if (it == ranges::begin(std::get<N>(*parent_*->*bases_*))) { it = *cartesian-common-arg-end*(std::get<N>(*parent_*->*bases_*)); *prev*<N - 1>(); }}--it;

[ð](#lib:distance-from,cartesian_product_view)

`template<class Tuple>
  constexpr difference_type distance-from(const Tuple& t) const;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16975)

Let:

- [(6.1)](#6.1)

*scaled-size*(N) be the product ofstatic_cast<difference_type>(ranges​::​size(std​::​get<​N>(*parent_*->*bases_*))) andscaled-size(N+1) if N â¤ sizeof...(Vs), otherwise static_cast<difference_type>(1);

- [(6.2)](#6.2)

*scaled-distance*(N) be the product ofstatic_cast<difference_type>(std​::​get<N>(*current_*) - std​::​get<N>(t)) and scaled-size(N+1); and

- [(6.3)](#6.3)

*scaled-sum* be the sum of *scaled-distance*(N) for every integer 0 â¤ N â¤ sizeof...(Vs)[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16991)

*Preconditions*: *scaled-sum* can be represented by difference_type[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16995)

*Returns*: *scaled-sum*[.](#8.sentence-1)

[ð](#lib:cartesian_product_view::iterator,constructor)

`constexpr iterator(Parent& parent, tuple<iterator_t<maybe-const<Const, First>>,
  iterator_t<maybe-const<Const, Vs>>...> current);
`

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17007)

*Effects*: Initializes*parent_* with addressof(parent) and*current_* with std​::​move(current)[.](#9.sentence-1)

[ð](#lib:cartesian_product_view::iterator,constructor_)

`constexpr iterator(iterator<!Const> i) requires Const &&
  ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<iterator_t<First>, iterator_t<const First>> &&
    ... && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<iterator_t<Vs>, iterator_t<const Vs>>);
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17022)

*Effects*: Initializes*parent_* with i.*parent_* and*current_* with std​::​move(i.*current_*)[.](#10.sentence-1)

[ð](#lib:operator*,cartesian_product_view::iterator)

`constexpr auto operator*() const;
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17035)

*Effects*: Equivalent to:return *tuple-transform*([](auto& i) -> decltype(auto) { return *i; }, *current_*);

[ð](#lib:operator++,cartesian_product_view::iterator)

`constexpr iterator& operator++();
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17049)

*Effects*: Equivalent to:*next*();return *this;

[ð](#lib:operator++,cartesian_product_view::iterator_)

`constexpr void operator++(int);
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17064)

*Effects*: Equivalent to ++*this[.](#13.sentence-1)

[ð](#lib:operator++,cartesian_product_view::iterator__)

`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<maybe-const<Const, First>>;
`

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17075)

*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;

[ð](#lib:operator--,cartesian_product_view::iterator)

`constexpr iterator& operator--()
  requires [cartesian-product-is-bidirectional](range.cartesian.view#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17092)

*Effects*: Equivalent to:*prev*();return *this;

[ð](#lib:operator--,cartesian_product_view::iterator_)

`constexpr iterator operator--(int)
  requires [cartesian-product-is-bidirectional](range.cartesian.view#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17108)

*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;

[ð](#lib:operator+=,cartesian_product_view::iterator)

`constexpr iterator& operator+=(difference_type x)
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17125)

Let orig be the value of *this before the call[.](#17.sentence-1)

Let ret be:

- [(17.1)](#17.1)

  If x > 0,
the value of *this had *next* been called x times[.](#17.1.sentence-1)

- [(17.2)](#17.2)

  Otherwise, if x < 0,
the value of *this had *prev* been called -x times[.](#17.2.sentence-1)

- [(17.3)](#17.3)

  Otherwise, orig[.](#17.3.sentence-1)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17140)

*Preconditions*: x is in the range[ranges​::​distance(*this, ranges​::​begin(**parent_*)),  
ranges​::​distance(*this, ranges​::​end(**parent_*))][.](#18.sentence-1)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17146)

*Effects*: Sets the value of *this to ret[.](#19.sentence-1)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17150)

*Returns*: *this[.](#20.sentence-1)

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17154)

*Complexity*: Constant[.](#21.sentence-1)

[ð](#lib:operator-=,cartesian_product_view::iterator)

`constexpr iterator& operator-=(difference_type x)
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17166)

*Effects*: Equivalent to:*this += -x;return *this;

[ð](#lib:operator%5b%5d,cartesian_product_view::iterator)

`constexpr reference operator[](difference_type n) const
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17182)

*Effects*: Equivalent to: return *((*this) + n);

[ð](#lib:operator==,cartesian_product_view::iterator)

`friend constexpr bool operator==(const iterator& x, const iterator& y)
  requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<iterator_t<maybe-const<Const, First>>>;
`

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17194)

*Effects*: Equivalent to: return x.*current_* == y.*current_*;

[ð](#lib:operator==,cartesian_product_view::iterator_)

`friend constexpr bool operator==(const iterator& x, default_sentinel_t);
`

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17205)

*Returns*: true if std​::​get<i>(x.*current_*) == ranges​::​end(std​::​get<i>(x.*parent_*->*bases_*)) is true for any integer 0 â¤ i â¤ sizeof...(Vs);
otherwise, false[.](#25.sentence-1)

[ð](#lib:operator%3c=%3e,cartesian_product_view::iterator)

`friend constexpr auto operator<=>(const iterator& x, const iterator& y)
  requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, First, Vs...>;
`

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17220)

*Effects*: Equivalent to: return x.*current_* <=> y.*current_*;

[ð](#lib:operator+,cartesian_product_view::iterator)

`friend constexpr iterator operator+(const iterator& x, difference_type y)
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17232)

*Effects*: Equivalent to: return *iterator*(x) += y;

[ð](#lib:operator+,cartesian_product_view::iterator_)

`friend constexpr iterator operator+(difference_type x, const iterator& y)
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17244)

*Effects*: Equivalent to: return y + x;

[ð](#lib:operator-,cartesian_product_view::iterator)

`friend constexpr iterator operator-(const iterator& x, difference_type y)
  requires [cartesian-product-is-random-access](range.cartesian.view#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, First, Vs...>;
`

[29](#29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17256)

*Effects*: Equivalent to: return *iterator*(x) -= y;

[ð](#lib:operator-,cartesian_product_view::iterator_)

`friend constexpr difference_type operator-(const iterator& x, const iterator& y)
  requires [cartesian-is-sized-sentinel](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, iterator_t, First, Vs...>;
`

[30](#30)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17268)

*Effects*: Equivalent to: return x.*distance-from*(y.*current_*);

[ð](#lib:operator-,cartesian_product_view::iterator__)

`friend constexpr difference_type operator-(const iterator& i, default_sentinel_t)
  requires [cartesian-is-sized-sentinel](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>;
`

[31](#31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17280)

Let *end-tuple* be an object of a type
that is a specialization of tuple, such that:

- [(31.1)](#31.1)

std​::​get<0>(*end-tuple*) has the same value asranges​::​end(std​::​get<0>(i.*parent_*->*bases_*));

- [(31.2)](#31.2)

std​::​get<N>(*end-tuple*) has the same value asranges​::​begin(std​::​get<N>(i.*parent_*->*bases_*)) for every integer 1 â¤ N â¤ sizeof...(Vs)[.](#31.sentence-1)

[32](#32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17293)

*Effects*: Equivalent to: return i.*distance-from*(*end-tuple*);

[ð](#lib:operator-,cartesian_product_view::iterator___)

`friend constexpr difference_type operator-(default_sentinel_t s, const iterator& i)
  requires [cartesian-is-sized-sentinel](range.cartesian.view#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_­product_­view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>;
`

[33](#33)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17305)

*Effects*: Equivalent to: return -(i - s);

[ð](#lib:iter_move,cartesian_product_view::iterator)

`friend constexpr auto iter_move(const iterator& i) noexcept(see below);
`

[34](#34)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17316)

*Effects*: Equivalent to: return *tuple-transform*(ranges​::​iter_move, i.*current_*);

[35](#35)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17320)

*Remarks*: The exception specification is equivalent to
the logical and of the following expressions:

- [(35.1)](#35.1)

noexcept(ranges​::​iter_move(std​::​get<N>(i.*current_*))) for every integer  
0 â¤ N â¤ sizeof...(Vs),

- [(35.2)](#35.2)

is_nothrow_move_constructible_v<range_rvalue_reference_t<*maybe-const*<Const, T>>>  
for every type T in First, Vs...[.](#35.sentence-1)

[ð](#lib:iter_swap,cartesian_product_view::iterator)

`friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
  requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<iterator_t<maybe-const<Const, First>>> && ... &&
        [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<iterator_t<maybe-const<Const, Vs>>>);
`

[36](#36)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17342)

*Effects*: For every integer 0 â¤ i â¤ sizeof...(Vs), performs:ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))

[37](#37)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17349)

*Remarks*: The exception specification is equivalent to the logical and of the following expressions:

- [(37.1)](#37.1)

noexcept(ranges​::​iter_swap(std​::​get<i>(l.*current_*), std​::​get<i>(r.*current_*))) for  
every integer 0 â¤ i â¤ sizeof...(Vs)[.](#37.sentence-1)
