22 Iterators library [iterators]

22.3 Iterator requirements [iterator.requirements]

22.3.2 Associated types [iterator.assoc.types] Incrementable traits [incrementable.traits]

To implement algorithms only in terms of incrementable types, it is often necessary to determine the difference type that corresponds to a particular incrementable type.
Accordingly, it is required that if WI is the name of a type that models the WeaklyIncrementable concept ([iterator.concept.winc]), the type
be defined as the incrementable type's difference type.
namespace std {
  template<class> struct incrementable_traits { };

  template<class T>
    requires is_object_v<T>
  struct incrementable_traits<T*> {
    using difference_type = ptrdiff_t;

  template<class I>
  struct incrementable_traits<const I>
    : incrementable_traits<I> { };

  template<class T>
    requires requires { typename T::difference_type; }
  struct incrementable_traits<T> {
    using difference_type = typename T::difference_type;

  template<class T>
    requires (!requires { typename T::difference_type; } &&
              requires(const T& a, const T& b) { { a - b } -> Integral; })
  struct incrementable_traits<T> {
    using difference_type = make_signed_t<decltype(declval<T>() - declval<T>())>;

  template<class T>
    using iter_difference_t = see below;
The type iter_­difference_­t<I> denotes
  • incrementable_­traits<I>::difference_­type if iterator_­traits<I> names a specialization generated from the primary template, and
  • iterator_­traits<I>::​difference_­type otherwise.
Users may specialize incrementable_­traits on program-defined types.