I have some code which does some serial communication with some hardware and then reads back some data (as as std::string
).
std::string data = cmd_exe("gmov");
char cmdReadback[4];
uint32_t Speed;
uint8_t uSpeed;
uint16_t Accel;
uint16_t Decel;
uint32_t AntiplaySpeed;
uint8_t uAntiplaySpeed;
cpMemReadback(cmdReadback, data, 0);
cpMemReadback(Speed, data, 4);
cpMemReadback(uSpeed, data, 8);
cpMemReadback(Accel, data, 9);
cpMemReadback(Decel, data, 11);
cpMemReadback(AntiplaySpeed, data, 13);
cpMemReadback(uAntiplaySpeed, data, 17);
where cpMemReadback
is quite trivial:
static constexpr auto cpMemReadback = [](auto& reg, std::string& s, size_t ix) {
std::memcpy(®, s.data()+ix, sizeof(reg));
};
There are still some ugly things in this code - but what's bugging me most, is this useless call of cpMemReadback
and then tracking of the index. I'd like to write:
parse_data(data, cmdReadback, Speed, uSpeed, ...);
I know that I'd want to use variadic templates, I presumably need a template parameter to track the index and then a parameter pack for my variables and then recursively execute the code, incrementing my index tracking template parameter. I'm just too stupid to actually write the code.
As I understand, you might have:
template <typename... Ts>
void parseData(const std::string& data, Ts&... args)
{
[[maybe_unused]]std::size_t idx = 0;
((cpMemReadback(args, data, idx), idx += sizeof (Ts)), ...);
}
and then replace
cpMemReadback(cmdReadback, data, 0);
cpMemReadback(Speed, data, 4);
cpMemReadback(uSpeed, data, 8);
cpMemReadback(Accel, data, 9);
cpMemReadback(Decel, data, 11);
cpMemReadback(AntiplaySpeed, data, 13);
cpMemReadback(uAntiplaySpeed, data, 17);
by
parse_data(data,
cmdReadback,
Speed,
uSpeed,
Accel,
Decel,
AntiplaySpeed,
uAntiplaySpeed);