#include <iostream>
struct csv_t { };
csv_t csv;
struct chain
{
bool first, alive;
std::ostream* stream;
chain(std::ostream* stream) : first(true), alive(true), stream(stream) { }
chain(chain&& src) : first(false), alive(src.alive), stream(src.stream)
{ src.alive = false; }
~chain() { if(alive) *stream << "\n"; }
};
chain operator<<(std::ostream& str, csv_t& csv)
{
return chain(&str);
}
template<typename T>
chain operator<<(chain c, T const& arg)
{
if(c.first) c.first = false;
else *c.stream << ",";
*c.stream << arg;
return c;
}
int main() {
std::cout << csv << 1 << "abc" << 3.14f;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IGNzdl90IHsgfTsKY3N2X3QgY3N2OwoKc3RydWN0IGNoYWluCnsKCWJvb2wgZmlyc3QsIGFsaXZlOwoJc3RkOjpvc3RyZWFtKiBzdHJlYW07CgkKCWNoYWluKHN0ZDo6b3N0cmVhbSogc3RyZWFtKSA6IGZpcnN0KHRydWUpLCBhbGl2ZSh0cnVlKSwgc3RyZWFtKHN0cmVhbSkgeyB9CgkKCWNoYWluKGNoYWluJiYgc3JjKSA6IGZpcnN0KGZhbHNlKSwgYWxpdmUoc3JjLmFsaXZlKSwgc3RyZWFtKHNyYy5zdHJlYW0pCgl7IHNyYy5hbGl2ZSA9IGZhbHNlOyB9CgkKCX5jaGFpbigpIHsgaWYoYWxpdmUpICpzdHJlYW0gPDwgIlxuIjsgfQp9OwoKY2hhaW4gb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIHN0ciwgY3N2X3QmIGNzdikKewoJcmV0dXJuIGNoYWluKCZzdHIpOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjaGFpbiBvcGVyYXRvcjw8KGNoYWluIGMsIFQgY29uc3QmIGFyZykKewoJaWYoYy5maXJzdCkgYy5maXJzdCA9IGZhbHNlOwoJZWxzZSAqYy5zdHJlYW0gPDwgIiwiOwoJKmMuc3RyZWFtIDw8IGFyZzsKCXJldHVybiBjOwp9CgppbnQgbWFpbigpIHsKCXN0ZDo6Y291dCA8PCBjc3YgPDwgMSA8PCAiYWJjIiA8PCAzLjE0ZjsKfQ==