60 lines
1.5 KiB
C++
60 lines
1.5 KiB
C++
#include <psemek/io/synchronized.hpp>
|
|
|
|
namespace psemek::io
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct synchronized_stream_impl
|
|
: ostream
|
|
{
|
|
synchronized_stream_impl(std::shared_ptr<ostream> stream, std::vector<std::weak_ptr<ostream>> 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<ostream> stream_;
|
|
std::vector<std::weak_ptr<ostream>> 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<std::unique_ptr<ostream>> synchronized(std::vector<std::unique_ptr<ostream>> streams)
|
|
{
|
|
std::vector<std::shared_ptr<ostream>> shared_streams(streams.size());
|
|
for (std::size_t i = 0; i < streams.size(); ++i)
|
|
shared_streams[i] = std::move(streams[i]);
|
|
|
|
std::vector<std::unique_ptr<ostream>> result;
|
|
for (std::size_t i = 0; i < streams.size(); ++i)
|
|
{
|
|
std::vector<std::weak_ptr<ostream>> 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<synchronized_stream_impl>(shared_streams[i], std::move(others)));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|