Reputation: 7242
Is there an easy way to check if something was serialized in stl::ostream. I am looking for something like:
some preparation
// ... a very complex code that may result in adding or not to the stream,
// that I will prefer not to change
check if the stream has something added
Note that this will need to works recursively. Is using register_callback is a good idea or there is easier way?
Upvotes: 1
Views: 174
Reputation: 4591
Are you passing the stream into the complex code, or is it globally visible? Can it be any kind of ostream
or can you constrain the type to ofstream
or ostringstream
?
You may be able to use tellp
to determine whether the file position has changed since your preparation code, if your ostream type supports it (such as with most fstream
s). Or, if you're passing the stream in, you could pass an empty ostringstream
in and check that it's not empty when the string is extracted to be printed out.
It's not entirely obvious which solution, if any, would be appropriate for you without knowing more about the context of your code and the specifics of your problem. The best answer may be to return (or set as a by-reference out-parameter) a flag indicating whether the stream was inserted into.
Upvotes: 0
Reputation: 153840
First the immediate question: register_callback()
is intended to deal with appropriate copying and releasing of resources stored in pword()
and will have operations only related to that (i.e., copying, assigning, and releasing plus observing std::locale
changes). So, no, that won't help you at all.
What you can do, however, is to create a filtering stream buffer which observes if there was a write to the stream, e.g., something like this:
class changedbuf: std::streambuf {
std::streambuf* d_sbuf;
bool d_changed;
int_type overflow(int_type c) {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
this->d_changed = true;
}
return this->d_sbuf->sputc(c);
}
public:
changedbuf(std::streambuf* sbuf): d_sbuf(d_sbuf), d_changed() {}
bool changed() const { return this->d_changed; }
}
You can use this in place of the std::ostream
you already have, e.g.:
void f(std::ostream& out) {
changedbuf changedbuf(out.rdbuf());
std::ostream changedout(&changedbuf);
// use changedout instead of out; if you need to use a global objects, you'd
// replace/restore the used stream buffer using the version of rdbuf() taking
// an argument
if (changedbuf.change()) {
std::cout << "there was a change\n";
}
}
A real implementation would actually provide a buffer and deal with proper flushing (i.e., override sync()
) and sequence output (i.e., override xsputn()
). However, the above version is sufficient as a proof-of-concept.
Others are likely to suggest the use of std::ostringstream
. Depending on the amount of data written, this can easily become a performance hog, especially compared to an advanced version of changedbuf
which appropriately deals with buffering.
Upvotes: 3