Reputation: 4661
Currently I'm struggling with something like this:
class Command final {
const std::vector<uint8_t> cmd;
public:
constexpr Command(const std::initializer_list<uint8_t> cmd_)
:cmd(cmd_)
{}
void copyToWithSlightModifications(uint8_t* buf, size_t len) { /*...*/ }
std::string getSomeInformation() { /*...*/ }
}
const Command cmd1({ 0x01, 0x02, 0x03 });
const Command cmd2({ 0x01, 0x02, 0x03, 0x04 });
// lots more of these
Of course, std::vector
is not something that works here, but it's here as it expresses my intent best. I tried std::array
and a few other ideas, but also have failed.
Background: this is for embedded development, so I'm tight on resources and consting things tends to put them to flash where memory is cheap. Doing it as a real vector will put this into scarce RAM memory. This is on gcc version 5.2.0.
TL;DR: I need to have a variable length container that I can put as a field on a const object with and initialize it in constexpr context. Any idea what that might look like? Doesn't have to be anything fancy, if it's a uint8_t*
and a size_t
with it's size, that will work too.
Upvotes: 1
Views: 166
Reputation: 21160
Going off of your description and the code snippet, this seems to fit the criteria.
template<size_t N>
class Command
{
uint8_t cmd[N];
public:
template<typename... Args>
constexpr Command(Args... args) : cmd{uint8_t(args)...}
{
static_assert(sizeof...(Args) == N,
"argument count mismatch");
}
};
constexpr Command<4> cmd4{0, 1, 2, 3};
constexpr Command<2> cmd2{0, 1};
You may also write a helper function to avoid explicitly typing the argument count
template<typename... Args>
constexpr Command<sizeof...(Args)> make_command(Args... args)
{
return {args...};
}
constexpr auto cmd4 = make_command(0, 1, 2, 3);
constexpr auto cmd2 = make_command(0, 1);
Alternatively, in C++17 there is template deduction guides
template<typename... Args>
Command(Args...) -> Command<sizeof...(Args)>;
constexpr Command cmd4{0, 1, 2, 3};
constexpr Command cmd2{0, 1};
Note however, a different sized Command
is a different type, meaning they won't fit in a container.
Upvotes: 3
Reputation: 1429
In deeply embedded you usually use circular buffers so solve this kind of problem. They have a fixed maximal size but depending on implementation they behave just like lists. Unfortunately the standard c++ library does not have any circular buffers but there are plenty of tutorials on the web.
I doublt you can use boost library on your restricted system but in case you do you can simply use boost::circular_buffer
Some other pages that might help you implement an circular buffer suitable for you might be this or this
Upvotes: 0