user3624760
user3624760

Reputation:

Implementing std::iter_­difference_­t

I'm implementing my own version of ranges because they are not in the standard library yet. I got stuck on implementing std::iter_­difference_­t.

The latest draft says:

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.

It seems like the obvious implementation is to have a concept for the first case and have 2nd case take everything else. But I have no idea how to transform this from English to C++. Can someone provide the code?

Upvotes: 4

Views: 551

Answers (1)

Barry
Barry

Reputation: 303517

Step 1. Be the owner of std::iterator_traits. This lets you write something in the primary like:

template <typename T>
struct iterator_traits {
    using __secret_am_i_the_primary_alias = iterator_traits;
};

Which you can check:

template <typename T>
concept is_iterator_primary = std::same_as<
    typename iterator_traits<T>::__secret_am_i_the_primary_alias,
    iterator_traits<T>>;

Step 2. Now it's pretty easy:

template <typename T>
struct iter_difference {
    using type = typename iterator_­traits<I>​::​​difference_­type;
};

template <is_iterator_primary T>
struct iter_difference<T> {
    using type = typename incrementable_­traits<I>​::​difference_­type;
};

template <typename T>
using iter_difference_t = typename iter_difference<T>::type;

Upvotes: 3

Related Questions