#include <iostream>
#include <type_traits>
using namespace std;

template <typename ... Types> struct GenKey;
template <typename R, typename ... Types> struct GenKey <R, Types...> : public GenKey<Types...>{
	template <typename P> 
	constexpr bool operator()(const P&p) const { return is_same<R,P>::value || GenKey<Types...>::operator()(p); }
};
template <typename R> struct GenKey <R>{
	template <typename P> 
	constexpr bool operator()(const P&) const { return is_same<R,P>::value; }
};
template <> struct GenKey <>{
	template <typename P> 
	constexpr bool operator()(const P&) const { return false; }
};

class Server  {
	public:
struct common{};
struct canEdit{};
struct canKill{};
	public:
	Server(){}
	void exec(const auto& key) {
		if (key(common())) {
			execCommon();
		}
		if (key(canEdit())) {
			execCanEdit();
		}
		if (key(canKill())) {
			execCanKill();
		}
	}
	private: 
	void execCommon() {
		cout << "common exec" << endl;
	}
	void execCanEdit() {
		cout << "edit exec" << endl;
	}
	void execCanKill() {
		cout << "kill exec" << endl;
	}
};

int main() {
	Server server;
	cout << "key0" << endl;
	server.exec(GenKey<>());
	cout << "key1" << endl;
	server.exec(GenKey<Server::common,Server::canEdit>());
	return 0;
}