zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob ccfbc7e9 (12342B) - Raw


      1 const std = @import("std");
      2 const testing = std.testing;
      3 const mem = std.mem;
      4 const expect = testing.expect;
      5 const expectEqual = testing.expectEqual;
      6 
      7 test "arrays" {
      8     var array: [5]u32 = undefined;
      9 
     10     var i: u32 = 0;
     11     while (i < 5) {
     12         array[i] = i + 1;
     13         i = array[i];
     14     }
     15 
     16     i = 0;
     17     var accumulator = @as(u32, 0);
     18     while (i < 5) {
     19         accumulator += array[i];
     20 
     21         i += 1;
     22     }
     23 
     24     expect(accumulator == 15);
     25     expect(getArrayLen(&array) == 5);
     26 }
     27 fn getArrayLen(a: []const u32) usize {
     28     return a.len;
     29 }
     30 
     31 test "array with sentinels" {
     32     const S = struct {
     33         fn doTheTest(is_ct: bool) void {
     34             if (is_ct) {
     35                 var zero_sized: [0:0xde]u8 = [_:0xde]u8{};
     36                 // Disabled at runtime because of
     37                 // https://github.com/ziglang/zig/issues/4372
     38                 expectEqual(@as(u8, 0xde), zero_sized[0]);
     39                 var reinterpreted = @ptrCast(*[1]u8, &zero_sized);
     40                 expectEqual(@as(u8, 0xde), reinterpreted[0]);
     41             }
     42             var arr: [3:0x55]u8 = undefined;
     43             // Make sure the sentinel pointer is pointing after the last element
     44             if (!is_ct) {
     45                 const sentinel_ptr = @ptrToInt(&arr[3]);
     46                 const last_elem_ptr = @ptrToInt(&arr[2]);
     47                 expectEqual(@as(usize, 1), sentinel_ptr - last_elem_ptr);
     48             }
     49             // Make sure the sentinel is writeable
     50             arr[3] = 0x55;
     51         }
     52     };
     53 
     54     S.doTheTest(false);
     55     comptime S.doTheTest(true);
     56 }
     57 
     58 test "void arrays" {
     59     var array: [4]void = undefined;
     60     array[0] = void{};
     61     array[1] = array[2];
     62     expect(@sizeOf(@TypeOf(array)) == 0);
     63     expect(array.len == 4);
     64 }
     65 
     66 test "array literal" {
     67     const hex_mult = [_]u16{
     68         4096,
     69         256,
     70         16,
     71         1,
     72     };
     73 
     74     expect(hex_mult.len == 4);
     75     expect(hex_mult[1] == 256);
     76 }
     77 
     78 test "array dot len const expr" {
     79     expect(comptime x: {
     80         break :x some_array.len == 4;
     81     });
     82 }
     83 
     84 const ArrayDotLenConstExpr = struct {
     85     y: [some_array.len]u8,
     86 };
     87 const some_array = [_]u8{
     88     0,
     89     1,
     90     2,
     91     3,
     92 };
     93 
     94 test "nested arrays" {
     95     const array_of_strings = [_][]const u8{
     96         "hello",
     97         "this",
     98         "is",
     99         "my",
    100         "thing",
    101     };
    102     for (array_of_strings) |s, i| {
    103         if (i == 0) expect(mem.eql(u8, s, "hello"));
    104         if (i == 1) expect(mem.eql(u8, s, "this"));
    105         if (i == 2) expect(mem.eql(u8, s, "is"));
    106         if (i == 3) expect(mem.eql(u8, s, "my"));
    107         if (i == 4) expect(mem.eql(u8, s, "thing"));
    108     }
    109 }
    110 
    111 var s_array: [8]Sub = undefined;
    112 const Sub = struct {
    113     b: u8,
    114 };
    115 const Str = struct {
    116     a: []Sub,
    117 };
    118 test "set global var array via slice embedded in struct" {
    119     var s = Str{ .a = s_array[0..] };
    120 
    121     s.a[0].b = 1;
    122     s.a[1].b = 2;
    123     s.a[2].b = 3;
    124 
    125     expect(s_array[0].b == 1);
    126     expect(s_array[1].b == 2);
    127     expect(s_array[2].b == 3);
    128 }
    129 
    130 test "array literal with specified size" {
    131     var array = [2]u8{
    132         1,
    133         2,
    134     };
    135     expect(array[0] == 1);
    136     expect(array[1] == 2);
    137 }
    138 
    139 test "array len field" {
    140     var arr = [4]u8{ 0, 0, 0, 0 };
    141     var ptr = &arr;
    142     expect(arr.len == 4);
    143     comptime expect(arr.len == 4);
    144     expect(ptr.len == 4);
    145     comptime expect(ptr.len == 4);
    146 }
    147 
    148 test "single-item pointer to array indexing and slicing" {
    149     testSingleItemPtrArrayIndexSlice();
    150     comptime testSingleItemPtrArrayIndexSlice();
    151 }
    152 
    153 fn testSingleItemPtrArrayIndexSlice() void {
    154     {
    155         var array: [4]u8 = "aaaa".*;
    156         doSomeMangling(&array);
    157         expect(mem.eql(u8, "azya", &array));
    158     }
    159     {
    160         var array = "aaaa".*;
    161         doSomeMangling(&array);
    162         expect(mem.eql(u8, "azya", &array));
    163     }
    164 }
    165 
    166 fn doSomeMangling(array: *[4]u8) void {
    167     array[1] = 'z';
    168     array[2..3][0] = 'y';
    169 }
    170 
    171 test "implicit cast single-item pointer" {
    172     testImplicitCastSingleItemPtr();
    173     comptime testImplicitCastSingleItemPtr();
    174 }
    175 
    176 fn testImplicitCastSingleItemPtr() void {
    177     var byte: u8 = 100;
    178     const slice = @as(*[1]u8, &byte)[0..];
    179     slice[0] += 1;
    180     expect(byte == 101);
    181 }
    182 
    183 fn testArrayByValAtComptime(b: [2]u8) u8 {
    184     return b[0];
    185 }
    186 
    187 test "comptime evalutating function that takes array by value" {
    188     const arr = [_]u8{ 0, 1 };
    189     _ = comptime testArrayByValAtComptime(arr);
    190     _ = comptime testArrayByValAtComptime(arr);
    191 }
    192 
    193 test "implicit comptime in array type size" {
    194     var arr: [plusOne(10)]bool = undefined;
    195     expect(arr.len == 11);
    196 }
    197 
    198 fn plusOne(x: u32) u32 {
    199     return x + 1;
    200 }
    201 
    202 test "runtime initialize array elem and then implicit cast to slice" {
    203     var two: i32 = 2;
    204     const x: []const i32 = &[_]i32{two};
    205     expect(x[0] == 2);
    206 }
    207 
    208 test "array literal as argument to function" {
    209     const S = struct {
    210         fn entry(two: i32) void {
    211             foo(&[_]i32{
    212                 1,
    213                 2,
    214                 3,
    215             });
    216             foo(&[_]i32{
    217                 1,
    218                 two,
    219                 3,
    220             });
    221             foo2(true, &[_]i32{
    222                 1,
    223                 2,
    224                 3,
    225             });
    226             foo2(true, &[_]i32{
    227                 1,
    228                 two,
    229                 3,
    230             });
    231         }
    232         fn foo(x: []const i32) void {
    233             expect(x[0] == 1);
    234             expect(x[1] == 2);
    235             expect(x[2] == 3);
    236         }
    237         fn foo2(trash: bool, x: []const i32) void {
    238             expect(trash);
    239             expect(x[0] == 1);
    240             expect(x[1] == 2);
    241             expect(x[2] == 3);
    242         }
    243     };
    244     S.entry(2);
    245     comptime S.entry(2);
    246 }
    247 
    248 test "double nested array to const slice cast in array literal" {
    249     const S = struct {
    250         fn entry(two: i32) void {
    251             const cases = [_][]const []const i32{
    252                 &[_][]const i32{&[_]i32{1}},
    253                 &[_][]const i32{&[_]i32{ 2, 3 }},
    254                 &[_][]const i32{
    255                     &[_]i32{4},
    256                     &[_]i32{ 5, 6, 7 },
    257                 },
    258             };
    259             check(&cases);
    260 
    261             const cases2 = [_][]const i32{
    262                 &[_]i32{1},
    263                 &[_]i32{ two, 3 },
    264             };
    265             expect(cases2.len == 2);
    266             expect(cases2[0].len == 1);
    267             expect(cases2[0][0] == 1);
    268             expect(cases2[1].len == 2);
    269             expect(cases2[1][0] == 2);
    270             expect(cases2[1][1] == 3);
    271 
    272             const cases3 = [_][]const []const i32{
    273                 &[_][]const i32{&[_]i32{1}},
    274                 &[_][]const i32{&[_]i32{ two, 3 }},
    275                 &[_][]const i32{
    276                     &[_]i32{4},
    277                     &[_]i32{ 5, 6, 7 },
    278                 },
    279             };
    280             check(&cases3);
    281         }
    282 
    283         fn check(cases: []const []const []const i32) void {
    284             expect(cases.len == 3);
    285             expect(cases[0].len == 1);
    286             expect(cases[0][0].len == 1);
    287             expect(cases[0][0][0] == 1);
    288             expect(cases[1].len == 1);
    289             expect(cases[1][0].len == 2);
    290             expect(cases[1][0][0] == 2);
    291             expect(cases[1][0][1] == 3);
    292             expect(cases[2].len == 2);
    293             expect(cases[2][0].len == 1);
    294             expect(cases[2][0][0] == 4);
    295             expect(cases[2][1].len == 3);
    296             expect(cases[2][1][0] == 5);
    297             expect(cases[2][1][1] == 6);
    298             expect(cases[2][1][2] == 7);
    299         }
    300     };
    301     S.entry(2);
    302     comptime S.entry(2);
    303 }
    304 
    305 test "read/write through global variable array of struct fields initialized via array mult" {
    306     const S = struct {
    307         fn doTheTest() void {
    308             expect(storage[0].term == 1);
    309             storage[0] = MyStruct{ .term = 123 };
    310             expect(storage[0].term == 123);
    311         }
    312 
    313         pub const MyStruct = struct {
    314             term: usize,
    315         };
    316 
    317         var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1;
    318     };
    319     S.doTheTest();
    320 }
    321 
    322 test "implicit cast zero sized array ptr to slice" {
    323     {
    324         var b = "".*;
    325         const c: []const u8 = &b;
    326         expect(c.len == 0);
    327     }
    328     {
    329         var b: [0]u8 = "".*;
    330         const c: []const u8 = &b;
    331         expect(c.len == 0);
    332     }
    333 }
    334 
    335 test "anonymous list literal syntax" {
    336     const S = struct {
    337         fn doTheTest() void {
    338             var array: [4]u8 = .{ 1, 2, 3, 4 };
    339             expect(array[0] == 1);
    340             expect(array[1] == 2);
    341             expect(array[2] == 3);
    342             expect(array[3] == 4);
    343         }
    344     };
    345     S.doTheTest();
    346     comptime S.doTheTest();
    347 }
    348 
    349 test "anonymous literal in array" {
    350     const S = struct {
    351         const Foo = struct {
    352             a: usize = 2,
    353             b: usize = 4,
    354         };
    355         fn doTheTest() void {
    356             var array: [2]Foo = .{
    357                 .{ .a = 3 },
    358                 .{ .b = 3 },
    359             };
    360             expect(array[0].a == 3);
    361             expect(array[0].b == 4);
    362             expect(array[1].a == 2);
    363             expect(array[1].b == 3);
    364         }
    365     };
    366     S.doTheTest();
    367     comptime S.doTheTest();
    368 }
    369 
    370 test "access the null element of a null terminated array" {
    371     const S = struct {
    372         fn doTheTest() void {
    373             var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' };
    374             expect(array[4] == 0);
    375             var len: usize = 4;
    376             expect(array[len] == 0);
    377         }
    378     };
    379     S.doTheTest();
    380     comptime S.doTheTest();
    381 }
    382 
    383 test "type deduction for array subscript expression" {
    384     const S = struct {
    385         fn doTheTest() void {
    386             var array = [_]u8{ 0x55, 0xAA };
    387             var v0 = true;
    388             expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]);
    389             var v1 = false;
    390             expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]);
    391         }
    392     };
    393     S.doTheTest();
    394     comptime S.doTheTest();
    395 }
    396 
    397 test "sentinel element count towards the ABI size calculation" {
    398     const S = struct {
    399         fn doTheTest() void {
    400             const T = packed struct {
    401                 fill_pre: u8 = 0x55,
    402                 data: [0:0]u8 = undefined,
    403                 fill_post: u8 = 0xAA,
    404             };
    405             var x = T{};
    406             var as_slice = mem.asBytes(&x);
    407             expectEqual(@as(usize, 3), as_slice.len);
    408             expectEqual(@as(u8, 0x55), as_slice[0]);
    409             expectEqual(@as(u8, 0xAA), as_slice[2]);
    410         }
    411     };
    412 
    413     S.doTheTest();
    414     comptime S.doTheTest();
    415 }
    416 
    417 test "zero-sized array with recursive type definition" {
    418     const U = struct {
    419         fn foo(comptime T: type, comptime n: usize) type {
    420             return struct {
    421                 s: [n]T,
    422                 x: usize = n,
    423             };
    424         }
    425     };
    426 
    427     const S = struct {
    428         list: U.foo(@This(), 0),
    429     };
    430 
    431     var t: S = .{ .list = .{ .s = undefined } };
    432     expectEqual(@as(usize, 0), t.list.x);
    433 }
    434 
    435 test "type coercion of anon struct literal to array" {
    436     const S = struct {
    437         const U = union{
    438             a: u32,
    439             b: bool,
    440             c: []const u8,
    441         };
    442 
    443         fn doTheTest() void {
    444             var x1: u8 = 42;
    445             const t1 = .{ x1, 56, 54 };
    446             var arr1: [3]u8 = t1;
    447             expect(arr1[0] == 42);
    448             expect(arr1[1] == 56);
    449             expect(arr1[2] == 54);
    450             
    451             var x2: U = .{ .a = 42 };
    452             const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } };
    453             var arr2: [3]U = t2;
    454             expect(arr2[0].a == 42);
    455             expect(arr2[1].b == true);
    456             expect(mem.eql(u8, arr2[2].c, "hello"));
    457         }
    458     };
    459     S.doTheTest();
    460     comptime S.doTheTest();
    461 }
    462 
    463 test "type coercion of pointer to anon struct literal to pointer to array" {
    464     const S = struct {
    465         const U = union{
    466             a: u32,
    467             b: bool,
    468             c: []const u8,
    469         };
    470 
    471         fn doTheTest() void {
    472             var x1: u8 = 42;
    473             const t1 = &.{ x1, 56, 54 };
    474             var arr1: *[3]u8 = t1;
    475             expect(arr1[0] == 42);
    476             expect(arr1[1] == 56);
    477             expect(arr1[2] == 54);
    478             
    479             var x2: U = .{ .a = 42 };
    480             const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } };
    481             var arr2: *[3]U = t2;
    482             expect(arr2[0].a == 42);
    483             expect(arr2[1].b == true);
    484             expect(mem.eql(u8, arr2[2].c, "hello"));
    485         }
    486     };
    487     S.doTheTest();
    488     comptime S.doTheTest();
    489 }