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_;
}
}