Simple way to handle rvalues and templates.
Ali Çehreli
acehreli at yahoo.com
Sun Feb 27 06:11:28 UTC 2022
On 2/26/22 19:38, Chris Piker wrote:
> But this doesn't work:
> ```d
> import std.bitmanip, std.system;
> ubyte[8192] data;
>
> ushort us = data[4..6].read!(ushort, Endian.bigEndian);
> ```
> The reasons for this are probably old hat for seasoned D programmers by
> this is really confusing for newbies.
Agreed. read() is designed to advance the buffer that it is given. It is
thought to be convenient for the next read() operation because the
semantics would be "read a ushort and then read an int", etc. And the
buffer would be consumed by read().
To play the way read() wants us to play, the first thing that comes to
mind is to read original data into a storage and define a range (data
below) for read() to consume.
However, it requires skipping over bytes by e.g. dropExactly(), which is
presumably a very fast operation for slices:
void main() {
import std.bitmanip, std.system;
ubyte[8192] storage;
auto data = storage[];
import std.range;
data.dropExactly(4);
ushort us = data.read!(ushort, Endian.bigEndian);
// Here, data is ready for the next read.
}
Another option is to write a wrapper which takes your slice by copy so
that read() is happy as it consumes a parameter instead of your rvalue:
import std.system;
// Adapting read()'s interface with one difference: 'ref' is removed:
auto readFrom(T, Endian endianness = Endian.bigEndian, R)(R range) {
import std.bitmanip;
return range.read!(ushort, endianness);
}
void main() {
import std.bitmanip, std.system;
ubyte[8192] data;
ushort us = data[4..6].readFrom!(ushort, Endian.bigEndian);
}
I don't like the name readFrom() yet but that works. :)
Ali
More information about the Digitalmars-d-learn
mailing list