Reputation: 8173
I have a bunch of longish hand initialized arrays, e.g.:
const std::array<int, 16> a{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
const std::array<int, 16> b{16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
...
Is there a way for a more concise initialization, e.g. along these lines (illegal):
const std::array<int, 16> a{std::views::iota(0, 16)};
const std::array<int, 16> b{std::views::iota(16, 32)};
...
Upvotes: 6
Views: 239
Reputation: 345
You can do this using plain old iota. Like so,
#include <array>
#include <numeric>
template<typename T, std::size_t N>
constexpr auto make_range_array(T const & start) noexcept {
std::array<T, N> range;
std::iota(range.begin(), range.end(), start);
return range;
}
auto main() -> int
{
auto const a = make_range_array<int, 16>(0);
auto const b = make_range_array<int, 16>(16);
}
Upvotes: 8
Reputation: 218138
With std::index_sequence
, you might do something like:
template <std::size_t N>
constexpr std::array<int, N> make_iota_array(int start = 0)
{
return [&]<std::size_t... Is>(std::index_sequence<Is...>){
return std::array<int, N>{static_cast<int>(start + N)...};
}(std::make_index_sequence<N>());
}
Upvotes: 5
Reputation: 1
Is there a way for a more concise initialization
Yes there is. You can write a helper make_array
as shown below.
#include <iostream>
#include <type_traits>
#include <array>
template<std::size_t start, std::size_t end>
std::enable_if_t<(end > start), std::array<int, end - start>> constexpr make_array()
{
std::array<int, end - start> tempArray{};
std::size_t count = 0;
for(int &elem:tempArray)
{
elem = start + count;
count++;
}
return tempArray;
}
int main()
{
constexpr auto arr = make_array<16, 32>();
}
Upvotes: 2