#include <iostream>
#include <map>
#include <type_traits>
#include <utility>
using namespace std;
struct one {
int foo(const int) { return 0; }
int bar() { return 0; }
};
struct two {
int foo(const int) { return 1; }
};
struct three {
int foo(const int) { return 2; }
int bar() { return 2; }
};
struct owner {
map<int, one> ones;
map<int, two> twos;
map<int, three> threes;
template <class... Fs>
struct overload_t {};
//template<>
//struct overload_t {};
// >1
template <class F0, class... Frest>
struct overload_t<F0, Frest...> : F0, overload_t<Frest...>
{
overload_t(F0 f0, Frest... rest) : F0(std::move(f0)), overload_t<Frest...>(std::move(rest)...) {}
using F0::operator();
using overload_t<Frest...>::operator();
};
// 1
template <class F0>
struct overload_t<F0> : F0
{
overload_t(F0 f0) : F0(std::move(f0)) {}
using F0::operator();
};
template <class... Fs>
auto overload(Fs... fs)
{
return overload_t<Fs...>(std::move(fs)...);
}
struct fallback_t { template<class T> fallback_t(T&&) {} };
template <typename T, typename Func>
int callFunc(T& param, const Func& func) {
return func(param);
}
template <typename T>
int findObject(int key, const T& func) {
if(ones.count(key) != 0U) {
return callFunc(ones[key], func);
}
else if(twos.count(key) != 0U) {
return callFunc(twos[key], func);
}
else {
return callFunc(threes[key], func);
}
}
int foo(const int key, const int param) { return findObject(key, [&](auto& value) { return value.foo(param); }); }
int bar(const int key) {
return findObject(key, overload(
[](const auto& value) -> decltype(int(value.bar())) { return value.bar(); },
[](fallback_t) -> int { std::cout << "fallback\n"; return 13; }
));
}
};
int main() {
owner myOwner;
myOwner.ones.insert(make_pair(0, one()));
myOwner.twos.insert(make_pair(1, two()));
myOwner.threes.insert(make_pair(2, three()));
myOwner.foo(2, 1);
cout << myOwner.bar(1) << endl;
cout << myOwner.bar(2) << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBvbmUgewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAwOyB9CiAgaW50IGJhcigpIHsgcmV0dXJuIDA7IH0KfTsKCnN0cnVjdCB0d28gewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAxOyB9Cn07CgpzdHJ1Y3QgdGhyZWUgewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAyOyB9CiAgaW50IGJhcigpIHsgcmV0dXJuIDI7IH0KfTsKCnN0cnVjdCBvd25lciB7CiAgbWFwPGludCwgb25lPiBvbmVzOwogIG1hcDxpbnQsIHR3bz4gdHdvczsKICBtYXA8aW50LCB0aHJlZT4gdGhyZWVzOwoKICB0ZW1wbGF0ZSA8Y2xhc3MuLi4gRnM+CiAgc3RydWN0IG92ZXJsb2FkX3Qge307CgogIC8vdGVtcGxhdGU8PgogIC8vc3RydWN0IG92ZXJsb2FkX3Qge307CgogIC8vID4xCiAgdGVtcGxhdGUgPGNsYXNzIEYwLCBjbGFzcy4uLiBGcmVzdD4KICBzdHJ1Y3Qgb3ZlcmxvYWRfdDxGMCwgRnJlc3QuLi4+IDogRjAsIG92ZXJsb2FkX3Q8RnJlc3QuLi4+CiAgewogICAgb3ZlcmxvYWRfdChGMCBmMCwgRnJlc3QuLi4gcmVzdCkgOiBGMChzdGQ6Om1vdmUoZjApKSwgb3ZlcmxvYWRfdDxGcmVzdC4uLj4oc3RkOjptb3ZlKHJlc3QpLi4uKSB7fQoKICAgIHVzaW5nIEYwOjpvcGVyYXRvcigpOwogICAgdXNpbmcgb3ZlcmxvYWRfdDxGcmVzdC4uLj46Om9wZXJhdG9yKCk7CiAgfTsKCiAgLy8gMQogIHRlbXBsYXRlIDxjbGFzcyBGMD4KICBzdHJ1Y3Qgb3ZlcmxvYWRfdDxGMD4gOiBGMAogIHsKICAgIG92ZXJsb2FkX3QoRjAgZjApIDogRjAoc3RkOjptb3ZlKGYwKSkge30KCiAgICB1c2luZyBGMDo6b3BlcmF0b3IoKTsKICB9OwoKICB0ZW1wbGF0ZSA8Y2xhc3MuLi4gRnM+CiAgYXV0byBvdmVybG9hZChGcy4uLiBmcykKICB7CiAgICByZXR1cm4gb3ZlcmxvYWRfdDxGcy4uLj4oc3RkOjptb3ZlKGZzKS4uLik7CiAgfQoKICBzdHJ1Y3QgZmFsbGJhY2tfdCB7IHRlbXBsYXRlPGNsYXNzIFQ+IGZhbGxiYWNrX3QoVCYmKSB7fSB9OwoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnVuYz4KICBpbnQgY2FsbEZ1bmMoVCYgcGFyYW0sIGNvbnN0IEZ1bmMmIGZ1bmMpIHsKICAgIHJldHVybiBmdW5jKHBhcmFtKTsKICB9CgogIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogIGludCBmaW5kT2JqZWN0KGludCBrZXksIGNvbnN0IFQmIGZ1bmMpIHsKICAgIGlmKG9uZXMuY291bnQoa2V5KSAhPSAwVSkgewogICAgICByZXR1cm4gY2FsbEZ1bmMob25lc1trZXldLCBmdW5jKTsKICAgIH0KICAgIGVsc2UgaWYodHdvcy5jb3VudChrZXkpICE9IDBVKSB7CiAgICAgIHJldHVybiBjYWxsRnVuYyh0d29zW2tleV0sIGZ1bmMpOwogICAgfQogICAgZWxzZSB7CiAgICAgIHJldHVybiBjYWxsRnVuYyh0aHJlZXNba2V5XSwgZnVuYyk7CiAgICB9CiAgfQoKICBpbnQgZm9vKGNvbnN0IGludCBrZXksIGNvbnN0IGludCBwYXJhbSkgeyByZXR1cm4gZmluZE9iamVjdChrZXksIFsmXShhdXRvJiB2YWx1ZSkgeyByZXR1cm4gdmFsdWUuZm9vKHBhcmFtKTsgfSk7IH0KICBpbnQgYmFyKGNvbnN0IGludCBrZXkpIHsKICAgIHJldHVybiBmaW5kT2JqZWN0KGtleSwgb3ZlcmxvYWQoCiAgICAgIFtdKGNvbnN0IGF1dG8mIHZhbHVlKSAtPiBkZWNsdHlwZShpbnQodmFsdWUuYmFyKCkpKSB7IHJldHVybiB2YWx1ZS5iYXIoKTsgfSwKICAgICAgW10oZmFsbGJhY2tfdCkgLT4gaW50IHsgc3RkOjpjb3V0IDw8ICJmYWxsYmFja1xuIjsgcmV0dXJuIDEzOyB9CiAgICAgICkpOwogIH0KfTsKCmludCBtYWluKCkgewogIG93bmVyIG15T3duZXI7CgogIG15T3duZXIub25lcy5pbnNlcnQobWFrZV9wYWlyKDAsIG9uZSgpKSk7CiAgbXlPd25lci50d29zLmluc2VydChtYWtlX3BhaXIoMSwgdHdvKCkpKTsKICBteU93bmVyLnRocmVlcy5pbnNlcnQobWFrZV9wYWlyKDIsIHRocmVlKCkpKTsKCiAgbXlPd25lci5mb28oMiwgMSk7CiAgY291dCA8PCBteU93bmVyLmJhcigxKSA8PCBlbmRsOwogIGNvdXQgPDwgbXlPd25lci5iYXIoMikgPDwgZW5kbDsKfQ==