╭ memcpy.zig ───────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
.. conflicting_externs/ hasdecl/ import/ namespace_depends_on_compile_var/ pub_enum/ x86_64/ zon/ abs.zig addrspace_and_linksection.zig align.zig alignof.zig array.zig asm.zig atomics.zig backing_int.zig basic.zig bit_shifting.zig bitcast.zig bitreverse.zig bool.zig builtin_functions_returning_void_ byteswap.zig byval_arg_var.zig call.zig cast.zig cast_int.zig comptime_memory.zig const_slice_child.zig decl_literals.zig decltest.zig defer.zig destructure.zig duplicated_test_names.zig enum.zig error.zig eval.zig export_builtin.zig export_c_keywords.zig export_keyword.zig export_self_referential_type_info extern.zig extern_struct_zero_size_fields.zi field_parent_ptr.zig file_to_embed.txt floatop.zig fn.zig fn_delegation.zig fn_in_struct_in_comptime.zig for.zig generics.zig globals.zig hasdecl.zig hasfield.zig if.zig import.zig import_c_keywords.zig incomplete_struct_param_tld.zig inline_switch.zig int128.zig int_comparison_elision.zig ir_block_deps.zig lower_strlit_to_vector.zig math.zig maximum_minimum.zig member_func.zig ╭─────────────────────────────────╮ │memcpy.zig │ ╰─────────────────────────────────╯ memmove.zig memset.zig merge_error_sets.zig muladd.zig multiple_externs_with_conflicting namespace_depends_on_compile_var. nan.zig null.zig optional.zig overlapping_assign.zig packed-struct.zig packed-union.zig packed_struct_explicit_backing_in pointers.zig popcount.zig prefetch.zig ptrcast.zig ptrfromint.zig pub_enum.zig ref_var_in_if_after_if_2nd_switch reflection.zig return_address.zig saturating_arithmetic.zig select.zig shuffle.zig sizeof_and_typeof.zig slice.zig slice_sentinel_comptime.zig spirv.zig splat.zig src.zig string_literals.zig struct.zig struct_contains_null_ptr_itself.z struct_contains_slice_of_itself.z switch.zig switch_loop.zig switch_on_captured_error.zig switch_prong_err_enum.zig switch_prong_implicit_cast.zig this.zig threadlocal.zig truncate.zig try.zig tuple.zig tuple_declarations.zig type.zig type_info.zig typename.zig undefined.zig underscore.zig union.zig var_args.zig vector.zig void.zig wasm.zig while.zig widening.zig wrapping_arithmetic.zig x86_64.zig zero.bin zon.zig
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 const expect = std.testing.expect; 4 const assert = std.debug.assert; 5 6 test "memcpy and memset intrinsics" { 7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 9 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 10 11 try testMemcpyMemset(); 12 try comptime testMemcpyMemset(); 13 } 14 15 fn testMemcpyMemset() !void { 16 var foo: [20]u8 = undefined; 17 var bar: [20]u8 = undefined; 18 19 @memset(&foo, 'A'); 20 @memcpy(&bar, &foo); 21 22 try expect(bar[0] == 'A'); 23 try expect(bar[11] == 'A'); 24 try expect(bar[19] == 'A'); 25 } 26 27 test "@memcpy with both operands single-ptr-to-array, one is null-terminated" { 28 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; 30 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 31 32 try testMemcpyBothSinglePtrArrayOneIsNullTerminated(); 33 try comptime testMemcpyBothSinglePtrArrayOneIsNullTerminated(); 34 } 35 36 fn testMemcpyBothSinglePtrArrayOneIsNullTerminated() !void { 37 var buf: [100]u8 = undefined; 38 const suffix = "hello"; 39 @memcpy(buf[buf.len - suffix.len ..], suffix); 40 try expect(buf[95] == 'h'); 41 try expect(buf[96] == 'e'); 42 try expect(buf[97] == 'l'); 43 try expect(buf[98] == 'l'); 44 try expect(buf[99] == 'o'); 45 } 46 47 test "@memcpy dest many pointer" { 48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; 50 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 51 52 try testMemcpyDestManyPtr(); 53 try comptime testMemcpyDestManyPtr(); 54 } 55 56 fn testMemcpyDestManyPtr() !void { 57 var str = "hello".*; 58 var buf: [5]u8 = undefined; 59 var len: usize = 5; 60 _ = &len; 61 @memcpy(@as([*]u8, @ptrCast(&buf)), @as([*]const u8, @ptrCast(&str))[0..len]); 62 try expect(buf[0] == 'h'); 63 try expect(buf[1] == 'e'); 64 try expect(buf[2] == 'l'); 65 try expect(buf[3] == 'l'); 66 try expect(buf[4] == 'o'); 67 } 68 69 test "@memcpy C pointer" { 70 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 71 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; 72 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 73 74 try testMemcpyCPointer(); 75 try comptime testMemcpyCPointer(); 76 } 77 78 fn testMemcpyCPointer() !void { 79 const src = "hello"; 80 var buf: [5]u8 = undefined; 81 @memcpy(@as([*c]u8, &buf), src); 82 try expect(buf[0] == 'h'); 83 try expect(buf[1] == 'e'); 84 try expect(buf[2] == 'l'); 85 try expect(buf[3] == 'l'); 86 try expect(buf[4] == 'o'); 87 } 88 89 test "@memcpy slice" { 90 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 91 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 92 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; 93 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 94 95 try testMemcpySlice(); 96 try comptime testMemcpySlice(); 97 } 98 99 fn testMemcpySlice() !void { 100 var buf: [5]u8 = undefined; 101 const dst: []u8 = &buf; 102 const src: []const u8 = "hello"; 103 @memcpy(dst, src); 104 try expect(buf[0] == 'h'); 105 try expect(buf[1] == 'e'); 106 try expect(buf[2] == 'l'); 107 try expect(buf[3] == 'l'); 108 try expect(buf[4] == 'o'); 109 } 110 111 comptime { 112 const S = struct { 113 buffer: [8]u8 = undefined, 114 fn set(self: *@This(), items: []const u8) void { 115 @memcpy(self.buffer[0..items.len], items); 116 } 117 }; 118 119 var s = S{}; 120 s.set("hello"); 121 if (!std.mem.eql(u8, s.buffer[0..5], "hello")) @compileError("bad"); 122 } 123 124 test "@memcpy comptime-only type" { 125 const in: [4]type = .{ u8, u16, u32, u64 }; 126 comptime var out: [4]type = undefined; 127 @memcpy(&out, &in); 128 129 comptime assert(out[0] == u8); 130 comptime assert(out[1] == u16); 131 comptime assert(out[2] == u32); 132 comptime assert(out[3] == u64); 133 } 134 135 test "@memcpy zero-bit type with aliasing" { 136 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 137 138 const S = struct { 139 fn doTheTest() void { 140 var buf: [3]void = @splat({}); 141 const slice: []void = &buf; 142 // These two pointers are the same, but it's still not considered aliasing because 143 // the input and output slices both correspond to zero bits of memory. 144 @memcpy(slice, slice); 145 comptime assert(buf[0] == {}); 146 comptime assert(buf[1] == {}); 147 comptime assert(buf[2] == {}); 148 } 149 }; 150 S.doTheTest(); 151 comptime S.doTheTest(); 152 } 153 154 test "@memcpy with sentinel" { 155 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 156 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; 157 158 const S = struct { 159 fn doTheTest() void { 160 const field_name = @typeInfo(struct { a: u32 }).@"struct".field_names[0]; 161 var buffer: [field_name.len]u8 = undefined; 162 @memcpy(&buffer, field_name); 163 } 164 }; 165 166 S.doTheTest(); 167 comptime S.doTheTest(); 168 } 169 170 test "@memcpy no sentinel source into sentinel destination" { 171 const S = struct { 172 fn doTheTest() void { 173 const src: []const u8 = &.{ 1, 2, 3 }; 174 comptime var dest_buf: [3:0]u8 = @splat(0); 175 const dest: [:0]u8 = &dest_buf; 176 @memcpy(dest, src); 177 } 178 }; 179 180 S.doTheTest(); 181 comptime S.doTheTest(); 182 } 183 184 test "@memcpy a global array" { 185 const S = struct { 186 var array_u8: [1]u8 = .{1}; 187 const slice_u8: []u8 = &array_u8; 188 var array_u32: [1]u32 = .{10}; 189 const slice_u32: []u32 = &array_u32; 190 }; 191 192 try expect(S.array_u8[0] == 1); 193 @memcpy(&S.array_u8, &[1]u8{2}); 194 try expect(S.array_u8[0] == 2); 195 @memcpy(&S.array_u8, &[1]u8{S.array_u8[0] + 1}); 196 try expect(S.array_u8[0] == 3); 197 @memcpy(S.slice_u8, &[1]u8{4}); 198 try expect(S.array_u8[0] == 4); 199 @memcpy(S.slice_u8, &[1]u8{S.array_u8[0] + 1}); 200 try expect(S.array_u8[0] == 5); 201 202 try expect(S.array_u32[0] == 10); 203 @memcpy(&S.array_u32, &[1]u32{20}); 204 try expect(S.array_u32[0] == 20); 205 @memcpy(&S.array_u32, &[1]u32{S.array_u32[0] + 10}); 206 try expect(S.array_u32[0] == 30); 207 @memcpy(S.slice_u32, &[1]u32{40}); 208 try expect(S.array_u32[0] == 40); 209 @memcpy(S.slice_u32, &[1]u32{S.array_u32[0] + 10}); 210 try expect(S.array_u32[0] == 50); 211 } 212