| ... | ... | @@ -3633,10 +3633,34 @@ test indexOfMinMax { |
| 3633 | 3633 | } |
| 3634 | 3634 | |
| 3635 | 3635 | /// Exchanges contents of two memory locations. |
| 3636 | | pub fn swap(comptime T: type, a: *T, b: *T) void { |
| 3637 | | const tmp = a.*; |
| 3638 | | a.* = b.*; |
| 3639 | | b.* = tmp; |
| 3636 | pub fn swap(comptime T: type, noalias a: *T, noalias b: *T) void { |
| 3637 | if (@inComptime()) { |
| 3638 | // In comptime, accessing bytes of values with no defined layout is a compile error. |
| 3639 | const tmp = a.*; |
| 3640 | a.* = b.*; |
| 3641 | b.* = tmp; |
| 3642 | } else { |
| 3643 | // Swapping in streaming nature from start to end instead of swapping |
| 3644 | // everything in one step allows easier optimizations and less stack usage. |
| 3645 | const a_bytes: []align(@alignOf(T)) u8 = @ptrCast(a); |
| 3646 | const b_bytes: []align(@alignOf(T)) u8 = @ptrCast(b); |
| 3647 | for (a_bytes, b_bytes) |*ab, *bb| { |
| 3648 | const tmp = ab.*; |
| 3649 | ab.* = bb.*; |
| 3650 | bb.* = tmp; |
| 3651 | } |
| 3652 | } |
| 3653 | } |
| 3654 | |
| 3655 | test "swap works at comptime with types with no defined layout" { |
| 3656 | comptime { |
| 3657 | const T = struct { val: u64 }; |
| 3658 | var a: T = .{ .val = 0 }; |
| 3659 | var b: T = .{ .val = 1 }; |
| 3660 | swap(T, &a, &b); |
| 3661 | try testing.expectEqual(T{ .val = 1 }, a); |
| 3662 | try testing.expectEqual(T{ .val = 0 }, b); |
| 3663 | } |
| 3640 | 3664 | } |
| 3641 | 3665 | |
| 3642 | 3666 | inline fn reverseVector(comptime N: usize, comptime T: type, a: []T) [N]T { |