@shuffle

@shuffle

도입부 없음 — 바로 내장 함수 본문으로 시작해요.

출처: Zig Documentation

본문

@shuffle(comptime E: type, a: @Vector(a_len, E), b: @Vector(b_len, E), comptime mask: @Vector(mask_len, i32)) @Vector(mask_len, E)

mask를 기준으로 ab에서 원소를 골라 새 vector를 만드는 함수예요.

mask의 각 원소는 ab 중 하나에서 원소 하나를 선택해요. 양수 값은 a에서 0부터 세어 선택하고, 음수 값은 b에서 -1부터 내려가며 선택해요. b의 인덱스는 ~ 연산자를 쓰는 걸 권장해요. 그래야 두 인덱스 모두 0부터 시작할 수 있거든요. 즉 ~@as(i32, 0)이 곧 -1이 되는 셈이에요.

mask의 어떤 원소, 또는 그 원소가 a/b에서 선택한 값이 undefined라면 결과 원소도 undefined가 돼요.

a_lenb_len은 길이가 달라도 돼요. 다만 mask의 원소 인덱스가 범위를 벗어나면 컴파일 에러가 나요.

abundefined면, 그 쪽은 다른 벡터와 같은 길이의 undefined 벡터로 취급돼요. 두 벡터가 모두 undefined라면 @shuffle은 모든 원소가 undefined인 벡터를 반환해요.

E정수, 부동소수, 포인터, 또는 bool이어야 해요. mask는 아무 길이나 될 수 있고, 그 길이가 곧 결과 벡터의 길이가 돼요.

test_shuffle_builtin.zig:

const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;

test "vector @shuffle" {
    const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' };
    const b = @Vector(4, u8){ 'w', 'd', '!', 'x' };

    // To shuffle within a single vector, pass undefined as the second argument.
    // Notice that we can re-order, duplicate, or omit elements of the input vector
    const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 };
    const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1);
    try expectEqualStrings("hello", &@as([5]u8, res1));

    // Combining two vectors
    const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 };
    const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2);
    try expectEqualStrings("world!", &@as([6]u8, res2));
}

Shell:

$ zig test test_shuffle_builtin.zig
1/1 test_shuffle_builtin.test.vector @shuffle...OK
All 1 tests passed.

더 알아보기