Bug 12489 – std.bitmanip byte swapping routines should be partially instantiable

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-03-29T04:15:00Z
Last change time
2014-03-30T05:45:56Z
Assigned to
nobody
Creator
andrej.mitrovich

Comments

Comment #0 by andrej.mitrovich — 2014-03-29T04:15:14Z
I've had a use case for generic endianness swapping when reading file headers, and was going to use attributes. For example: struct Header { @Converter!(littleEndianToNative!ushort) ushort reserved1; } Unfortunately this doesn't work because you can't partially instantiate littleEndianToNative: Error: template instance littleEndianToNative!ushort does not match template declaration littleEndianToNative(T, uint n)(ubyte[n] val) if (canSwapEndianness!T && n == T.sizeof) It would have to be converted to a template, e.g.: Before: ----- T littleEndianToNative(T, size_t n)(ubyte[n] val) @safe pure nothrow ----- After: ----- template littleEndianToNative(T) { T littleEndianToNative(size_t n)(ubyte[n] val) @safe pure nothrow { ... } } -----
Comment #1 by andrej.mitrovich — 2014-03-29T04:32:30Z
Here's a somewhat generic wrapper workaround: ----- template PartialTempl(alias templ, T...) { auto PartialTempl(Args...)(auto ref Args args) { return templ!T(args); } } ----- Usable as: ----- @Converter!(PartialTempl!(littleEndianToNative, ushort)) ushort reserved1; ----- Of course 'littleEndianToNative' and friends take a ubyte[N], not a ushort, so in my file loading routine I have to take that into account. But using attributes is pretty nice.
Comment #2 by andrej.mitrovich — 2014-03-29T13:01:05Z
(In reply to comment #1) > Here's a somewhat generic wrapper workaround: > > ----- > template PartialTempl(alias templ, T...) > { > auto PartialTempl(Args...)(auto ref Args args) > { > return templ!T(args); > } > } > ----- This solves it for me.
Comment #3 by dlang-bugzilla — 2014-03-30T04:37:22Z
(In reply to comment #0) > @Converter!(littleEndianToNative!ushort) > ushort reserved1; I don't know the context, but there's some redundancy here already (ushort is listed twice). Any reason you can't use `@Converter!littleEndianToNative` ?
Comment #4 by andrej.mitrovich — 2014-03-30T05:45:56Z
(In reply to comment #3) > (In reply to comment #0) > > @Converter!(littleEndianToNative!ushort) > > ushort reserved1; > > I don't know the context, but there's some redundancy here already (ushort is > listed twice). Any reason you can't use `@Converter!littleEndianToNative` ? Yeah you're right, I don't need to embed this information. It's really nice that I can now write: struct Header { @Converter!littleEndianToNative { ushort reserved1; ushort ordnum; ushort insnum; ushort patnum; ushort flags; ushort cwtv; ushort version_; } }