// helper
template<unsigned N>
struct priority : priority<N-1>{};
template<> struct priority<0>{};
// []foo would result in:
struct __unnamed__{
template<class... Ts>
auto operator()(Ts&&... vs)
-> decltype(call(priority<5>{}, std::forward<Ts>(vs)...))
{
return call(priority<5>{}, std::forward<Ts>(vs)...);
}
private:
template<class C, class... Ts>
auto call(priority<5>, C&& o, Ts&&... vs)
-> decltype(std::forward<C>(o).foo(std::forward<Ts>(vs)...))
{
return std::forward<C>(o).foo(std::forward<Ts>(vs)...);
}
template<class C, class... Ts>
auto call(priority<4>, C&& o, Ts&&... vs)
-> decltype(std::forward<C>(o)->foo(std::forward<Ts>(vs)...))
{
return std::forward<C>(o)->foo(std::forward<Ts>(vs)...);
}
template<class C>
auto call(priority<3>, C&& o)
-> decltype(std::forward<C>(o).foo)
{
return std::forward<C>(o).foo;
}
template<class C>
auto call(priority<2>, C&& o)
-> decltype(std::forward<C>(o)->foo)
{
return std::forward<C>(o)->foo;
}
template<class... Ts>
auto call(priority<1>, Ts&&... vs)
-> decltype(foo(std::forward<Ts>(vs)...))
{
return foo(std::forward<Ts>(vs)...);
}
};
Ly8gaGVscGVyCnRlbXBsYXRlPHVuc2lnbmVkIE4+CnN0cnVjdCBwcmlvcml0eSA6IHByaW9yaXR5PE4tMT57fTsKdGVtcGxhdGU8PiBzdHJ1Y3QgcHJpb3JpdHk8MD57fTsKCi8vIFtdZm9vIHdvdWxkIHJlc3VsdCBpbjoKCnN0cnVjdCBfX3VubmFtZWRfX3sKICB0ZW1wbGF0ZTxjbGFzcy4uLiBUcz4KICBhdXRvIG9wZXJhdG9yKCkoVHMmJi4uLiB2cykKICAgICAgLT4gZGVjbHR5cGUoY2FsbChwcmlvcml0eTw1Pnt9LCBzdGQ6OmZvcndhcmQ8VHM+KHZzKS4uLikpCiAgewogICAgcmV0dXJuIGNhbGwocHJpb3JpdHk8NT57fSwgc3RkOjpmb3J3YXJkPFRzPih2cykuLi4pOwogIH0KICAKcHJpdmF0ZToKICB0ZW1wbGF0ZTxjbGFzcyBDLCBjbGFzcy4uLiBUcz4KICBhdXRvIGNhbGwocHJpb3JpdHk8NT4sIEMmJiBvLCBUcyYmLi4uIHZzKQogICAgICAtPiBkZWNsdHlwZShzdGQ6OmZvcndhcmQ8Qz4obykuZm9vKHN0ZDo6Zm9yd2FyZDxUcz4odnMpLi4uKSkKICB7CiAgICByZXR1cm4gc3RkOjpmb3J3YXJkPEM+KG8pLmZvbyhzdGQ6OmZvcndhcmQ8VHM+KHZzKS4uLik7CiAgfQogIAogIHRlbXBsYXRlPGNsYXNzIEMsIGNsYXNzLi4uIFRzPgogIGF1dG8gY2FsbChwcmlvcml0eTw0PiwgQyYmIG8sIFRzJiYuLi4gdnMpCiAgICAgIC0+IGRlY2x0eXBlKHN0ZDo6Zm9yd2FyZDxDPihvKS0+Zm9vKHN0ZDo6Zm9yd2FyZDxUcz4odnMpLi4uKSkKICB7CiAgICByZXR1cm4gc3RkOjpmb3J3YXJkPEM+KG8pLT5mb28oc3RkOjpmb3J3YXJkPFRzPih2cykuLi4pOwogIH0KICAKICB0ZW1wbGF0ZTxjbGFzcyBDPgogIGF1dG8gY2FsbChwcmlvcml0eTwzPiwgQyYmIG8pCiAgICAgIC0+IGRlY2x0eXBlKHN0ZDo6Zm9yd2FyZDxDPihvKS5mb28pCiAgewogICAgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxDPihvKS5mb287CiAgfQogIAogIHRlbXBsYXRlPGNsYXNzIEM+CiAgYXV0byBjYWxsKHByaW9yaXR5PDI+LCBDJiYgbykKICAgICAgLT4gZGVjbHR5cGUoc3RkOjpmb3J3YXJkPEM+KG8pLT5mb28pCiAgewogICAgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxDPihvKS0+Zm9vOwogIH0KICAKICB0ZW1wbGF0ZTxjbGFzcy4uLiBUcz4KICBhdXRvIGNhbGwocHJpb3JpdHk8MT4sIFRzJiYuLi4gdnMpCiAgICAgIC0+IGRlY2x0eXBlKGZvbyhzdGQ6OmZvcndhcmQ8VHM+KHZzKS4uLikpCiAgewogICAgcmV0dXJuIGZvbyhzdGQ6OmZvcndhcmQ8VHM+KHZzKS4uLik7CiAgfQp9Ow==