In recent months, I've been improving my C++ skills, after all plain C is really starting to show it's age. So, variadic templates, auto typed variables, lambda expressions and even fold expressions, I looked at all that stuff, pretty interesting overall.
I've found that from the point of view of 8 bit MCU programming, the constexpr modifier is quite useful. Everyone knows these 8 bit chips have limited processing power, so being able to do complex calculations at compile time is great, in my opinion.
This small example creates a constant array in flash memory, containing 8 bit samples forming one period of a sine wave. Normally, the samples would be calculated by some external program and converted to some ugly array, but in this case the compiler does the job. (note: this code requires C++14, so you need to enable that, for example, in AS7, add the option -std=gnu++14 to the compiler)
#include <stdint.h> #include <avr/io.h> #include <avr/pgmspace.h> #define _USE_MATH_DEFINES #include <math.h> // We need to return an array, which is not possible in C/C++ // So we return a structure that contains the array. struct array { uint8_t _[256]; }; // This function returns an array structure filled with a calculated period of a sine wave (8 bit resolution). // Since it is defined as constexpr, the compiler knows that the result of the function can be determined at compile time. // No actual AVR code is generated, just data. constexpr array table_generator() { array tmp {}; double angle {}; for (int i = 0; i < 256; i++) { angle = i * M_PI / 128; tmp._[i] = 128 + 127 * sin(angle); } return tmp; } // Fill flash memory with the sine wave table const PROGMEM array sine_wave = table_generator(); // A define to pretend we are dealing with a simple array #define SINE_WAVE (&(sine_wave._[0])) // Use the table so it's not optimized away int main () { for (int i = 0; i < 256; i ++) { PORTD = SINE_WAVE[i]; } }