about summary refs log tree commit diff
path: root/lang/zig/for.zig
blob: e816fcc93e2c5248e9618e0ae6e7b5ede01bb899 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const expect = @import("std").testing.expect;

test "for basics" {
    const items = [_]i32{ 4, 5, 3, 4, 0 };
    var sum: i32 = 0;

    // For loops iterate over slices and arrays.
    for (items) |value| {
        // Break and continue are supported.
        if (value == 0)
            continue;
        sum += value;
    }
    expect(sum == 16);

    // To iterate over a portion of a slice, reslice.
    for (items[0..1]) |value|
        sum += value;
    expect(sum == 20);

    // To access the index of iteration, specify a second capture value.
    // This is zero-indexed.
    var sum2: i32 = 0;
    for (items) |value, i| {
        expect(@TypeOf(i) == usize);
        sum2 += @intCast(i32, i);
    }
    expect(sum2 == 10);
}

test "for reference" {
    var items = [_]i32{ 3, 4, 2 };

    // Iterate over the slice by reference by
    // specifying that the capture value is a pointer.
    for (items) |*value|
        value.* += 1;

    expect(items[0] == 4);
    expect(items[1] == 5);
    expect(items[2] == 3);
}

test "for else" {
    // For allows an else attached to it, the same as a while loop.
    var items = [_]?i32{ 3, 4, null, 5 };

    // For loops can also be used as expressions.
    // Similar to while loops, when you break from a for loop,
    // the else branch is not evaluated.
    var sum: i32 = 0;
    const result = for (items) |value| {
        if (value != null)
            sum += value.?;
    } else blk: {
        expect(sum == 12);
        break :blk sum;
    };
    expect(result == 12);
}

test "nested break" {
    var count: usize = 0;
    outer: for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
        for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
            count += 1;
            break :outer;
        }
    }
    expect(count == 1);
}

test "nested continue" {
    var count: usize = 0;
    outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| {
        for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
            count += 1;
            continue :outer;
        }
    }
    expect(count == 8);
}

fn typeNameLength(comptime T: type) usize {
    return @typeName(T).len;
}

test "inline for loop" {
    var sum: usize = 0;
    inline for ([_]i32{ 2, 4, 6 }) |i| {
        const T = switch (i) {
            2 => f32,
            4 => i8,
            6 => bool,
            else => unreachable,
        };
        sum += typeNameLength(T);
    }
    expect(sum == 9);
}