Re: help cast

2018-03-19 Thread John Colvin via Digitalmars-d
On Monday, 19 March 2018 at 11:20:05 UTC, Steven Schveighoffer 
wrote:

Let me adjust your example a bit, and see if you still agree:

auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 
123_456_789];


writeln(bytes); // [148, 33, 64, 78, 21]

I have used cast(ubyte[]) to get ubytes as well, but I normally 
would do this for values that actually *could be* ubytes. for 
values higher than ubytes, I would not have expected implicit 
truncation. It's especially confusing to someone who has seen 
when you cast an int[] to a ubyte[], and gets the bytes for 
that same data. When I use cast(ubyte[]), I took it to mean 
"pretend this is a ubyte[] literal", not "cast each element to 
ubyte".


I can also see this biting someone who has a long set of 
ubytes, and accidentally does one that is larger than 255.


-Steve


Raw `cast` is just nasty. It's overloaded and confusing. Wrapper 
template functions like `reinterpretBitsAs` can help alleviate 
the pain, e.g. `assert([1, 2, 
3].reinterpretBitsAs!(ubyte[]).length == 12);`.


I feel like C++ got it right (or just less wrong) with casts.


Re: help cast

2018-03-19 Thread bauss via Digitalmars-d
On Monday, 19 March 2018 at 11:20:05 UTC, Steven Schveighoffer 
wrote:

On 3/18/18 4:07 PM, Jonathan M Davis wrote:

That's exactly what it's doing, and when you have multiple 
elements in the
literal, it quickly gets a lot more pleasant than casting each 
element

individually. e.g.

cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

vs

[cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, 
cast(ubyte)4,
  cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, 
cast(ubyte)9,

  cast(ubyte)10]

I use this trick all the time when creating arrays of integral 
types smaller
than int, precisely because casting each element is a royal 
pain and way

harder to read.


Let me adjust your example a bit, and see if you still agree:

auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 
123_456_789];


writeln(bytes); // [148, 33, 64, 78, 21]

I have used cast(ubyte[]) to get ubytes as well, but I normally 
would do this for values that actually *could be* ubytes. for 
values higher than ubytes, I would not have expected implicit 
truncation. It's especially confusing to someone who has seen 
when you cast an int[] to a ubyte[], and gets the bytes for 
that same data. When I use cast(ubyte[]), I took it to mean 
"pretend this is a ubyte[] literal", not "cast each element to 
ubyte".


I can also see this biting someone who has a long set of 
ubytes, and accidentally does one that is larger than 255.


-Steve


An even funnier example.

auto bytes = cast(ubyte[])cast(int[])[55_444, 289, 1_000_000, 
846, 123_456_789];
auto bytes2 = cast(int[])[55_444, 289, 1_000_000, 846, 
123_456_789];

auto bytes3 = cast(ubyte[])bytes2;

writeln(bytes); // Guess what the output is here.
writeln(bytes2); // Prints:[55444, 289, 100, 846, 
123456789]
writeln(bytes3); // Prints: [148, 216, 0, 0, 33, 1, 0, 0, 64, 
66, 15, 0, 78, 3, 0, 0, 21, 205, 91, 7]


Re: help cast

2018-03-19 Thread Steven Schveighoffer via Digitalmars-d

On 3/18/18 4:07 PM, Jonathan M Davis wrote:


That's exactly what it's doing, and when you have multiple elements in the
literal, it quickly gets a lot more pleasant than casting each element
individually. e.g.

cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

vs

[cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, cast(ubyte)4,
  cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, cast(ubyte)9,
  cast(ubyte)10]

I use this trick all the time when creating arrays of integral types smaller
than int, precisely because casting each element is a royal pain and way
harder to read.


Let me adjust your example a bit, and see if you still agree:

auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 123_456_789];

writeln(bytes); // [148, 33, 64, 78, 21]

I have used cast(ubyte[]) to get ubytes as well, but I normally would do 
this for values that actually *could be* ubytes. for values higher than 
ubytes, I would not have expected implicit truncation. It's especially 
confusing to someone who has seen when you cast an int[] to a ubyte[], 
and gets the bytes for that same data. When I use cast(ubyte[]), I took 
it to mean "pretend this is a ubyte[] literal", not "cast each element 
to ubyte".


