Skip to content

Instantly share code, notes, and snippets.

@gatchamix
Created September 7, 2017 16:07
Show Gist options
  • Save gatchamix/217a6d5376d7a78f86125f2bbabb3121 to your computer and use it in GitHub Desktop.
Save gatchamix/217a6d5376d7a78f86125f2bbabb3121 to your computer and use it in GitHub Desktop.
improvement to static class design using hana::is_valid + C++2a explicit lambda templates
#include <utility>
//
template <class F, class... Args,
class = decltype(std::declval<F&&>()(std::declval<Args&&>()...))>
auto constexpr is_valid_impl(int)
{ return true; }
template <class F, class... Args>
auto constexpr is_valid_impl(...)
{ return false; }
template <class F>
constexpr auto is_valid(F&&)
{
return [](auto&& ...args)
{ return is_valid_impl<F&&, decltype(args)&&...>(int{}); };
}
//
template <class... Ts>
struct type_list
{};
template <class R, class T>
auto constexpr match(R T::*)
{}
template <class R>
auto constexpr match(R)
{}
//
template <class T>
struct base
{
constexpr base()
{
auto constexpr has_func = is_valid([]<class Sig>(type_list<Sig>)
-> decltype(match<Sig>(&T::func)){});
static_assert(has_func(type_list<void()>{}));
static_assert(has_func(type_list<void() const>{}));
}
};
template <template <class> class T>
struct derived : public T<derived<T>>
{
using base_t = T<derived<T>>;
friend base_t;
private:
void func() {}
void func() const {}
};
//
int main()
{
volatile auto constexpr test = derived<base>{};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment