Skip to content

Instantly share code, notes, and snippets.

@LB--
Last active March 22, 2018 02:35
Show Gist options
  • Save LB--/74961099b32d6554ca1d03a66c30207a to your computer and use it in GitHub Desktop.
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.
#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