Comment #0 by andrej.mitrovich — 2014-03-23T09:05:24Z
This seems to be a common occurrence in D code:
-----
uint pop24bitsLE(R)(ref R input) if (isInputRange!R)
{
ubyte b0 = popByte(input);
ubyte b1 = popByte(input);
ubyte b2 = popByte(input);
return (b2 << 16) | (b1 << 8) | b0;
}
-----
std.bitmanip comes close with:
-----
import std.bitmanip;
uint u = range.read!(uint, Endian.littleEndian)();
-----
But this will actually read 4 bytes instead of 3. I propose we add an overload or two via:
-----
// compile-time byte-count version
T read(T, Endian endianness = Endian.bigEndian, R, size_t bytes = T.sizeof)(ref R range).
// run-time equivalent
T read(T, Endian endianness = Endian.bigEndian, R)(ref R range, size_t bytes = T.sizeof).
-----
'read' would ensure 'bytes' does not exceed T.sizeof, but it would allow the bytes to be smaller than T.sizeof. The usage would be:
-----
import std.bitmanip;
// run-time version
uint u = range.read!(uint, Endian.littleEndian)(3);
// or for the compile-time version:
alias pop24bitsLE = read!(uint, Endian.littleEndian, 3);
uint u = range.pop24bitsLE();
-----
Comment #1 by andrej.mitrovich — 2014-03-23T09:11:51Z
Sorry, the terminology is wrong. It should say "count of elements", not number of bytes. The function operates on ranges of bytes.
Comment #2 by robert.schadek — 2024-12-01T16:20:38Z