I write tools to dump and load common objects in a binary file. In a first quick implementation, I wrote the following code for std::vector<bool>
. It works, but it is clearly not optimized in memory.
template <>
void binary_write(std::ofstream& fout, const std::vector<bool>& x)
{
std::size_t n = x.size();
fout.write((const char*)&n, sizeof(std::size_t));
for(std::size_t i = 0; i < n; ++i)
{
bool xati = x.at(i);
binary_write(fout, xati);
}
}
template <>
void binary_read(std::ifstream& fin, std::vector<bool>& x)
{
std::size_t n;
fin.read((char*)&n, sizeof(std::size_t));
x.resize(n);
for(std::size_t i = 0; i < n; ++i)
{
bool xati;
binary_read(fin, xati);
x.at(i) = xati;
}
}
How can I copy the internal memory of a std::vector<bool>
in my stream ?
Note : I don't want to replace std::vector<bool>
by something other.
Answering my own question, currently validated as the best answer, but it can change if someone provides somthing better.
A way to do that is the following. It requires to access each value, but it works.
template <>
void binary_write(std::ofstream& fout, const std::vector<bool>& x)
{
std::vector<bool>::size_type n = x.size();
fout.write((const char*)&n, sizeof(std::vector<bool>::size_type));
for(std::vector<bool>::size_type i = 0; i < n;)
{
unsigned char aggr = 0;
for(unsigned char mask = 1; mask > 0 && i < n; ++i, mask <<= 1)
if(x.at(i))
aggr |= mask;
fout.write((const char*)&aggr, sizeof(unsigned char));
}
}
template <>
void binary_read(std::ifstream& fin, std::vector<bool>& x)
{
std::vector<bool>::size_type n;
fin.read((char*)&n, sizeof(std::vector<bool>::size_type));
x.resize(n);
for(std::vector<bool>::size_type i = 0; i < n;)
{
unsigned char aggr;
fin.read((char*)&aggr, sizeof(unsigned char));
for(unsigned char mask = 1; mask > 0 && i < n; ++i, mask <<= 1)
x.at(i) = aggr & mask;
}
}