#include <iostream>
//
// Shim interface
//
struct Interface {
virtual void print(std::ostream& out) const = 0;
}; // struct Interface
std::ostream& operator<<(std::ostream& out, Interface const& i) {
i.print(out);
return out;
}
template <typename T>
struct IT: public Interface {
IT(T const& t): _t(t) {}
virtual void print(std::ostream& out) const { out << _t; }
T const& _t;
};
template <typename T>
IT<T> shim(T const& t) { return IT<T>(t); }
//
// printf (or it could be!)
//
void printf_impl(char const*, std::initializer_list<Interface const*> array) {
typedef std::initializer_list<Interface const*>::const_iterator It;
for (It it = array.begin(), end = array.end(); it != end; ++it) { std::cout << **it; }
std::cout << "\n";
}
template <typename... T>
void printf_bridge(char const* format, T const&... t) {
printf_impl(format, {(&t)...});
}
template <typename... T>
void printf(char const* format, T const&... t) {
printf_bridge(format, ((Interface const&)shim(t))...);
}
//
// Usage
//
struct Pair { int first; int second; };
std::ostream& operator<<(std::ostream& out, Pair const& p) {
return out << "(" << p.first << ", " << p.second << ")";
}
int main() {
Pair const p = { 1, 2 };
printf("unused", 1, 4, p);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKLy8KLy8gU2hpbSBpbnRlcmZhY2UKLy8Kc3RydWN0IEludGVyZmFjZSB7CiAgICB2aXJ0dWFsIHZvaWQgcHJpbnQoc3RkOjpvc3RyZWFtJiBvdXQpIGNvbnN0ID0gMDsKfTsgLy8gc3RydWN0IEludGVyZmFjZQoKc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3V0LCBJbnRlcmZhY2UgY29uc3QmIGkpIHsKICAgIGkucHJpbnQob3V0KTsKICAgIHJldHVybiBvdXQ7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgSVQ6IHB1YmxpYyBJbnRlcmZhY2UgewogICAgSVQoVCBjb25zdCYgdCk6IF90KHQpIHt9CiAgICB2aXJ0dWFsIHZvaWQgcHJpbnQoc3RkOjpvc3RyZWFtJiBvdXQpIGNvbnN0IHsgb3V0IDw8IF90OyB9CiAgICBUIGNvbnN0JiBfdDsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpJVDxUPiBzaGltKFQgY29uc3QmIHQpIHsgcmV0dXJuIElUPFQ+KHQpOyB9CgovLwovLyBwcmludGYgKG9yIGl0IGNvdWxkIGJlISkKLy8Kdm9pZCBwcmludGZfaW1wbChjaGFyIGNvbnN0Kiwgc3RkOjppbml0aWFsaXplcl9saXN0PEludGVyZmFjZSBjb25zdCo+IGFycmF5KSB7CiAgICB0eXBlZGVmIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxJbnRlcmZhY2UgY29uc3QqPjo6Y29uc3RfaXRlcmF0b3IgSXQ7CiAgICBmb3IgKEl0IGl0ID0gYXJyYXkuYmVnaW4oKSwgZW5kID0gYXJyYXkuZW5kKCk7IGl0ICE9IGVuZDsgKytpdCkgeyBzdGQ6OmNvdXQgPDwgKippdDsgfQogICAgc3RkOjpjb3V0IDw8ICJcbiI7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUPgp2b2lkIHByaW50Zl9icmlkZ2UoY2hhciBjb25zdCogZm9ybWF0LCBUIGNvbnN0Ji4uLiB0KSB7CiAgICBwcmludGZfaW1wbChmb3JtYXQsIHsoJnQpLi4ufSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUPgp2b2lkIHByaW50ZihjaGFyIGNvbnN0KiBmb3JtYXQsIFQgY29uc3QmLi4uIHQpIHsKICAgIHByaW50Zl9icmlkZ2UoZm9ybWF0LCAoKEludGVyZmFjZSBjb25zdCYpc2hpbSh0KSkuLi4pOwp9CgovLwovLyBVc2FnZQovLwpzdHJ1Y3QgUGFpciB7IGludCBmaXJzdDsgaW50IHNlY29uZDsgfTsKc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3V0LCBQYWlyIGNvbnN0JiBwKSB7CiAgICByZXR1cm4gb3V0IDw8ICIoIiA8PCBwLmZpcnN0IDw8ICIsICIgPDwgcC5zZWNvbmQgPDwgIikiOwp9CgppbnQgbWFpbigpIHsKICAgIFBhaXIgY29uc3QgcCA9IHsgMSwgMiB9OwogICAgcHJpbnRmKCJ1bnVzZWQiLCAxLCA0LCBwKTsKfQ==