In a piece of code I'm writing, I receive packets as uint8_t * and std::size_t combination. I can register functions to call with these two parameters, based on which file descriptor the packet was received from. I use an std::map<int, std::function<void(const uint8_t *, std::size_t)> > handlers to keep track of which function to call.
I would like to be able to (indirectly) register functions with arbitrary arguments. I already have a function like this to transform from the uint8_t * and std::size_t to separate variables:
int unpack(const uint8_t *buf, std::size_t len) { return 0; }
template <typename T, typename... Types>
int unpack(const uint8_t *buf, std::size_t len, T &var1, Types... var2) {
static_assert(std::is_trivially_copyable<T>::value, "unpack() only works for primitive types");
if (len < sizeof(T)) return -1;
var1 = *reinterpret_cast<const T *>(buf);
const auto sum = unpack(buf + sizeof(T), len - sizeof(T), var2...);
const auto ret = (sum == -1) ? -1 : sum + sizeof(T);
return ret;
}
My question is: Is it possible with C++20 to auto-generate a function that convers from uint8_t * and std::size_t to the arguments that a passed function needs?
I would like to be able to do this:
void handler(unsigned int i) { ... }
int main(int argc, char ** argv) {
/* some code generating an fd */
handlers[fd] = function_returning_an_unpacker_function_that_calls_handler(handler);
edit: I realize I went a bit too short on my answer, as some mentioned (thanks!).
I am wondering if it is possible (and if so, how?) to implement the function_returning_an_unpacker_function_that_calls_handler function. I started out doing something like this (written from memory):
template<typename... Types>
std::function<void(const uint8_t * buf, std::size_t)>
function_returning_an_unpacker_function_that_calls_handler(std::function<void(Types...)> function_to_call) {
const auto ret = new auto([fun](const uint8_t * buf, std::size_t len) -> void {
const auto unpack_result = unpack(buf, len, list_of_variables_based_on_template_params);
if(unpack_result == -1) return nullptr;
function_to_call(list_of_variables_based_on_template_params);
};
return ret;
}
This is also why I supplied the unpack function. The problem I'm encountering is that I'm struggling with the list_of_variables_based_on_template_params bit. I haven't found any way to generate a list of variables that I can repeat identically in two places.
I also looked a little bit into using std::tuple::tie and friends, but I didn't see a solution there either.