mardi 25 juillet 2017

Cosine lookup table with c++

Here's a snippet that should generate a cosine lookup table of 2048 elements, taken from the book Building Embedded Systems by Changyi Gu:

#include <cmath>
#include <array>

template<typename T>
constexpr T look_up_table_elem (int i) {
    return {};
}

template<>
constexpr uint16_t look_up_table_elem (int i) {
    return round (cos (static_cast <long double>(i) / 2048 * 3.14159 / 4) * 32767);
}


template<typename T, int... N>
struct lookup_table_expand{};

template<typename T, int... N>
struct lookup_table_expand<T, 1, N...> {
    static constexpr std::array<T, sizeof...(N) + 1> values = ;
};

template<typename T, int L, int... N> 
struct lookup_table_expand<T, L, N...>: lookup_table_expand<T, L-1, look_up_table_elem<T>(L-1), N...> {};


template<typename T, int... N>
constexpr std::array<T, sizeof...(N) + 1> lookup_table_expand<T, 1, N...>::values;

const std::array<uint16_t, 2048> lookup_table = lookup_table_expand<uint16_t, 2048>::values;

Note: Written for C++11.

I come from a primarily Java world and I've got an okay grasp of the basics of C++. Since it's never really explained in the book, I am really confused as to how does this snippet achieve the task, and how does it achieve the following (also taken out of the book):

Template specialization and class inheritance will help us get rid of the restriction that constexpr function can only have return state as its function body, which is why the lookup table has to be manually populated when the table size increases.

Any help would be greatly appreciated. I understand the part with constexpr template which would generate the actual value, but I am really unsure what the struct is doing and how the final array is constructed.

Aucun commentaire:

Enregistrer un commentaire