#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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uIFR5cGVzPiBzdHJ1Y3QgR2VuS2V5Owp0ZW1wbGF0ZSA8dHlwZW5hbWUgUiwgdHlwZW5hbWUgLi4uIFR5cGVzPiBzdHJ1Y3QgR2VuS2V5IDxSLCBUeXBlcy4uLj4gOiBwdWJsaWMgR2VuS2V5PFR5cGVzLi4uPnsKCXRlbXBsYXRlIDx0eXBlbmFtZSBQPiAKCWNvbnN0ZXhwciBib29sIG9wZXJhdG9yKCkoY29uc3QgUCZwKSBjb25zdCB7IHJldHVybiBpc19zYW1lPFIsUD46OnZhbHVlIHx8IEdlbktleTxUeXBlcy4uLj46Om9wZXJhdG9yKCkocCk7IH0KfTsKdGVtcGxhdGUgPHR5cGVuYW1lIFI+IHN0cnVjdCBHZW5LZXkgPFI+ewoJdGVtcGxhdGUgPHR5cGVuYW1lIFA+IAoJY29uc3RleHByIGJvb2wgb3BlcmF0b3IoKShjb25zdCBQJikgY29uc3QgeyByZXR1cm4gaXNfc2FtZTxSLFA+Ojp2YWx1ZTsgfQp9Owp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgR2VuS2V5IDw+ewoJdGVtcGxhdGUgPHR5cGVuYW1lIFA+IAoJY29uc3RleHByIGJvb2wgb3BlcmF0b3IoKShjb25zdCBQJikgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KfTsKCmNsYXNzIFNlcnZlciAgewoJcHVibGljOgpzdHJ1Y3QgY29tbW9ue307CnN0cnVjdCBjYW5FZGl0e307CnN0cnVjdCBjYW5LaWxse307CglwdWJsaWM6CglTZXJ2ZXIoKXt9Cgl2b2lkIGV4ZWMoY29uc3QgYXV0byYga2V5KSB7CgkJaWYgKGtleShjb21tb24oKSkpIHsKCQkJZXhlY0NvbW1vbigpOwoJCX0KCQlpZiAoa2V5KGNhbkVkaXQoKSkpIHsKCQkJZXhlY0NhbkVkaXQoKTsKCQl9CgkJaWYgKGtleShjYW5LaWxsKCkpKSB7CgkJCWV4ZWNDYW5LaWxsKCk7CgkJfQoJfQoJcHJpdmF0ZTogCgl2b2lkIGV4ZWNDb21tb24oKSB7CgkJY291dCA8PCAiY29tbW9uIGV4ZWMiIDw8IGVuZGw7Cgl9Cgl2b2lkIGV4ZWNDYW5FZGl0KCkgewoJCWNvdXQgPDwgImVkaXQgZXhlYyIgPDwgZW5kbDsKCX0KCXZvaWQgZXhlY0NhbktpbGwoKSB7CgkJY291dCA8PCAia2lsbCBleGVjIiA8PCBlbmRsOwoJfQp9OwoKaW50IG1haW4oKSB7CglTZXJ2ZXIgc2VydmVyOwoJY291dCA8PCAia2V5MCIgPDwgZW5kbDsKCXNlcnZlci5leGVjKEdlbktleTw+KCkpOwoJY291dCA8PCAia2V5MSIgPDwgZW5kbDsKCXNlcnZlci5leGVjKEdlbktleTxTZXJ2ZXI6OmNvbW1vbixTZXJ2ZXI6OmNhbkVkaXQ+KCkpOwoJcmV0dXJuIDA7Cn0=