简体   繁体   中英

What is the right way to format to a circular buffer and flush to a file

I made a file class that has its own fixed length internal buffer as a drop-in replacement for the CRT file. I want to add a format method to the file class which will use fmt to format to the internal buffer. When the buffer is full, it needs to flush it to the file and continue formatting from the beginning of the buffer. The goal is an improvement in performance by reducing allocations, copying, and branches ( push_back ) but still being just as easy to use as a call to fmt::format .

I was able to do this in a hacky way as a proof of idea by modifying the grow method and capacity value in iterator_buffer :

Modifications:

template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
 protected:
     FMT_CONSTEXPR20 void grow(size_t) override
     {
        std::cout << "FLUSH: " << std::string_view{&*this->begin(), &*this->end()} << '\n';
        buffer<T>::set(&*this->begin(), 32); buffer<T>::clear();
     }

 public:
  explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, 32) {}

  auto out() -> T* { return &*this->end(); }
};

Main code:

std::array<char, 32> buffer; // the actual buffer is much larger

auto out = fmt::format_to(buffer.data(), "example format string 0x{:016X}. {} {} {} {} ", 0x99, "this could have some", "somewhat", "very long", "data in reality");

std::cout << "CLOSE: " << std::string_view{ buffer.data(), out } << '\n';

Output:

FLUSH: example format string 0x00000000
FLUSH: 00000099. this could have some
FLUSH: somewhat very long
CLOSE: data in reality

What is the right way to do this?

You can use std::ofstream 's buffer mechanism directly, it also provide a way to let you specify the buffer you want .

void foo(){
    std::array<char, 32> buffer;
    std::ofstream file;
    file.rdbuf()->pubsetbuf(buffer.data(), buffer.size()); // set the buffer
    file.open("file.txt");
    
    std::format_to(
        std::ostreambuf_iterator(file), // use the buffer as iterator
        "example format string 0x{:016X}. {} {} {} {} ", 
        0x99, 
        "this could have some", "somewhat", 
        "very long", "data in reality"
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM