-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
What
I am proposing to add a function swapRanges to std.mem. Here is an example implementation.
fn swapRanges(comptime T: type, left: []T, right: []T) !void {
if (left.len != right.len) {
return error{SliceLengthMismatch}.SliceLengthMismatch;
}
for (0..left.len) |i| {
const tmp = left[i];
left[i] = right[i];
right[i] = tmp;
}
}Why
Swapping the contents of two slices is a common low-level operation that should be added to the zig standard library. Implementing this in user code encourages code duplication, and is tedious. Additionally, this abstraction lends itself to future potential optimizations in implementation such as SIMD usage, parallelization, memory tricks, specializations, etc. Furthermore it is simple, small and there are no assumptions required for consuming code.
Why it fits
In zig, slices are treated as a first-class types that are passed around freely, iterated on, assigned and copied. However, there is a missing builtin low-level operation for them. A function to swap the contents of two slices would be very useful and it fits the established precedent of the standard library. There are plenty of examples of functions in the zig standard library for data swapping and general manipulation of slices. You will notice that some are fallible and equally straightforward to implement in userspace. Here are a few in std.mem:
std.mem.copyBackwards(comptime T: type, dest: []T, source: []const T) void
std.mem.swap(comptime T: type, a: *T, b: *T) void
std.mem.byteSwapAllElements(comptime Elem: type, slice: []Elem) void
std.mem.byteSwapAllFields(comptime S: type, ptr: *S) void
std.mem.eql(comptime T: type, a: []const T, b: []const T) bool
std.mem.alignInBytes(bytes: []u8, comptime new_alignment: usize) ?[]align(new_alignment) u8
std.mem.concat(allocator: Allocator, comptime T: type, slices: []const []const T) Allocator.Error![]TEdge cases
If any assurances are needed, like enforcing non-overlapping buffers, they may easily be encoded in the function signature or enforced in implementation.