I can also see this biting someone who has a long set of ubytes, and 
accidentally does one that is larger than 255.


-Steve


Re: help cast

2018-03-18 Thread sdvcn via Digitalmars-d

On Sunday, 18 March 2018 at 20:07:28 UTC, Jonathan M Davis wrote:
On Sunday, March 18, 2018 14:56:04 Steven Schveighoffer via 
Digitalmars-d wrote:

On 3/18/18 2:24 PM, Jonathan M Davis wrote:
> On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via 
> Digitalmars-d

>
> wrote:
>> On 3/18/18 4:34 AM, sdvcn wrote:
>>> dchar v11=dchar.max;
>>>
>>>   auto vp11 = [v11];
>>>
>>>   auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
>>>   auto v22 = cast(ubyte[])( [v11]); //v2.length=1
>>
>> This seems like a bug to me.
>>
>> It appears that v22 has truncated v11 to a byte and made 
>> only a single byte array out of it.

>
> Except that that's precisely how you usually get an array 
> any integral type smaller than an integer. e.g.

>
> auto arr = cast(ubyte[])([1, 2, 3, 4]);
>
> In this case, you could do
>
> ubyte[] arr = [1, 2, 3, 4];
>
> instead, but if you're not dealing with an initializaton or 
> assignment like this (e.g. you're passing the array to a 
> functon), then the cast is the way you do it. Normally, you 
> do it with integer literals, and I could see an argument 
> that it shouldn't allow it without VRP being used to make it 
> work, but it _is_ a cast, and casts are a bit of a blunt 
> instrument.

>
> So, I really don't think that it's a bug.

It's quite possible that you aren't understanding what is 
happening:


ubyte[] arr = cast(ubyte[])[555];
writeln(arr); // [43]

Why is this not a bug? I didn't cast the 555 to a ubyte, so it 
should either complain that it can't do it, or give me an 
array of 4 bytes.


I guess it could be explained as the same thing as:

ubyte[] arr = [cast(ubyte)555];

But this is surprisingly weird behavior.


That's exactly what it's doing, and when you have multiple 
elements in the literal, it quickly gets a lot more pleasant 
than casting each element individually. e.g.


cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

vs

[cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, 
cast(ubyte)4,
 cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, 
cast(ubyte)9,

 cast(ubyte)10]

I use this trick all the time when creating arrays of integral 
types smaller than int, precisely because casting each element 
is a royal pain and way harder to read.


- Jonathan M Davis




代码目的是转换任意类行到ubyte[]
The object of the code is to convert any class of rows to ubyte[]

但是非数组类无法正确转化
But non - array classes can't be converted correctly



void pByte(T)(T v)
{
ubyte[] uBuf;
static if(isArray!T){
uBuf = cast(ubyte[])mKey;
}else{
uBuf = cast(ubyte[])[v];
}
writeln(uBuf);
}

无法得到正确结果
Unable to get the correct result





Re: help cast

