Last active
January 3, 2016 10:09
-
-
Save dgodfrey206/8447788 to your computer and use it in GitHub Desktop.
Opting in or out of the flushing mechanism of std::endl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
static int disable() { | |
static int index(std::ios_base::xalloc()); | |
return index; | |
} | |
class save_buffer | |
{ | |
public: | |
save_buffer(std::ios& other) | |
: str(other), buf(other.rdbuf()) | |
{ } | |
~save_buffer() { str.rdbuf(buf); } | |
private: | |
std::ios& str; | |
std::streambuf* buf; | |
}; | |
class syncing_buffer_optional : public std::streambuf, public save_buffer | |
{ | |
public: | |
syncing_buffer_optional(std::ostream& other) | |
: save_buffer(other), | |
buf(other.rdbuf()), | |
disable_sync(other.iword(disable())) | |
{ } | |
std::streambuf::int_type overflow(std::streambuf::int_type c) | |
{ | |
buf->sputc(c); | |
return 0; | |
} | |
int sync() | |
{ | |
return disable_sync? 0: buf->pubsync(); | |
} | |
private: | |
std::streambuf* buf; | |
bool disable_sync; | |
}; | |
std::ostream& flush_on_endl(std::ostream& os) | |
{ | |
os.iword(disable()) = false; | |
return os; | |
} | |
std::ostream& noflush_on_endl(std::ostream& os) | |
{ | |
os.iword(disable()) = true; | |
return os; | |
} | |
std::ostream& endl(std::ostream& os) | |
{ | |
syncing_buffer_optional eb(os); | |
os.rdbuf(&eb); | |
return os << std::endl; | |
} | |
int main() | |
{ | |
std::cout << noflush_on_endl << endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: I needed to create an endl function because of the lifetime dependencies between the buffer and the stream. Moreover, even if the buffer was static, how can we distinguish between an std::endl call and an arbitrary flush()?