Suppose I have a vector (potentially large) of trivial types, e.g.
std::vector<int> v{1,2,3};
What is the best way to repeat it n times?
E.g. 3 times would give the result {1,2,3,1,2,3,1,2,3}
Surely, this is a problem that arises often (numeric libraries usually have such a function build in). My naive solution:
template<typename T>
std::vector<T> repeat(const std::vector<T> &input, unsigned int times) {
std::vector<T> result;
auto input_size = input.size();
result.reserve(input_size * times);
for (std::size_t rep = 0; rep < times; ++rep) {
for (std::size_t i = 0; i < input_size; ++i) {
result.push_back(input[i % input_size]);
}
}
return result;
}
Surely this can be made faster? Maybe with std::copy? In that case, however, I'm not sure how to tell the vector its new size while avoiding zero-initialization. Apparently it cannot be done easily (see, e.g., 1). I tried to do it with iterators as well, but it didn't seem to be faster.
With range-v3 you could write:
#include <range/v3/all.hpp>
namespace rv = ranges::views;
template<typename T>
auto repeat(const std::vector<T> &input, unsigned int times)
{
return rv::repeat_n(input, times)
| rv::join
| ranges::to<std::vector<T>>;
}
Here's a demo.
I suspect this will have sufficiently good performance for your needs.