I've got a function
template<typename T, typename FuncT, typename ... Args>
static void Submit(Handle<T> handle, FuncT&& funcT, Args&& ... args);
Handle
is a class that contains an index to the data inside some array. This data can be retrieved through a handle_cast
function.
T& data = *handle_cast<T*>(handle);
I'm not going to cover this implementation, because it's not related to my question.
Handle<T> handle
is the main handle to a resource. I'd like args
to be a mix, sometimes it'd be a handle, sometimes a different data.
FuncT
first argument is T&
and the rest of the arguments might be either *handle_cast<Args*>
if this argument is Handle<Some Type>
or just Arg
I came out with this solution, but I'm not sure if it's correct or maybe it could be done easier.
template<typename T, typename FuncT, typename ... Args>
static void Submit(Handle<T> handle, FuncT&& funcT, Args&& ... args)
{
std::variant<Args...> v;
bool isHandle = std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_base_of_v<HandleBase, T>) {
return true;
} return false;
}, v);
func(*handle_cast<T*>(handle), std::forward<Args>(isHandle ? *handle_cast<Args*>(args) : args)...);
}
Is this solution ok or it can be done easier/cleaner?
CodePudding user response:
You may be looking for something like this (not tested):
// Cloned from the standard std::forward
template<typename T>
T&& maybe_handle_forward(typename std::remove_reference<T>::type& t ) noexcept {
return std::forward<T>(t);
}
template<typename T>
T& maybe_handle_forward(Handle<T> h) noexcept {
return *handle_cast<T*>(h);
}
Now you can write
func(*handle_cast<T*>(handle), maybe_handle_forward<Args>(args)...);