Last active
March 22, 2018 02:35
-
-
Save LB--/74961099b32d6554ca1d03a66c30207a to your computer and use it in GitHub Desktop.
I'm working on an implementation of std::overload. This is a simple ugly hacky version that only works with plain functions or +lambdas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <variant> | |
template<typename R, typename Arg> | |
using unary_func = R (*)(Arg); | |
template<typename R, typename... Arg> | |
struct Callable final | |
{ | |
std::add_pointer_t<void> const funcs[sizeof...(Arg)]; | |
template<typename GivenArg, std::size_t Index = 0> | |
static constexpr std::size_t index_of() | |
{ | |
static_assert(Index < sizeof...(Arg)); | |
if constexpr(std::is_convertible_v<GivenArg &, std::variant_alternative_t<Index, std::variant<Arg...>> &>) | |
{ | |
return Index; | |
} | |
else if constexpr(true) | |
{ | |
return index_of<GivenArg, Index+1>(); | |
} | |
} | |
template<typename GivenArg> | |
R operator()(GivenArg arg) | |
{ | |
return reinterpret_cast<unary_func<R, GivenArg>>(funcs[index_of<GivenArg>()])(arg); | |
} | |
}; | |
template<typename R, typename... Arg> | |
auto overload(unary_func<R, Arg>... funcs) | |
{ | |
using types = std::variant<Arg...>; | |
return Callable<R, Arg...>{{reinterpret_cast<void *>(funcs)...}}; | |
} | |
int main() | |
{ | |
short v = 100; | |
return overload | |
( | |
+[](char const v) | |
-> int | |
{ | |
return v+1; | |
}, | |
+[](short v) | |
-> int | |
{ | |
return v+2; | |
}, | |
+[](int &v) | |
-> int | |
{ | |
return v+3; | |
} | |
)(v); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment