Don't reassign the output streambuf. Use transform, or a loop on the
streambuf iterators.
struct convert
{
uint16_t operator()(const uint16 c) const
{
return (c >> shift) & pmask);
}
convert(uint16_t& pmask_) : pmask(pmask_) { }
private:
static const shift = (16 - 12 - 1);
uint16_t pmask;
};
void DoAction(std::istream& is, std:
stream& os)
{
std::transform(std::istreambuf_iterator<uint16_t>(is),
std::istreambuf_iterator<uint16_t>(),
std:
streambuf_iterator<uint16_t>(os));
And since when can you initialize an
[io]streambuf_iterator<uint16_t> with an [io]stream? [io]stream
which means that it can said:
}
void DoAction(std::istream& is, std:
stream& os)
{
std::istreambuf_iterator<uint16_t> in(is);
const istream_iterator<uint16_t> end;
std:
streambuf_iterator<uint16_t> out(os);
while (in != end)
*out++ = ((*in++) >> (16 - 12 - 1)) & pmask;
}
Same problem.
From what little he's posted, he's copying data from an input
stream to an output stream. Both of which are presumably
different (e.g. different files). Which means that a copy will
be necessary. Until he explains what he's really trying to do
(what is the input data, what does he want in output, etc.),
it's hard to say more. He said something about an "extra copy"
in his original posting, but frankly, I don't see one in the
code he posted.
(If he's reading binary data, something like:
uint16_t c = is.get() << 8 ;
c |= is.get() ;
c = (c >> 3) & pmask ;
os.put( c >> 8 ) ;
os.put( c ) ;
in the loop might be faster; a good compiler should be able to
optimize this so that c is always in a register. In practice, I
doubt that the difference will be measurable, however, but this
does have the added advantage of actually having portably
defined semantics, which his original code didn't.)
James Kanze (GABI Software) mailto:
[email protected]
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34