Fixes #35683
Random.array: use sliceAsBytes #35687
Der_Teufel/zig:fix-random-array into master
I believe this could cause weird behaviour if E is not an integer type.
For example, if E is enum (u2) { A, B, C } then it'd be possible to get an integer value of 3 which isn't mapped to an actual value.
Random.array could just be restricted to integer types, but it'd also be nice to have it be able to generate arrays of enums, though in that case it'd likely have to do
for(result)|*e|{e.*=r.enumValue(E);}for all enums which don't have a value associated with every single integer representation, which could be rather slow.
Random.arraycould just be restricted to integer types
this is the right way
generate arrays of enums
this should be implemented in the userspace
there can be one branch that checks std.meta.hasUniqueRepresentation(E) and uses the code as is in the current PR
the else branch can use a loop
@nektro wrote in #35687 (comment):
there can be one branch that checks
std.meta.hasUniqueRepresentation(E)and uses the code as is in the current PR the else branch can use a loop
This sounds like a good solution, I'll have to find all the possible types for the else branch
i meant a literal else branch similar to this
pubfnarray(r:Random,comptimeE:type,comptimeN:usize)[N]E{varresult:[N]E=undefined;if(std.meta.hasUniqueRepresentation(E)){bytes(r,std.mem.sliceAsBytes(&result));}else{for(&result)|*item|item.*=@bitCast(int(r,@Int(.unsigned,@bitSizeOf(E))));}returnresult;}
That wouldn't solve the issue of invalid enum values for exhaustive enums
although in hindsight that also wouldnt be perfect because enum { a, b, c, d, e } would be backed by u3 but have many invalid values like Rue pointed out so you may need to check typeInfo and use .enumValue(E) for example, but the use of the if statement stands
I was thinking something more like
pubfnarray(r:Random,comptimeE:type,comptimeN:usize)[N]E{varresult:[N]E=undefined;if(std.meta.hasUniqueRepresentation(E)){bytes(r,std.mem.sliceAsBytes(&result));}else{for(&result)|*val|{val.*=switch(@typeInfo(E)){.@"enum"=>r.enumValue(E),.int=>r.int(E),.float=>r.float(E),else=>@compileError("Type"++@typeName(E)++" not supported"),};}}returnresult;}
I believe that in a case like that it'd make more sense to have to switch based on E outside and then hasUniqueRepresentation check inside, because with the code you have there, if E == f32 it'd fill the array with values between 0.0 and 1.0, but if hasUniqueRepresentation gets changed so it returns true for f32, that'd also change the behaviour of array(f32, ...). I doubt the person changing hasUniqueRepresentation would notice that change in behaviour, and we'd probably end up with some confused users of array(f32, ...).
Unit test coverage please, doesn't have to be fancy.
@ -76,3 +76,3 @@
pubfnarray(r:Random,comptimeE:type,comptimeN:usize)[N]E{
varresult:[N]E=undefined;
bytes(r,&result);
bytes(r,std.mem.sliceAsBytes(&result));
- bytes(r, std.mem.sliceAsBytes(&result));
+ bytes(r, @ptrCast(&result));
8b0e88be64
e98fd1bc06
Just noticed that you did include test, you should add type that evaluate std.meta.hasUniqueRepresentation(E) to false.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?