2018-03-18 Thread Jonathan M Davis via Digitalmars-d
On Sunday, March 18, 2018 14:56:04 Steven Schveighoffer via Digitalmars-d 
wrote:
> On 3/18/18 2:24 PM, Jonathan M Davis wrote:
> > On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via
> > Digitalmars-d
> >
> > wrote:
> >> On 3/18/18 4:34 AM, sdvcn wrote:
> >>> dchar v11=dchar.max;
> >>>
> >>>   auto vp11 = [v11];
> >>>
> >>>   auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
> >>>   auto v22 = cast(ubyte[])( [v11]); //v2.length=1
> >>
> >> This seems like a bug to me.
> >>
> >> It appears that v22 has truncated v11 to a byte and made only a single
> >> byte array out of it.
> >
> > Except that that's precisely how you usually get an array any integral
> > type smaller than an integer. e.g.
> >
> > auto arr = cast(ubyte[])([1, 2, 3, 4]);
> >
> > In this case, you could do
> >
> > ubyte[] arr = [1, 2, 3, 4];
> >
> > instead, but if you're not dealing with an initializaton or assignment
> > like this (e.g. you're passing the array to a functon), then the cast
> > is the way you do it. Normally, you do it with integer literals, and I
> > could see an argument that it shouldn't allow it without VRP being used
> > to make it work, but it _is_ a cast, and casts are a bit of a blunt
> > instrument.
> >
> > So, I really don't think that it's a bug.
>
> It's quite possible that you aren't understanding what is happening:
>
> ubyte[] arr = cast(ubyte[])[555];
> writeln(arr); // [43]
>
> Why is this not a bug? I didn't cast the 555 to a ubyte, so it should
> either complain that it can't do it, or give me an array of 4 bytes.
>
> I guess it could be explained as the same thing as:
>
> ubyte[] arr = [cast(ubyte)555];
>
> But this is surprisingly weird behavior.

That's exactly what it's doing, and when you have multiple elements in the
literal, it quickly gets a lot more pleasant than casting each element
individually. e.g.

cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

vs

[cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, cast(ubyte)4,
 cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, cast(ubyte)9,
 cast(ubyte)10]

I use this trick all the time when creating arrays of integral types smaller
than int, precisely because casting each element is a royal pain and way
harder to read.

- Jonathan M Davis



Re: help cast

2018-03-18 Thread Steven Schveighoffer via Digitalmars-d

On 3/18/18 2:24 PM, Jonathan M Davis wrote:

On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via Digitalmars-d
wrote:

On 3/18/18 4:34 AM, sdvcn wrote:

dchar v11=dchar.max;

  auto vp11 = [v11];

  auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
  auto v22 = cast(ubyte[])( [v11]); //v2.length=1


This seems like a bug to me.

It appears that v22 has truncated v11 to a byte and made only a single
byte array out of it.


Except that that's precisely how you usually get an array any integral type
smaller than an integer. e.g.

auto arr = cast(ubyte[])([1, 2, 3, 4]);

In this case, you could do

ubyte[] arr = [1, 2, 3, 4];

instead, but if you're not dealing with an initializaton or assignment like
this (e.g. you're passing the array to a functon), then the cast is the way
you do it. Normally, you do it with integer literals, and I could see an
argument that it shouldn't allow it without VRP being used to make it work,
but it _is_ a cast, and casts are a bit of a blunt instrument.

So, I really don't think that it's a bug.



It's quite possible that you aren't understanding what is happening:

ubyte[] arr = cast(ubyte[])[555];
writeln(arr); // [43]

Why is this not a bug? I didn't cast the 555 to a ubyte, so it should 
either complain that it can't do it, or give me an array of 4 bytes.


I guess it could be explained as the same thing as:

ubyte[] arr = [cast(ubyte)555];

But this is surprisingly weird behavior.

-Steve


Re: help cast

2018-03-18 Thread Jonathan M Davis via Digitalmars-d
On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via Digitalmars-d 
wrote:
> On 3/18/18 4:34 AM, sdvcn wrote:
> > dchar v11=dchar.max;
> >
> >  auto vp11 = [v11];
> >
> >  auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
> >  auto v22 = cast(ubyte[])( [v11]); //v2.length=1
>
> This seems like a bug to me.
>
> It appears that v22 has truncated v11 to a byte and made only a single
> byte array out of it.

Except that that's precisely how you usually get an array any integral type
smaller than an integer. e.g.

auto arr = cast(ubyte[])([1, 2, 3, 4]);

In this case, you could do

ubyte[] arr = [1, 2, 3, 4];

instead, but if you're not dealing with an initializaton or assignment like
this (e.g. you're passing the array to a functon), then the cast is the way
you do it. Normally, you do it with integer literals, and I could see an
argument that it shouldn't allow it without VRP being used to make it work,
but it _is_ a cast, and casts are a bit of a blunt instrument.

So, I really don't think that it's a bug.

- Jonathan M Davis



Re: help cast

2018-03-18 Thread Steven Schveighoffer via Digitalmars-d

On 3/18/18 4:34 AM, sdvcn wrote:

dchar v11=dchar.max;
 auto vp11 = [v11];

 auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
 auto v22 = cast(ubyte[])( [v11]); //v2.length=1



This seems like a bug to me.

It appears that v22 has truncated v11 to a byte and made only a single 
byte array out of it.


-Steve