I need to initialize an uint8_t array, most of it is constant (fixed identifiers), some elements encode length of next section, and some elements are variable.
uint8_t data[] = {
0x01, 0x05, 0x06, SomeVariable, 0x13,0x09, OtherVariable
};
I would like to compose it from named components, something like this
uint8_t data[] = MyData(DataHeader(), DataValue(SomeVariable), OtherValue(OtherVariable))
MyData would concatenate any number of parameters and produce
{
0x01, length of all parameters,
data from first parameter...,
data from second parameter...,
...
}
DataValue would produce {0x06, SomeVariable},
OtherValue would produce {0x13, 0x09, OtherVariable},
etc
How to do it in c++, without dynamic allocation (the total size of resulting array is known at compile time) ?
I tried using template with constexpr and parameter packs, but failed as the values in the array are not constexprs. However the sizes of the arrays are constexprs, so I hope it can be done.
While it is not clear to me what benefit you would have with what you are describing there are a couple of things to address. Let's start with the syntax:
This is only possible if MyData() returns an initializer-list. This however is not possible because initializer-lists do not extend the lifetime of the underlying array (reference). If you
return std::initializer_list<uint8_t>{1,2,3}then it will be destroyed before the return statement completes.You could however let MyData allocate memory and return the address:
But then you need to destroy the data. An alternative would be to pass the pointer to MyData:
Now with that out of the way you may write
MyDatato take variadic arguments:As mentioned you cannot have functions return initalizer_lists. You may play around with this but in the end it probably won't make it any prettier.
The way you describe it, it sounds like you could use the preprocessor to do what you want. Write macros to fill the initializer-list for you.