24 Iterators library [iterators]

24.3 Iterator requirements [iterator.requirements]

24.3.7 Common algorithm requirements [alg.req]

24.3.7.1 General [alg.req.general]

There are several additional iterator concepts that are commonly applied to families of algorithms.
These group together iterator requirements of algorithm families.
There are three relational concepts that specify how element values are transferred between indirectly_readable and indirectly_writable types: indirectly_movable, indirectly_copyable, and indirectly_swappable.
There are three relational concepts for rearrangements: permutable, mergeable, and sortable.
There is one relational concept for comparing values from different sequences: indirectly_comparable.
[Note 1: 
The ranges​::​less function object type used in the concepts below imposes constraints on the concepts' arguments in addition to those that appear in the concepts' bodies ([range.cmp]).
— end note]

24.3.7.2 Concept indirectly_movable [alg.req.ind.move]

The indirectly_movable concept specifies the relationship between an indirectly_readable type and an indirectly_writable type between which values may be moved.
template<class In, class Out> concept indirectly_movable = indirectly_readable<In> && indirectly_writable<Out, iter_rvalue_reference_t<In>>;
The indirectly_movable_storable concept augments indirectly_movable with additional requirements enabling the transfer to be performed through an intermediate object of the indirectly_readable type's value type.
template<class In, class Out> concept indirectly_movable_storable = indirectly_movable<In, Out> && indirectly_writable<Out, iter_value_t<In>> && movable<iter_value_t<In>> && constructible_from<iter_value_t<In>, iter_rvalue_reference_t<In>> && assignable_from<iter_value_t<In>&, iter_rvalue_reference_t<In>>;
Let i be a dereferenceable value of type In.
In and Out model indirectly_movable_storable<In, Out> only if after the initialization of the object obj in iter_value_t<In> obj(ranges::iter_move(i)); obj is equal to the value previously denoted by *i.
If iter_rvalue_reference_t<In> is an rvalue reference type, the resulting state of the value denoted by *i is valid but unspecified ([lib.types.movedfrom]).

24.3.7.3 Concept indirectly_copyable [alg.req.ind.copy]

The indirectly_copyable concept specifies the relationship between an indirectly_readable type and an indirectly_writable type between which values may be copied.
template<class In, class Out> concept indirectly_copyable = indirectly_readable<In> && indirectly_writable<Out, iter_reference_t<In>>;
The indirectly_copyable_storable concept augments indirectly_copyable with additional requirements enabling the transfer to be performed through an intermediate object of the indirectly_readable type's value type.
It also requires the capability to make copies of values.
template<class In, class Out> concept indirectly_copyable_storable = indirectly_copyable<In, Out> && indirectly_writable<Out, iter_value_t<In>&> && indirectly_writable<Out, const iter_value_t<In>&> && indirectly_writable<Out, iter_value_t<In>&&> && indirectly_writable<Out, const iter_value_t<In>&&> && copyable<iter_value_t<In>> && constructible_from<iter_value_t<In>, iter_reference_t<In>> && assignable_from<iter_value_t<In>&, iter_reference_t<In>>;
Let i be a dereferenceable value of type In.
In and Out model indirectly_copyable_storable<In, Out> only if after the initialization of the object obj in iter_value_t<In> obj(*i); obj is equal to the value previously denoted by *i.
If iter_reference_t<In> is an rvalue reference type, the resulting state of the value denoted by *i is valid but unspecified ([lib.types.movedfrom]).

24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]

The indirectly_swappable concept specifies a swappable relationship between the values referenced by two indirectly_readable types.
template<class I1, class I2 = I1> concept indirectly_swappable = indirectly_readable<I1> && indirectly_readable<I2> && requires(const I1 i1, const I2 i2) { ranges::iter_swap(i1, i1); ranges::iter_swap(i2, i2); ranges::iter_swap(i1, i2); ranges::iter_swap(i2, i1); };

24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]

The indirectly_comparable concept specifies the common requirements of algorithms that compare values from two different sequences.
template<class I1, class I2, class R, class P1 = identity, class P2 = identity> concept indirectly_comparable = indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>;

24.3.7.6 Concept permutable [alg.req.permutable]

The permutable concept specifies the common requirements of algorithms that reorder elements in place by moving or swapping them.
template<class I> concept permutable = forward_iterator<I> && indirectly_movable_storable<I, I> && indirectly_swappable<I, I>;

24.3.7.7 Concept mergeable [alg.req.mergeable]

The mergeable concept specifies the requirements of algorithms that merge sorted sequences into an output sequence by copying elements.
template<class I1, class I2, class Out, class R = ranges::less, class P1 = identity, class P2 = identity> concept mergeable = input_iterator<I1> && input_iterator<I2> && weakly_incrementable<Out> && indirectly_copyable<I1, Out> && indirectly_copyable<I2, Out> && indirect_strict_weak_order<R, projected<I1, P1>, projected<I2, P2>>;

24.3.7.8 Concept sortable [alg.req.sortable]

The sortable concept specifies the common requirements of algorithms that permute sequences into ordered sequences (e.g., sort).
template<class I, class R = ranges::less, class P = identity> concept sortable = permutable<I> && indirect_strict_weak_order<R, projected<I, P>>;