template<typename T, class...Fs> struct visitor_t;
template<typename T, class F1, class...Fs>
struct visitor_t<T, F1, Fs...> : F1, visitor_t<T, Fs...>::type {
typedef visitor_t type;
visitor_t(F1 head, Fs...tail) : F1(head), visitor_t<T, Fs...>::type(tail...) {}
using F1::operator();
using visitor_t<T, Fs...>::type::operator();
};
template<typename T, class F> struct visitor_t<T, F> : F, boost::static_visitor<T> {
typedef visitor_t type;
visitor_t(F f) : F(f) {}
using F::operator();
};
template<typename T=void, class...Fs>
typename visitor_t<T, Fs...>::type make_visitor(Fs...x) { return {x...}; }
struct Person
{
std::string name;
double height, weight;
friend std::ostream& operator<<(std::ostream& os, Person const& s) {
return os << "Person { name:" << s.name << ", height:" << s.height << ", weight:" << s.weight << " }";
}
};
dGVtcGxhdGU8dHlwZW5hbWUgVCwgY2xhc3MuLi5Gcz4gc3RydWN0IHZpc2l0b3JfdDsKIAp0ZW1wbGF0ZTx0eXBlbmFtZSBULCBjbGFzcyBGMSwgY2xhc3MuLi5Gcz4Kc3RydWN0IHZpc2l0b3JfdDxULCBGMSwgRnMuLi4+IDogRjEsIHZpc2l0b3JfdDxULCBGcy4uLj46OnR5cGUgewogICAgdHlwZWRlZiB2aXNpdG9yX3QgdHlwZTsKICAgIHZpc2l0b3JfdChGMSBoZWFkLCBGcy4uLnRhaWwpIDogRjEoaGVhZCksIHZpc2l0b3JfdDxULCBGcy4uLj46OnR5cGUodGFpbC4uLikge30KICAgIAogICAgdXNpbmcgRjE6Om9wZXJhdG9yKCk7CiAgICB1c2luZyB2aXNpdG9yX3Q8VCwgRnMuLi4+Ojp0eXBlOjpvcGVyYXRvcigpOwp9OwogCnRlbXBsYXRlPHR5cGVuYW1lIFQsIGNsYXNzIEY+IHN0cnVjdCB2aXNpdG9yX3Q8VCwgRj4gOiBGLCBib29zdDo6c3RhdGljX3Zpc2l0b3I8VD4gewogICAgdHlwZWRlZiB2aXNpdG9yX3QgdHlwZTsKICAgIHZpc2l0b3JfdChGIGYpIDogRihmKSB7fQogICAgdXNpbmcgRjo6b3BlcmF0b3IoKTsKfTsKIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUPXZvaWQsIGNsYXNzLi4uRnM+CnR5cGVuYW1lIHZpc2l0b3JfdDxULCBGcy4uLj46OnR5cGUgbWFrZV92aXNpdG9yKEZzLi4ueCkgeyByZXR1cm4ge3guLi59OyB9CgpzdHJ1Y3QgUGVyc29uCnsKICAgIHN0ZDo6c3RyaW5nIG5hbWU7CiAgICBkb3VibGUgaGVpZ2h0LCB3ZWlnaHQ7CiAgICBmcmllbmQgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIFBlcnNvbiBjb25zdCYgcykgewogICAgICAgIHJldHVybiBvcyA8PCAiUGVyc29uIHsgbmFtZToiIDw8IHMubmFtZSA8PCAiLCBoZWlnaHQ6IiA8PCBzLmhlaWdodCA8PCAiLCB3ZWlnaHQ6IiA8PCBzLndlaWdodCA8PCAiIH0iOwogICAgfQp9OwoK