Thread overview
question about using std.bitmanip.read
Nov 07, 2015
Charles
Nov 07, 2015
BBaz
Nov 07, 2015
Nicholas Wilson
Nov 07, 2015
Charles
Nov 07, 2015
Mike Parker
Nov 07, 2015
Mike Parker
Nov 07, 2015
Charles
November 07, 2015
Hi guys,

It's me again... still having some issues pop up getting started, but I remain hopeful I'll stop needing to ask so many questions soon.

I'm trying to use std.bitmanip.read; however, am having some issues using it. For basic testing I'm just trying to use:

    read!double(endianess, ubyteArr).writeln;

endianess is an Endian from std.system, and ubyteArr is an 8 byte ubyte[].

When I run this I get:

Error: template std.bitmanip.read cannot deduce function from argument types !(double)(Endian, ubyte[]), candidates are:
    std.bitmanip.read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte)))
dmd failed with exit code 1.


Clearly that didn't work, so I tried excluding the endianess:

    read!double(ubyteArr).writeln;

and that does work! But its the wrong byte order, so its incorrect anyways.

I went to std.bitmanip to look for unittests using the Endian, and the only one that does uses read!(T, endianness), which needs endianness to be known at compile time, which I don't have.

Any suggestions?
November 07, 2015
On Saturday, 7 November 2015 at 03:19:44 UTC, Charles wrote:
> Hi guys,
>
> It's me again... still having some issues pop up getting started, but I remain hopeful I'll stop needing to ask so many questions soon.
>
> I'm trying to use std.bitmanip.read; however, am having some issues using it. For basic testing I'm just trying to use:
>
>     read!double(endianess, ubyteArr).writeln;
>
> endianess is an Endian from std.system, and ubyteArr is an 8 byte ubyte[].
>
> When I run this I get:
>
> Error: template std.bitmanip.read cannot deduce function from argument types !(double)(Endian, ubyte[]), candidates are:
>     std.bitmanip.read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte)))
> dmd failed with exit code 1.
>
>
> Clearly that didn't work, so I tried excluding the endianess:
>
>     read!double(ubyteArr).writeln;
>
> and that does work! But its the wrong byte order, so its incorrect anyways.
>
> I went to std.bitmanip to look for unittests using the Endian, and the only one that does uses read!(T, endianness), which needs endianness to be known at compile time, which I don't have.
>
> Any suggestions?

You must create a classic run-time branch:

---
if(endianess == Endian.bigEndian)
   read!(Endian.bigEndian, double)(ubyteArr).writeln;
else
   read!(Endian.littleEndian, double)(ubyteArr).writeln;
---

or in the same fashion use a final switch.
November 07, 2015
On Saturday, 7 November 2015 at 03:19:44 UTC, Charles wrote:
> Hi guys,
>
> It's me again... still having some issues pop up getting started, but I remain hopeful I'll stop needing to ask so many questions soon.
>
> I'm trying to use std.bitmanip.read; however, am having some issues using it. For basic testing I'm just trying to use:
>
>     read!double(endianess, ubyteArr).writeln;
>
> endianess is an Endian from std.system, and ubyteArr is an 8 byte ubyte[].
>
> When I run this I get:
>
> Error: template std.bitmanip.read cannot deduce function from argument types !(double)(Endian, ubyte[]), candidates are:
>     std.bitmanip.read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte)))
> dmd failed with exit code 1.
>
>
> Clearly that didn't work, so I tried excluding the endianess:
>
>     read!double(ubyteArr).writeln;
>
> and that does work! But its the wrong byte order, so its incorrect anyways.
>
> I went to std.bitmanip to look for unittests using the Endian, and the only one that does uses read!(T, endianness), which needs endianness to be known at compile time, which I don't have.
>
> Any suggestions?

Cheat!

T read(T,R)(Endian endianness , R r)
{
         if(endianness == Endian.bigEndian)
                return std.bitmanip.read!(T,Endian.bigEndian,R)(r);
         else if (endianness == Endian.littleEndian)
                return std.bitmanip.read!(T,Endian.littleEndian,R)(r);
}

but...
you are on a little endian system (bigEndian gave wrong byte order )
you don't need to use bitmanip.read type repainting will work.
ubyte[] r = [ /* ... */ ];
double d = *cast(double*)r.ptr;

November 07, 2015
On Saturday, 7 November 2015 at 03:53:14 UTC, Nicholas Wilson wrote:
> On Saturday, 7 November 2015 at 03:19:44 UTC, Charles wrote:
>> Hi guys,
>>
>> It's me again... still having some issues pop up getting started, but I remain hopeful I'll stop needing to ask so many questions soon.
>>
>> I'm trying to use std.bitmanip.read; however, am having some issues using it. For basic testing I'm just trying to use:
>>
>>     read!double(endianess, ubyteArr).writeln;
>>
>> endianess is an Endian from std.system, and ubyteArr is an 8 byte ubyte[].
>>
>> When I run this I get:
>>
>> Error: template std.bitmanip.read cannot deduce function from argument types !(double)(Endian, ubyte[]), candidates are:
>>     std.bitmanip.read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte)))
>> dmd failed with exit code 1.
>>
>>
>> Clearly that didn't work, so I tried excluding the endianess:
>>
>>     read!double(ubyteArr).writeln;
>>
>> and that does work! But its the wrong byte order, so its incorrect anyways.
>>
>> I went to std.bitmanip to look for unittests using the Endian, and the only one that does uses read!(T, endianness), which needs endianness to be known at compile time, which I don't have.
>>
>> Any suggestions?
>
> Cheat!
>
> T read(T,R)(Endian endianness , R r)
> {
>          if(endianness == Endian.bigEndian)
>                 return std.bitmanip.read!(T,Endian.bigEndian,R)(r);
>          else if (endianness == Endian.littleEndian)
>                 return std.bitmanip.read!(T,Endian.littleEndian,R)(r);
> }

Thanks!

> but...
> you are on a little endian system (bigEndian gave wrong byte order )

The actual use case is reading a binary file of unknown endianness. I don't think I'm that fortunate sadly.
November 07, 2015
On Saturday, 7 November 2015 at 03:19:44 UTC, Charles wrote:
> Hi guys,
>
> It's me again... still having some issues pop up getting started, but I remain hopeful I'll stop needing to ask so many questions soon.
>
> I'm trying to use std.bitmanip.read; however, am having some issues using it. For basic testing I'm just trying to use:
>
>     read!double(endianess, ubyteArr).writeln;
>
> endianess is an Endian from std.system, and ubyteArr is an 8 byte ubyte[].
>
> When I run this I get:
>
> Error: template std.bitmanip.read cannot deduce function from argument types !(double)(Endian, ubyte[]), candidates are:
>     std.bitmanip.read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte)))
> dmd failed with exit code 1.
>

You're passing endianess as a function argument, but the signatures in the error says it's supposed to be a template argument. Did you try this?

read!(double, endianess)(ubyteArr);

November 07, 2015
On Saturday, 7 November 2015 at 03:19:44 UTC, Charles wrote:

>
> I went to std.bitmanip to look for unittests using the Endian, and the only one that does uses read!(T, endianness), which needs endianness to be known at compile time, which I don't have.

Missed this in my previous reply.

November 07, 2015
On Saturday, 7 November 2015 at 04:25:00 UTC, Mike Parker wrote:
> Missed this in my previous reply.

No problem. I appreciate you taking the time to help me either way :)