Deferred caller, delegator implementation with variadic template
Recently I started playing with a small toy project – tiny web server with C++. The first requirement I wanted to implement was the ‘static type routing handler’ as shown from the crow project.
Which means, users should be able to register its routing handlers as the following manner:
In order to do that, two things come up to the list:
- constexpr string parser to determine the parameter type (e.g <int>, <string>…)
- being able to register lambda which can have variadic template arguments
Regarding #2 issue, people would agree it should have been called ‘delegator’ or ‘deferred caller’. Its concept is basically same. Accepts a functor, saves it and calls it later. Then, how can I save functor which can have variadic number and types without using variant?
I got a hint from the Codeproject article, and implemented as follows. The routing_delegator structure is a container owns a pointer to the routing_record interface pointer.
‘to(F&& f)’ is lambda subscribing function. If user tries to pass a lambda to the function, you can figure out the lambda’s parameters by specifying operator() functor signature to a specialized template below. (refer to this SO link)
The typed_routing_recored is the template class, and lambda signature will be deduced, and the typed figured out all will be saved to the std::function.
How about calling the saved functors? The routing_record is an interface and declares one abstract function – which is ‘handle(void*)’. As you might guess from its name, void* is the key point to enable accept variadic sized, typed arguments.
If user calls ‘handle’ with parameters, routing_delegator::handle(Args&&… args) wconverterts those parameters into tuple and passes it to the routing_record::handle(void*) with its address
And finally child class’s handle(void*) implementation will casts into tuple again and delivers it to the actual std::function functor.
You can check out the all code here, https://github.com/heejune/tinyweb-cppserver/blob/develop/router.h
Please be warned, it’s still in development and all experimental code. Thanks!