I have the following code which reads values/parameters from a pointer and calls a function:
#include <iostream>
#include <functional>
#include <string>
#include <tuple>
template<typename T>
T Read(void*& ptr)
{
T result = *static_cast<T*>(ptr);
ptr = static_cast<T*>(ptr) + 1;
return result;
}
template<typename T>
void Write(void*& ptr, const T &value)
{
*static_cast<T*>(ptr) = value;
ptr = static_cast<T*>(ptr) + 1;
}
template<typename R, typename... Args>
R Call(void* arguments, R (*func)(Args...))
{
//args = [c, b, a] somehow..?
auto args = std::make_tuple(Read<std::decay_t<Args>>(arguments)...);
return std::apply(func, args);
}
void func_one(int a, int b, int c)
{
std::cout<<"a: "<<a<<" b: "<<b<<" c: "<<c<<"\n";
}
int main()
{
int a = 1024;
int b = 2048;
int c = 3072;
int* args = new int[3];
void* temp = args;
Write(temp, a);
Write(temp, b);
Write(temp, c);
Call(args, func_one);
delete[] args;
return 0;
}
However if I do:
auto args = std::tuple<Args...>();
std::apply([&arguments](auto&... args) {((args = Read<std::decay_t<decltype(args)>>(arguments)), ...);}, args);
Then args = [a, b, c]. It's in the correct order. In the latter code, I used the comma operator to read each value and assigned it to the tuple.
I have tried: std::invoke(func, Read<std::decay_t<Args>>(arguments)...);
Which results in the order of arguments being in reverse as well.
So.. What is the difference between the two below:
Read<Args>(arguments)... //tuple is reversed - a: 3072 b: 2048 c: 1024
//and
(Read<Args>(arguments)), ...) //tuple is in the right order - a: 1024 b: 2048 c: 3072
And why does the first one create a tuple in reversed order?
Is there a better way to do it that using std::apply to get the correct order?