[iterators.common]

# 24 Iterators library [[iterators]](./#iterators)

## 24.5 Iterator adaptors [[predef.iterators]](predef.iterators#iterators.common)

### 24.5.5 Common iterators [iterators.common]

#### [24.5.5.1](#common.iterator) Class template common_iterator [[common.iterator]](common.iterator)

[1](#common.iterator-1)

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

Class template common_iterator is an iterator/sentinel adaptor that is
capable of representing a non-common range of elements (where the types of the
iterator and sentinel differ) as a common range (where they are the same)[.](#common.iterator-1.sentence-1)

It
does this by holding either an iterator or a sentinel, and implementing the
equality comparison operators appropriately[.](#common.iterator-1.sentence-2)

[2](#common.iterator-2)

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

[*Note [1](#common.iterator-note-1)*:

The common_iterator type is useful for interfacing with legacy
code that expects the begin and end of a range to have the same type[.](#common.iterator-2.sentence-1)

â *end note*]

[3](#common.iterator-3)

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

[*Example [1](#common.iterator-example-1)*: template<class ForwardIterator>void fun(ForwardIterator begin, ForwardIterator end);

list<int> s;// populate the list susing CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;// call fun on a range of 10 ints fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel)); â *end example*]

[ð](#lib:common_iterator)

namespace std {template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I> S>requires (![same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I, S> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<I>)class common_iterator {public:constexpr common_iterator() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<I> = default; constexpr common_iterator(I i); constexpr common_iterator(S s); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const S2&, S>constexpr common_iterator(const common_iterator<I2, S2>& x); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const S2&, S> &&[assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")<S&, const S2&>constexpr common_iterator& operator=(const common_iterator<I2, S2>& x); constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() constrequires [*dereferenceable*](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator>&nbsp;synopsis [iterator.synopsis]")<const I>; constexpr auto operator->() constrequires *see below*; constexpr common_iterator& operator++(); constexpr decltype(auto) operator++(int); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<S, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<I, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I> S2>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<S, I2>friend constexpr iter_difference_t<I2> operator-(const common_iterator& x, const common_iterator<I2, S2>& y); friend constexpr decltype(auto) iter_move(const common_iterator& i)noexcept(noexcept(ranges::iter_move(declval<const I&>())))requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]")<I>; template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<I> I2, class S2>friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>()))); private: variant<I, S> v_; // *exposition only*}; template<class I, class S>struct incrementable_traits<common_iterator<I, S>> {using difference_type = iter_difference_t<I>; }; template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I, class S>struct iterator_traits<common_iterator<I, S>> {using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t<I>; using difference_type = iter_difference_t<I>; using pointer = *see below*; using reference = iter_reference_t<I>; };}

#### [24.5.5.2](#common.iter.types) Associated types [[common.iter.types]](common.iter.types)

[1](#common.iter.types-1)

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

The nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category of
the specialization of iterator_traits for common_iterator<I, S> is defined if and only if iter_difference_t<I> is an integral type[.](#common.iter.types-1.sentence-1)

In that case,iterator_category denotes forward_iterator_tag if
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") iterator_traits<I>​::​iterator_category is valid and denotes a type that
models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<forward_iterator_tag>;
otherwise it denotes input_iterator_tag[.](#common.iter.types-1.sentence-2)

[2](#common.iter.types-2)

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

The remaining nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s* of the specialization ofiterator_traits for common_iterator<I, S> are defined as follows:

- [(2.1)](#common.iter.types-2.1)

  iterator_concept denotes forward_iterator_tag if I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]");
otherwise it denotes input_iterator_tag[.](#common.iter.types-2.1.sentence-1)

- [(2.2)](#common.iter.types-2.2)

  Let a denote an lvalue of type const common_iterator<I, S>[.](#common.iter.types-2.2.sentence-1)
  If the expression a.operator->() is well-formed,
then pointer denotes decltype(a.operator->())[.](#common.iter.types-2.2.sentence-2)
  Otherwise, pointer denotes void[.](#common.iter.types-2.2.sentence-3)

#### [24.5.5.3](#common.iter.const) Constructors and conversions [[common.iter.const]](common.iter.const)

[ð](#lib:common_iterator,constructor)

`constexpr common_iterator(I i);
`

[1](#common.iter.const-1)

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

*Effects*: Initializes v_ as if by v_{in_place_type<I>, std​::​move(i)}[.](#common.iter.const-1.sentence-1)

[ð](#lib:common_iterator,constructor_)

`constexpr common_iterator(S s);
`

[2](#common.iter.const-2)

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

*Effects*: Initializes v_ as if byv_{in_place_type<S>, std​::​move(s)}[.](#common.iter.const-2.sentence-1)

[ð](#lib:common_iterator,constructor__)

`template<class I2, class S2>
  requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const S2&, S>
    constexpr common_iterator(const common_iterator<I2, S2>& x);
`

[3](#common.iter.const-3)

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

*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-3.sentence-1)

[4](#common.iter.const-4)

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

*Effects*: Initializes v_ as if byv_{in_place_index<i>, get<i>(x.v_)},
where i is x.v_.index()[.](#common.iter.const-4.sentence-1)

[ð](#lib:operator=,common_iterator)

`template<class I2, class S2>
  requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const S2&, S> &&
           [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")<S&, const S2&>
    constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
`

[5](#common.iter.const-5)

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

*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-5.sentence-1)

[6](#common.iter.const-6)

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

*Effects*: Equivalent to:

- [(6.1)](#common.iter.const-6.1)

  If v_.index() == x.v_.index(), thenget<i>(v_) = get<i>(x.v_)[.](#common.iter.const-6.1.sentence-1)

- [(6.2)](#common.iter.const-6.2)

  Otherwise, v_.emplace<i>(get<i>(x.v_))[.](#common.iter.const-6.2.sentence-1)

where i is x.v_.index()[.](#common.iter.const-6.sentence-2)

[7](#common.iter.const-7)

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

*Returns*: *this[.](#common.iter.const-7.sentence-1)

#### [24.5.5.4](#common.iter.access) Accessors [[common.iter.access]](common.iter.access)

[ð](#lib:operator*,common_iterator)

`constexpr decltype(auto) operator*();
constexpr decltype(auto) operator*() const
  requires [dereferenceable](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator>&nbsp;synopsis [iterator.synopsis]")<const I>;
`

[1](#common.iter.access-1)

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

*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-1.sentence-1)

[2](#common.iter.access-2)

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

*Effects*: Equivalent to: return *get<I>(v_);

[ð](#lib:operator-%3e,common_iterator)

`constexpr auto operator->() const
  requires see below;
`

[3](#common.iter.access-3)

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

The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]")<const I> &&(requires(const I& i) { i.operator->(); } || is_reference_v<iter_reference_t<I>> ||[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<iter_value_t<I>, iter_reference_t<I>>)

[4](#common.iter.access-4)

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

*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-4.sentence-1)

[5](#common.iter.access-5)

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

*Effects*: 

- [(5.1)](#common.iter.access-5.1)

If I is a pointer type or if the expressionget<I>(v_).operator->() is
well-formed, equivalent to: return get<I>(v_);

- [(5.2)](#common.iter.access-5.2)

Otherwise, if iter_reference_t<I> is a reference type, equivalent to:auto&& tmp = *get<I>(v_);return addressof(tmp);

- [(5.3)](#common.iter.access-5.3)

Otherwise, equivalent to:return *proxy*(*get<I>(v_)); where*proxy* is the exposition-only class:class *proxy* { iter_value_t<I> keep_; constexpr *proxy*(iter_reference_t<I>&& x): keep_(std::move(x)) {}public:constexpr const iter_value_t<I>* operator->() const noexcept {return addressof(keep_); }};

#### [24.5.5.5](#common.iter.nav) Navigation [[common.iter.nav]](common.iter.nav)

[ð](#lib:operator++,common_iterator)

`constexpr common_iterator& operator++();
`

[1](#common.iter.nav-1)

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

*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-1.sentence-1)

[2](#common.iter.nav-2)

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

*Effects*: Equivalent to ++get<I>(v_)[.](#common.iter.nav-2.sentence-1)

[3](#common.iter.nav-3)

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

*Returns*: *this[.](#common.iter.nav-3.sentence-1)

[ð](#lib:operator++,common_iterator_)

`constexpr decltype(auto) operator++(int);
`

[4](#common.iter.nav-4)

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

*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-4.sentence-1)

[5](#common.iter.nav-5)

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

*Effects*: If I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]"), equivalent to:common_iterator tmp = *this;++*this;return tmp;

Otherwise, ifrequires(I& i) { { *i++ } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator>&nbsp;synopsis [iterator.synopsis]"); } is true or[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]")<I> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<iter_value_t<I>, iter_reference_t<I>> &&[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_­constructible [concept.moveconstructible]")<iter_value_t<I>> is false,
equivalent to:return get<I>(v_)++;

Otherwise, equivalent to:*postfix-proxy* p(**this);++*this;return p; where *postfix-proxy* is the exposition-only class:class *postfix-proxy* { iter_value_t<I> keep_; constexpr *postfix-proxy*(iter_reference_t<I>&& x): keep_(std::forward<iter_reference_t<I>>(x)) {}public:constexpr const iter_value_t<I>& operator*() const noexcept {return keep_; }};

#### [24.5.5.6](#common.iter.cmp) Comparisons [[common.iter.cmp]](common.iter.cmp)

[ð](#lib:operator==,common_iterator)

`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I> S2>
  requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<S, I2>
friend constexpr bool operator==(
  const common_iterator& x, const common_iterator<I2, S2>& y);
`

[1](#common.iter.cmp-1)

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

*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-1.sentence-1)

[2](#common.iter.cmp-2)

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

*Returns*: true if i == j,
and otherwise get<i>(x.v_) == get<j>(y.v_),
where i is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-2.sentence-1)

[ð](#lib:operator==,common_iterator_)

`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I> S2>
  requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<I, I2>
friend constexpr bool operator==(
  const common_iterator& x, const common_iterator<I2, S2>& y);
`

[3](#common.iter.cmp-3)

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

*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-3.sentence-1)

[4](#common.iter.cmp-4)

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

*Returns*: true if i and j are each 1, and otherwiseget<i>(x.v_) == get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-4.sentence-1)

[ð](#lib:operator-,common_iterator)

`template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I> S2>
  requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<S, I2>
friend constexpr iter_difference_t<I2> operator-(
  const common_iterator& x, const common_iterator<I2, S2>& y);
`

[5](#common.iter.cmp-5)

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

*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-5.sentence-1)

[6](#common.iter.cmp-6)

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

*Returns*: 0 if i and j are each 1, and otherwiseget<i>(x.v_) - get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-6.sentence-1)

#### [24.5.5.7](#common.iter.cust) Customizations [[common.iter.cust]](common.iter.cust)

[ð](#lib:iter_move,common_iterator)

`friend constexpr decltype(auto) iter_move(const common_iterator& i)
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
    requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]")<I>;
`

[1](#common.iter.cust-1)

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

*Hardened preconditions*: holds_alternative<I>(i.v_) is true[.](#common.iter.cust-1.sentence-1)

[2](#common.iter.cust-2)

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

*Effects*: Equivalent to: return ranges​::​iter_move(get<I>(i.v_));

[ð](#lib:iter_swap,common_iterator)

`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")<I> I2, class S2>
  friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
    noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
`

[3](#common.iter.cust-3)

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

*Hardened preconditions*: holds_alternative<I>(x.v_) and holds_alternative<I2>(y.v_) are each true[.](#common.iter.cust-3.sentence-1)

[4](#common.iter.cust-4)

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

*Effects*: Equivalent to ranges​::​iter_swap(get<I>(x.v_), get<I2>(y.v_))[.](#common.iter.cust-4.sentence-1)
