I recently had to repeatedly iterate over an array but increment the index to start from each time. Since this is quite cumbersome in comparison to a normal for loop I made a small template function that does this for me:
#include <algorithm>
#include <iostream>
template<typename TSize, typename TFunc>
void for_start(const TSize start, const TSize size, TFunc&& fn)
{
for(TSize c{}, i{c + start}; c < size; ++c, ++i)
{
if(i >= size)
i = 0;
fn(i);
}
}
template<typename TRAIter, typename TFunc>
void for_start(TRAIter start, TRAIter begin, TRAIter end, TFunc&& fn)
{
for(TRAIter c{begin}, i{c + std::distance(begin, start)}; c != end; ++i, ++c)
{
if(i == end)
i = begin;
fn(i);
}
}
// usage
int main()
{
const unsigned ARR_SIZE{10};
int arr[ARR_SIZE]{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
for_start(5u, ARR_SIZE, [arr](unsigned i)
{
std::cout << arr[i] << ' ';
});
std::cout << '\n';
for_start(std::begin(arr) + 5, std::begin(arr), std::end(arr), [](const int* i)
{
std::cout << *i << ' ';
});
}
// prints:
// 5 6 7 8 9 0 1 2 3 4
// 5 6 7 8 9 0 1 2 3 4
I'd like to get some feedback on things like usability (function name, order of parameters) and reuseability. Note that I'd like to use this function with signed & unsigned integers.
std::range
, which has been voted in to C++20. \$\endgroup\$