23 Iterators library [iterators]

23.3 Iterator requirements [iterator.requirements]

23.3.7 Common algorithm requirements [alg.req]

23.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 readable and 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
:
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
 ]

23.3.7.2 Concept indirectly_­movable [alg.req.ind.move]

The indirectly_­movable concept specifies the relationship between a readable type and a writable type between which values may be moved.
template<class In, class Out>
  concept indirectly_movable =
    readable<In> &&
    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 readable type's value type.
template<class In, class Out>
  concept indirectly_movable_storable =
    indirectly_movable<In, Out> &&
    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]).

23.3.7.3 Concept indirectly_­copyable [alg.req.ind.copy]

The indirectly_­copyable concept specifies the relationship between a readable type and a writable type between which values may be copied.
template<class In, class Out>
  concept indirectly_copyable =
    readable<In> &&
    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 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> &&
    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]).

23.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]

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

23.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_relation<R, projected<I1, P1>, projected<I2, P2>>;

23.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>;

23.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>>;

23.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>>;