#include <mutex>
#include <iostream>
class locked_stream
{
static std::mutex s_out_mutex;
std::unique_lock<std::mutex> lock_;
std::ostream* stream_; // can't make this reference so we can move
public:
locked_stream(std::ostream& stream)
: lock_(s_out_mutex)
, stream_(&stream)
{ }
locked_stream(locked_stream&& other)
: lock_(std::move(other.lock_))
, stream_(other.stream_)
{
other.stream_ = nullptr;
}
friend locked_stream&& operator << (locked_stream&& s, std::ostream& (*arg)(std::ostream&))
{
(*s.stream_) << arg;
return std::move(s);
}
template <typename Arg>
friend locked_stream&& operator << (locked_stream&& s, Arg&& arg)
{
(*s.stream_) << std::forward<Arg>(arg);
return std::move(s);
}
};
std::mutex locked_stream::s_out_mutex{};
locked_stream locked_cout()
{
return locked_stream(std::cout);
}
int main (int argc, char * argv[])
{
locked_cout() << "hello world: " << 1 << 3.14 << std::endl;
return 0;
}
I2luY2x1ZGUgPG11dGV4PgojaW5jbHVkZSA8aW9zdHJlYW0+CgoKY2xhc3MgbG9ja2VkX3N0cmVhbQp7CglzdGF0aWMgc3RkOjptdXRleCBzX291dF9tdXRleDsKIAkKCXN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9ja187CglzdGQ6Om9zdHJlYW0qIHN0cmVhbV87IC8vIGNhbid0IG1ha2UgdGhpcyByZWZlcmVuY2Ugc28gd2UgY2FuIG1vdmUKCnB1YmxpYzoKCWxvY2tlZF9zdHJlYW0oc3RkOjpvc3RyZWFtJiBzdHJlYW0pCgkJOiBsb2NrXyhzX291dF9tdXRleCkKCQksIHN0cmVhbV8oJnN0cmVhbSkKICAgIHsgfQogIAoJbG9ja2VkX3N0cmVhbShsb2NrZWRfc3RyZWFtJiYgb3RoZXIpCgkJOiBsb2NrXyhzdGQ6Om1vdmUob3RoZXIubG9ja18pKQoJCSwgc3RyZWFtXyhvdGhlci5zdHJlYW1fKQoJewoJCW90aGVyLnN0cmVhbV8gPSBudWxscHRyOwoJfQogIAogICAgZnJpZW5kIGxvY2tlZF9zdHJlYW0mJiBvcGVyYXRvciA8PCAobG9ja2VkX3N0cmVhbSYmIHMsIHN0ZDo6b3N0cmVhbSYgKCphcmcpKHN0ZDo6b3N0cmVhbSYpKQogICAgewoJCSgqcy5zdHJlYW1fKSA8PCBhcmc7CiAgICAJcmV0dXJuIHN0ZDo6bW92ZShzKTsKICAgIH0KICAKICAJdGVtcGxhdGUgPHR5cGVuYW1lIEFyZz4KICAgIGZyaWVuZCBsb2NrZWRfc3RyZWFtJiYgb3BlcmF0b3IgPDwgKGxvY2tlZF9zdHJlYW0mJiBzLCBBcmcmJiBhcmcpCiAgICB7CgkJKCpzLnN0cmVhbV8pIDw8IHN0ZDo6Zm9yd2FyZDxBcmc+KGFyZyk7CiAgICAJcmV0dXJuIHN0ZDo6bW92ZShzKTsKICAgIH0KfTsKCnN0ZDo6bXV0ZXggbG9ja2VkX3N0cmVhbTo6c19vdXRfbXV0ZXh7fTsKCmxvY2tlZF9zdHJlYW0gbG9ja2VkX2NvdXQoKQp7CglyZXR1cm4gbG9ja2VkX3N0cmVhbShzdGQ6OmNvdXQpOwp9CgppbnQgbWFpbiAoaW50IGFyZ2MsIGNoYXIgKiBhcmd2W10pCnsKIAlsb2NrZWRfY291dCgpIDw8ICJoZWxsbyB3b3JsZDogIiA8PCAxIDw8IDMuMTQgPDwgc3RkOjplbmRsOwoJcmV0dXJuIDA7Cn0=