direct_buffered_file -> ostream

This commit is contained in:
Victor Zverovich
2020-07-11 11:06:52 -07:00
parent e1bfb59619
commit 415cd51913
3 changed files with 26 additions and 20 deletions

View File

@@ -343,8 +343,8 @@ class file {
// Returns the memory page size. // Returns the memory page size.
long getpagesize(); long getpagesize();
// A buffered file with a direct buffer access and no synchronization. // A fast output stream without synchronization.
class direct_buffered_file : private detail::buffer<char> { class ostream : private detail::buffer<char> {
private: private:
file file_; file file_;
char buffer_[BUFSIZ]; char buffer_[BUFSIZ];
@@ -357,11 +357,18 @@ class direct_buffered_file : private detail::buffer<char> {
void grow(size_t) final; void grow(size_t) final;
public: ostream(cstring_view path, int oflag)
direct_buffered_file(cstring_view path, int oflag)
: buffer<char>(buffer_, 0, BUFSIZ), file_(path, oflag) {} : buffer<char>(buffer_, 0, BUFSIZ), file_(path, oflag) {}
~direct_buffered_file() { flush(); } public:
ostream(ostream&& other)
: buffer<char>(buffer_, 0, BUFSIZ), file_(std::move(other.file_)) {
append(other.begin(), other.end());
other.clear();
}
~ostream() { flush(); }
friend ostream output_file(cstring_view path, int oflag);
void close() { void close() {
flush(); flush();
@@ -369,13 +376,14 @@ class direct_buffered_file : private detail::buffer<char> {
} }
template <typename S, typename... Args> template <typename S, typename... Args>
friend void print(direct_buffered_file& f, const S& format_str, void print(const S& format_str, const Args&... args) {
const Args&... args); format_to(detail::buffer_appender<char>(*this), format_str, args...);
}
}; };
template <typename S, typename... Args> inline ostream output_file(cstring_view path,
void print(direct_buffered_file& f, const S& format_str, const Args&... args) { int oflag = file::WRONLY | file::CREATE) {
format_to(detail::buffer_appender<char>(f), format_str, args...); return {path, oflag};
} }
#endif // FMT_USE_FCNTL #endif // FMT_USE_FCNTL

View File

@@ -314,7 +314,7 @@ long getpagesize() {
# endif # endif
} }
void direct_buffered_file::grow(size_t) { void ostream::grow(size_t) {
if (this->size() == BUFSIZ) flush(); if (this->size() == BUFSIZ) flush();
} }
#endif // FMT_USE_FCNTL #endif // FMT_USE_FCNTL

View File

@@ -287,21 +287,19 @@ TEST(BufferedFileTest, Fileno) {
EXPECT_READ(copy, FILE_CONTENT); EXPECT_READ(copy, FILE_CONTENT);
} }
TEST(DirectBufferedFileTest, Print) { TEST(OStreamTest, Print) {
fmt::direct_buffered_file out("test-file", fmt::ostream out = fmt::output_file("test-file");
fmt::file::WRONLY | fmt::file::CREATE); out.print("The answer is {}.\n", 42);
fmt::print(out, "The answer is {}.\n", 42);
out.close(); out.close();
file in("test-file", file::RDONLY); file in("test-file", file::RDONLY);
EXPECT_READ(in, "The answer is 42.\n"); EXPECT_READ(in, "The answer is 42.\n");
} }
TEST(DirectBufferedFileTest, BufferBoundary) { TEST(OStreamTest, BufferBoundary) {
auto str = std::string(4096, 'x'); auto str = std::string(4096, 'x');
fmt::direct_buffered_file out("test-file", fmt::ostream out = fmt::output_file("test-file");
fmt::file::WRONLY | fmt::file::CREATE); out.print("{}", str);
fmt::print(out, "{}", str); out.print("{}", str);
fmt::print(out, "{}", str);
out.close(); out.close();
file in("test-file", file::RDONLY); file in("test-file", file::RDONLY);
EXPECT_READ(in, str + str); EXPECT_READ(in, str + str);