Passing a ubyte[] to a function taking a 'ref ubyte[16]'
Jonathan M Davis
jmdavisProg at gmx.com
Sat Jun 23 16:51:14 PDT 2012
On Saturday, June 23, 2012 20:23:26 Johannes Pfau wrote:
> I'm working on the new design for std.hash and I hit an interesting
> problem:
>
> The OOP interface has to take buffers as slices with unknown length, as
> the length differs between hashes and I have to put a common function
> declaration in a interface. So I have this:
> ------------
> interface Digest
> {
> ubyte[] finish(ubyte[] buf);
> }
> ------------
I confess that I'm baffled as to why you'd even be using interfaces for this,
given that Phobos always uses structs and templates for this sort of thing.
> Now the template API can and should use the correct type, so there
> finish is defined like this:
> ------------
> struct MD5
> {
> void finish(ref ubyte[16] data);
> }
> ------------
>
> And the interface implementation for MD5 has to call the MD5 structs
> finish function:
> ------------
> class MD5Digest : Digest
> {
> private MD5 _digest;
>
> ubyte[] finish(ubyte[] buf)
> {
> enforce(buf.length >= 16);
> _digest.finish(buf); //How to do this?
> }
> }
> ------------
>
> So how to pass a ubyte[] to a function expecting a ref ubyte[16]
> without allocating/using any extra memory (Not even stack)?
>
> This seems to work, but it's very ugly:
> ------------
> _digest.finish(*cast(ubyte[16]*)buf.ptr);
> ------------
>
> I thought this might create a temporary, but it passes all unittests,
> so it seems to work?
I believe that that will work, but it's definitely ugly. However, if you do
that, you _need_ to put an assertion about the length of buf in there,
otherwise, you could be using memory from past the end of buf.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list