#include namespace psemek::io { namespace { struct synchronized_stream_impl : ostream { synchronized_stream_impl(std::shared_ptr stream, std::vector> others) : stream_(std::move(stream)) , others_(std::move(others)) {} std::size_t write(char const * p, std::size_t size) override { for (auto const & ptr : others_) if (auto stream = ptr.lock()) stream->flush(); return stream_->write(p, size); } void flush() override { stream_->flush(); } private: std::shared_ptr stream_; std::vector> others_; }; } // Convert a set of output streams to a set of mutually // synchronized streams: writing to any of the streams // flushes all the other streams std::vector> synchronized(std::vector> streams) { std::vector> shared_streams(streams.size()); for (std::size_t i = 0; i < streams.size(); ++i) shared_streams[i] = std::move(streams[i]); std::vector> result; for (std::size_t i = 0; i < streams.size(); ++i) { std::vector> others; for (std::size_t j = 0; j < streams.size(); ++j) if (i != j) others.push_back(shared_streams[i]); result.push_back(std::make_unique(shared_streams[i], std::move(others))); } return result; } }