Reputation: 582
Let's say I have some container C
of elements and two iterators it1
and it2
(it1 <= it2
wlog) . If std::distance(it1, it2) <= n
, I want to perform some action f
. Furthermore, it1
and it2
are changing (possibly randomly) within a loop and I need to check the distance with every iteration.
If C
is very large and not random-access, calling std::distance
on every iteration is extremely wasteful, since we only need to determine if the distance is less than some n
. It's fairly trivial to write some function which would take two iterators and an integer and return whether or not the distance between the two is within the provided integer, however I'm wondering if there is some way to use the STL to accomplish this task.
Essentially, what I am looking for is an STL version of the function below:
template <class ForwardIt>
bool is_within(ForwardIt it1, ForwardIt it2, int n) {
int i = 0;
while (i++ <= n)
if (it1++ == it2) return true;
return false
}
Upvotes: 2
Views: 145
Reputation: 2819
As far as I'm aware there's nothing in the standard library to do this automatically. However your solution is on the right track to being what you want anyway. You only need a minor change to make it more efficient for random access iterators.
template<typename Iter>
bool is_within(Iter a, Iter b, std::size_t n)
{
// if we're a random access iterator, use the (faster) std::distance() method
if constexpr (std::is_same_v<typename std::iterator_traits<Iter>::iterator_category, std::random_access_iterator_tag>)
{
return std::distance(a, b) <= n;
}
// otherwise go the long way around with short circuiting on n
else
{
for (; n > 0 && a != b; --n, ++a);
return a == b;
}
}
Upvotes: 3