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