Zig 0.17.0-dev (Split by item) This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig standard library.
std › mem › eqlBytes Private Function eqlBytes Doc Source Private Function std.mem.eqlBytes
fn eqlBytes (a : []const u8 , b : []const u8 ) bool Params a : []const u8 b : []const u8 File mem.zig: 793
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851 fn eqlBytes (a : []const u8 , b : []const u8 ) bool {
comptime assert (use_vectors_for_comparison );
if (a .len != b .len ) return false ;
if (a .len == 0 or a .ptr == b .ptr ) return true ;
if (a .len <= 16 ) {
if (a .len < 4 ) {
const x = (a [0 ] ^ b [0 ]) | (a [a .len - 1 ] ^ b [a .len - 1 ]) | (a [a .len / 2 ] ^ b [a .len / 2 ]);
return x == 0 ;
}
var x : u32 = 0 ;
for ([_ ]usize { 0 , a .len - 4 , (a .len / 8 ) * 4 , a .len - 4 - ((a .len / 8 ) * 4 ) }) |n | {
x |= @as (u32 , @bitCast (a [n ..][0 ..4 ].*)) ^ @as (u32 , @bitCast (b [n ..][0 ..4 ].*));
}
return x == 0 ;
}
// Figure out the fastest way to scan through the input in chunks.
// Uses vectors when supported and falls back to usize/words when not.
const Scan = if (std .simd .suggestVectorLength (u8 )) |vec_size |
struct {
pub const size = vec_size ;
pub const Chunk = @Vector (size , u8 );
pub inline fn isNotEqual (chunk_a : Chunk , chunk_b : Chunk ) bool {
return @reduce (.Or , chunk_a != chunk_b );
}
}
else
struct {
pub const size = @sizeOf (usize );
pub const Chunk = usize ;
pub inline fn isNotEqual (chunk_a : Chunk , chunk_b : Chunk ) bool {
return chunk_a != chunk_b ;
}
};
inline for (1 ..6 ) |s | {
const n = 16 << s ;
if (n <= Scan .size and a .len <= n ) {
const V = @Vector (n / 2 , u8 );
var x = @as (V , a [0 .. n / 2 ].*) ^ @as (V , b [0 .. n / 2 ].*);
x |= @as (V , a [a .len - n / 2 ..][0 .. n / 2 ].*) ^ @as (V , b [a .len - n / 2 ..][0 .. n / 2 ].*);
const zero : V = @splat (0 );
return !@reduce (.Or , x != zero );
}
}
// Compare inputs in chunks at a time (excluding the last chunk).
for (0 ..(a .len - 1 ) / Scan .size ) |i | {
const a_chunk : Scan .Chunk = @bitCast (a [i * Scan .size ..][0 ..Scan .size ].*);
const b_chunk : Scan .Chunk = @bitCast (b [i * Scan .size ..][0 ..Scan .size ].*);
if (Scan .isNotEqual (a_chunk , b_chunk )) return false ;
}
// Compare the last chunk using an overlapping read (similar to the previous size strategies).
const last_a_chunk : Scan .Chunk = @bitCast (a [a .len - Scan .size ..][0 ..Scan .size ].*);
const last_b_chunk : Scan .Chunk = @bitCast (b [a .len - Scan .size ..][0 ..Scan .size ].*);
return !Scan .isNotEqual (last_a_chunk , last_b_chunk );
}
std.mem.eql heavily optimized for slices of bytes.