#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 <typename ... Ts>
struct overload {};
template <typename T>
struct overload<T> : T
{
template <typename U>
overload(U&& u) : T(std::forward<U>(u)) {}
using T::operator();
};
template <typename T, typename ... Ts>
struct overload<T, Ts...> : overload<T>, overload<Ts...>
{
template <typename U, typename ... Us>
overload(U&& arg, Us&&... args) : overload<T>(std::forward<U>(arg)), overload<Ts...>(std::forward<Us>(args)...) {}
using overload<T>::operator();
using overload<Ts...>::operator();
};
template<class... Ts>
overload<std::decay_t<Ts>...> make_overload(Ts&&... args)
{
return { std::forward<Ts>(args)... };
}
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, make_overload(
[](const auto& value) -> decltype(fooint(value.bar())) { return value.bar(); },
[](fallback_t){ 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+CiNpbmNsdWRlIDx1dGlsaXR5PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBvbmUgewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAwOyB9CiAgaW50IGJhcigpIHsgcmV0dXJuIDA7IH0KfTsKCnN0cnVjdCB0d28gewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAxOyB9Cn07CgpzdHJ1Y3QgdGhyZWUgewogIGludCBmb28oY29uc3QgaW50KSB7IHJldHVybiAyOyB9CiAgaW50IGJhcigpIHsgcmV0dXJuIDI7IH0KfTsKCnN0cnVjdCBvd25lciB7CiAgbWFwPGludCwgb25lPiBvbmVzOwogIG1hcDxpbnQsIHR3bz4gdHdvczsKICBtYXA8aW50LCB0aHJlZT4gdGhyZWVzOwoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uIFRzPgogIHN0cnVjdCBvdmVybG9hZCB7fTsKCiAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgc3RydWN0IG92ZXJsb2FkPFQ+IDogVAogIHsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogICAgb3ZlcmxvYWQoVSYmIHUpIDogVChzdGQ6OmZvcndhcmQ8VT4odSkpIHt9CgogICAgdXNpbmcgVDo6b3BlcmF0b3IoKTsKICB9OwoKCiAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLiBUcz4KICBzdHJ1Y3Qgb3ZlcmxvYWQ8VCwgVHMuLi4+IDogb3ZlcmxvYWQ8VD4sIG92ZXJsb2FkPFRzLi4uPgogIHsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBVLCB0eXBlbmFtZSAuLi4gVXM+CiAgICBvdmVybG9hZChVJiYgYXJnLCBVcyYmLi4uIGFyZ3MpIDogb3ZlcmxvYWQ8VD4oc3RkOjpmb3J3YXJkPFU+KGFyZykpLCBvdmVybG9hZDxUcy4uLj4oc3RkOjpmb3J3YXJkPFVzPihhcmdzKS4uLikge30KCiAgICB1c2luZyBvdmVybG9hZDxUPjo6b3BlcmF0b3IoKTsKICAgIHVzaW5nIG92ZXJsb2FkPFRzLi4uPjo6b3BlcmF0b3IoKTsKICB9OwoKICB0ZW1wbGF0ZTxjbGFzcy4uLiBUcz4KICBvdmVybG9hZDxzdGQ6OmRlY2F5X3Q8VHM+Li4uPiBtYWtlX292ZXJsb2FkKFRzJiYuLi4gYXJncykKICB7CiAgICByZXR1cm4geyBzdGQ6OmZvcndhcmQ8VHM+KGFyZ3MpLi4uIH07CiAgfQoKICBzdHJ1Y3QgZmFsbGJhY2tfdCB7IHRlbXBsYXRlPGNsYXNzIFQ+IGZhbGxiYWNrX3QoVCYmKSB7fSB9OwoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnVuYz4KICBpbnQgY2FsbEZ1bmMoVCYgcGFyYW0sIGNvbnN0IEZ1bmMmIGZ1bmMpIHsKICAgIHJldHVybiBmdW5jKHBhcmFtKTsKICB9CgogIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogIGludCBmaW5kT2JqZWN0KGludCBrZXksIGNvbnN0IFQmIGZ1bmMpIHsKICAgIGlmKG9uZXMuY291bnQoa2V5KSAhPSAwVSkgewogICAgICByZXR1cm4gY2FsbEZ1bmMob25lc1trZXldLCBmdW5jKTsKICAgIH0KICAgIGVsc2UgaWYodHdvcy5jb3VudChrZXkpICE9IDBVKSB7CiAgICAgIHJldHVybiBjYWxsRnVuYyh0d29zW2tleV0sIGZ1bmMpOwogICAgfQogICAgZWxzZSB7CiAgICAgIHJldHVybiBjYWxsRnVuYyh0aHJlZXNba2V5XSwgZnVuYyk7CiAgICB9CiAgfQoKICBpbnQgZm9vKGNvbnN0IGludCBrZXksIGNvbnN0IGludCBwYXJhbSkgeyByZXR1cm4gZmluZE9iamVjdChrZXksIFsmXShhdXRvJiB2YWx1ZSkgeyByZXR1cm4gdmFsdWUuZm9vKHBhcmFtKTsgfSk7IH0KICBpbnQgYmFyKGNvbnN0IGludCBrZXkpIHsKICAgIHJldHVybiBmaW5kT2JqZWN0KGtleSwgbWFrZV9vdmVybG9hZCgKICAgICAgW10oY29uc3QgYXV0byYgdmFsdWUpIC0+IGRlY2x0eXBlKGZvb2ludCh2YWx1ZS5iYXIoKSkpIHsgcmV0dXJuIHZhbHVlLmJhcigpOyB9LAogICAgICBbXShmYWxsYmFja190KXsgc3RkOjpjb3V0IDw8ICJmYWxsYmFja1xuIjsgcmV0dXJuIDEzOyB9CiAgICAgICkpOwogIH0KfTsKCmludCBtYWluKCkgewogIG93bmVyIG15T3duZXI7CgogIG15T3duZXIub25lcy5pbnNlcnQobWFrZV9wYWlyKDAsIG9uZSgpKSk7CiAgbXlPd25lci50d29zLmluc2VydChtYWtlX3BhaXIoMSwgdHdvKCkpKTsKICBteU93bmVyLnRocmVlcy5pbnNlcnQobWFrZV9wYWlyKDIsIHRocmVlKCkpKTsKCiAgbXlPd25lci5mb28oMiwgMSk7CiAgY291dCA8PCBteU93bmVyLmJhcigxKSA8PCBlbmRsOwogIGNvdXQgPDwgbXlPd25lci5iYXIoMikgPDwgZW5kbDsKfQ==