#include <iostream>
#include <string>
using namespace std;
class Stream;
class StreamTemporary
{
public:
StreamTemporary(Stream& s) : _s(s) {}
StreamTemporary& operator<<(const string& str);
~StreamTemporary();
private:
Stream& _s;
};
class Stream
{
public:
StreamTemporary operator<<(const string& str)
{
write(str);
return StreamTemporary(*this);
}
private:
friend class StreamTemporary;
// write without returning a temporary
void write(const string& str)
{
cout << str;
}
};
StreamTemporary::~StreamTemporary()
{
// make sure not to call operator<< here or there will be infinite recursion
_s.write("\n");
}
StreamTemporary& StreamTemporary::operator<<(const string& str)
{
// make sure not to call operator<< here or extra newlines will be printed
_s.write(str);
}
int main() {
Stream myStream;
myStream << "Hello, " << "World!";
myStream << "a" << "b" << "c";
myStream << "end of program";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgU3RyZWFtOwpjbGFzcyBTdHJlYW1UZW1wb3JhcnkKewpwdWJsaWM6CglTdHJlYW1UZW1wb3JhcnkoU3RyZWFtJiBzKSA6IF9zKHMpIHt9CglTdHJlYW1UZW1wb3JhcnkmIG9wZXJhdG9yPDwoY29uc3Qgc3RyaW5nJiBzdHIpOwoJflN0cmVhbVRlbXBvcmFyeSgpOwpwcml2YXRlOgoJU3RyZWFtJiBfczsKfTsKCmNsYXNzIFN0cmVhbQp7CnB1YmxpYzoKCVN0cmVhbVRlbXBvcmFyeSBvcGVyYXRvcjw8KGNvbnN0IHN0cmluZyYgc3RyKQoJewoJCXdyaXRlKHN0cik7CgkJcmV0dXJuIFN0cmVhbVRlbXBvcmFyeSgqdGhpcyk7Cgl9CnByaXZhdGU6CglmcmllbmQgY2xhc3MgU3RyZWFtVGVtcG9yYXJ5OwoJLy8gd3JpdGUgd2l0aG91dCByZXR1cm5pbmcgYSB0ZW1wb3JhcnkKCXZvaWQgd3JpdGUoY29uc3Qgc3RyaW5nJiBzdHIpCgl7CgkJY291dCA8PCBzdHI7Cgl9Cn07CgpTdHJlYW1UZW1wb3Jhcnk6On5TdHJlYW1UZW1wb3JhcnkoKQp7CgkvLyBtYWtlIHN1cmUgbm90IHRvIGNhbGwgb3BlcmF0b3I8PCBoZXJlIG9yIHRoZXJlIHdpbGwgYmUgaW5maW5pdGUgcmVjdXJzaW9uCglfcy53cml0ZSgiXG4iKTsKfQoKU3RyZWFtVGVtcG9yYXJ5JiBTdHJlYW1UZW1wb3Jhcnk6Om9wZXJhdG9yPDwoY29uc3Qgc3RyaW5nJiBzdHIpCnsJCgkvLyBtYWtlIHN1cmUgbm90IHRvIGNhbGwgb3BlcmF0b3I8PCBoZXJlIG9yIGV4dHJhIG5ld2xpbmVzIHdpbGwgYmUgcHJpbnRlZAoJX3Mud3JpdGUoc3RyKTsKfQoKaW50IG1haW4oKSB7CglTdHJlYW0gbXlTdHJlYW07CglteVN0cmVhbSA8PCAiSGVsbG8sICIgPDwgIldvcmxkISI7CglteVN0cmVhbSA8PCAiYSIgPDwgImIiIDw8ICJjIjsKCW15U3RyZWFtIDw8ICJlbmQgb2YgcHJvZ3JhbSI7Cn0=