Wait, I'm not talking about metafunctions, for sure compile time functions on types are something essential to metaprogramming, which can indeed deliver powerful abstractions to the user when some tradeoffs are bought. I'm referring to functions on objects at compile time, aka, constexpr or consteval functions. I came across to a interesting problem when developing a driver to an OLED display dot matrix that has GDDRAM(Graphics Display RAM) to represent each dot(pixel) as one bit, yes, bitmaps! But there is a catch, the bitmap is represented in the RAM rotated 90 degrees clockwise. So, it's very useful and expressive declare something like this in the code:
constexpr static const uint8_t bitmap_h[] = {
0b10000000,
0b10000000,
0b10111000,
0b11000100,
0b10000100,
0b10000100,
0b10000100,
0b10000100,
};
But actually we need something like this to be sent to the device:
static const uint8_t letter_h[] [[gnu::__progmem__]] = {
0b11111111,
0b00001000,
0b00000100,
0b00000100,
0b11111000,
0b00000000,
0b00000000,
};
Note that we are using __progmem__ because it's almost imperative to put the charset in the memory flash when using tiny devices. It would be perfect if the last array assigned to letter_h was the result of a function called at compile time that receives bitmap_h. We can easily do that using C++17:
constexpr uint8_t rotate(uint8_t col, uint8_t b, uint8_t pos) {
if(pos > col) b >>= pos - col;
else if (pos < col) b <<= col - pos;
return b &= 1<<(7 - pos);
}
struct bitmap_90_clockwise { uint8_t data[8]{}; };
/** Transform a bitmap to a sequence of bytes to be sent to the
GDDRAM. Basically the bitmap is rotated 90 degress clockwise.
*/
constexpr bitmap_90_clockwise toGDDRAM(const uint8_t(&bitmap)[8]) {
bitmap_90_clockwise ret;
for(uint8_t col{0}; col < 8; ++col)
for(uint8_t row{0}; row < 8; ++row)
ret.data[col] |= rotate(col, bitmap[row], 7 - row);
return ret;
}
Now, we can rewrite the assignment to letter_h:
static const bitmap_90_clockwise letter_h [[gnu::__progmem__]] = toGDDRAM(bitmap_h);
This isn't only an expressive way to describe each letter(symbol) using the normal(human) orientation but it's also useful because it allows the programmer to make adjustments easily in the bitmap.