If you need an iterator based solution then even in c++23 it's not getting better than that:
struct istreambuf_iterator_byte : public std::istreambuf_iterator<char> {
using base_type = std::istreambuf_iterator<char>;
static_assert(std::is_same_v<base_type::iterator_category, std::input_iterator_tag>, "Stronger iterator requires more methods to be reimplemented here.");
using value_type = std::byte;
using reference = std::byte;
std::byte operator*() const noexcept(noexcept(base_type::operator*())) {
return static_cast<std::byte>(base_type::operator*());
}
istreambuf_iterator_byte& operator++() noexcept(noexcept(base_type::operator++())) {
base_type::operator++();
return *this;
}
istreambuf_iterator_byte operator++(int) noexcept(noexcept(base_type::operator++(int{}))) {
return istreambuf_iterator_byte{base_type::operator++(int{})};
}
};
#if defined __cpp_concepts
static_assert(std::input_iterator<istreambuf_iterator_byte>);
#endif
auto read_file(const std::string& file_path) -> std::vector<std::byte> {
std::ifstream input_file(file_path, std::ios::binary);
return {istreambuf_iterator_byte{input_file}, istreambuf_iterator_byte{}};
}
At the same time, As Remy Lebeau pointed out, there is much more efficient way to read raw data using preallocation and read()
, readsome()
methods. My tests shows that it's 2 to 5 times faster this way, and practically as fast as assign()
'ing memory-mapped file for all file sizes from 5KB to 4GB.
auto read_file(const std::string& file_path) -> std::vector<std::byte> {
std::ifstream input_file(file_path, std::ios::binary);
input_file.seekg(0, std::ios::end);
auto const file_size = input_file.tellg();
input_file.seekg(0, std::ios::beg);
std::vector<std::byte> result(file_size);
input_file.read(reinterpret_cast<char*>(&result[0]), file_size);
result.resize(input_file.tellg());
return result;
}
istream_iterator
if geterror: no match for ‘operator>>’ (operand types are ‘std::istream_iterator<std::byte>::istream_type {aka std::basic_istream<char>}’ and ‘std::byte’)
– Showoperator>>
that reads astd::byte
from astd::istream
– Acetylate