Skip to content

Proposal: Add a swapRanges function to std #26060

@largenumberhere

Description

@largenumberhere

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![]T

Edge cases

If any assurances are needed, like enforcing non-overlapping buffers, they may easily be encoded in the function signature or enforced in implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions