c++ostream

How to get state of ostream when wrapped inside osyncstream


Is there a way to extract iostate (goodbit,badbit, failbit) or other means of error state of a std::ostream when I access this std::ostream through a std::osyncstream.

I would like to detect whether an output stream operation has succeeded or if the output stream is in an error state.

When using ostream directly I could use fail(), good() and bad() methods to determine the state of the stream. Consider a situation like this:

std::ofstream logFile("file1.txt");

std::ostream oStream(logFile.rdbuf());

{
    std::ofstream logFile2("file2.txt");
    oStream.rdbuf(logFile2.rdbuf());    
}

std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
oStream << "This is probably UB because used streambuf is gone" << std::endl;
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";

However once I wrap the ostream inside osyncstream, I do not manage to get the stream state anymore. The goodbit stays true and failbit/badbit stay false for both the ostream as well as the osyncstream object, even though I would expect otherwise.

std::ofstream logFile("file1.txt");

std::ostream oStream(logFile.rdbuf());

{
    std::ofstream logFile2("file2.txt");
    oStream.rdbuf(logFile2.rdbuf());    
}

std::osyncstream osyncStream(oStream);

std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
std::cout << "osyncStream.fail(): " << oStream.fail() << "\n";
std::cout << "osyncStream.good(): " << oStream.good() << "\n";
std::cout << "osyncStream.bad(): " << oStream.bad() << "\n";
osyncStream << "This is probably UB because used streambuf is gone" << std::endl;
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
std::cout << "osyncStream.fail(): " << oStream.fail() << "\n";
std::cout << "osyncStream.good(): " << oStream.good() << "\n";
std::cout << "osyncStream.bad(): " << oStream.bad() << "\n";

Or maybe my whole approach to checking for error state of ostreams is not correct. What I want to achieve in the end is to detect if a caller provides an ostream to my class which goes out of scope while my class is still using it. As of today my class is either holding a std::reference_wrapper to the external ostream or using the underlying streambuf as described in this anwser.


Solution

  • There is no standardized way to extract or observe the error state from a std::osyncstream, because it's designed in such a way so that it buffers output for synchronized, thread-safe writes, while not exposing the underlying stream's state in the same way that a raw std::ostream does.