Kamil Koczurek
Kamil Koczurek

Reputation: 706

Some kind of a generative loop

I have this piece of code:

template<class T, class color_type>
void assign_channels(T* ptr, const color_type& color) {
    *(ptr + 0) = get_channel<0>(color);

    if constexpr(1 < color_type::size) {
        *(ptr + 1) = get_channel<1>(color);
    }
    if constexpr(2 < color_type::size) {
        *(ptr + 2) = get_channel<2>(color);
    }
    if constexpr(3 < color_type::size) {
        *(ptr + 3) = get_channel<3>(color);
    }
    if constexpr(4 < color_type::size) {
        *(ptr + 4) = get_channel<4>(color);
    }
    if constexpr(5 < color_type::size) {
        *(ptr + 5) = get_channel<5>(color);
    }
    if constexpr(6 < color_type::size) {
        *(ptr + 6) = get_channel<6>(color);
    }
    if constexpr(7 < color_type::size) {
        *(ptr + 7) = get_channel<7>(color);
    }
}

It has two clear flaws:

  1. It won't work properly unless I have no more than 8 channels;
  2. It's mostly boilerplate.

Is there a way in C++ to rewrite it in some kind of a loop? I think a recurring templated struct would do the job, but it's not really readable. What should I do?

Upvotes: 0

Views: 52

Answers (1)

Passer By
Passer By

Reputation: 21131

Use fold expressions and std::index_sequence in C++17

template<class T, class color_type, size_t... Is>
void assign_channels(T* ptr, const color_type& color, std::index_sequence<Is...>) {
    ((ptr[Is] = get_channel<Is>(color)), ...);
}

template<class T, class color_type>
void assign_channels(T* ptr, const color_type& color) {
    assign_channels(ptr, color, std::make_index_sequence<color_type::size>{});
}

Prior to C++17, you'd have to rewrite the fold expression as recursion.

Upvotes: 4

Related Questions