Add some bit set variants

This commit is contained in:
Martin Wickham 2021-02-04 23:04:49 -06:00 committed by Andrew Kelley
parent 1f861ecc95
commit 7613e51a57
4 changed files with 1322 additions and 0 deletions

1254
lib/std/bit_set.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1330,3 +1330,59 @@ test "math.comptime" {
comptime const v = sin(@as(f32, 1)) + ln(@as(f32, 5));
testing.expect(v == sin(@as(f32, 1)) + ln(@as(f32, 5)));
}
/// Returns a mask of all ones if value is true,
/// and a mask of all zeroes if value is false.
/// Compiles to one instruction for register sized integers.
pub inline fn boolMask(comptime MaskInt: type, value: bool) MaskInt {
if (@typeInfo(MaskInt) != .Int)
@compileError("boolMask requires an integer mask type.");
if (MaskInt == u0 or MaskInt == i0)
@compileError("boolMask cannot convert to u0 or i0, they are too small.");
// The u1 and i1 cases tend to overflow,
// so we special case them here.
if (MaskInt == u1) return @boolToInt(value);
if (MaskInt == i1) {
// The @as here is a workaround for #7950
return @bitCast(i1, @as(u1, @boolToInt(value)));
}
// At comptime, -% is disallowed on unsigned values.
// So we need to jump through some hoops in that case.
// This is a workaround for #7951
if (@typeInfo(@TypeOf(.{value})).Struct.fields[0].is_comptime) {
// Since it's comptime, we don't need this to generate nice code.
// We can just do a branch here.
return if (value) ~@as(MaskInt, 0) else 0;
}
return -%@intCast(MaskInt, @boolToInt(value));
}
test "boolMask" {
const runTest = struct {
fn runTest() void {
testing.expectEqual(@as(u1, 0), boolMask(u1, false));
testing.expectEqual(@as(u1, 1), boolMask(u1, true));
testing.expectEqual(@as(i1, 0), boolMask(i1, false));
testing.expectEqual(@as(i1, -1), boolMask(i1, true));
testing.expectEqual(@as(u13, 0), boolMask(u13, false));
testing.expectEqual(@as(u13, 0x1FFF), boolMask(u13, true));
testing.expectEqual(@as(i13, 0), boolMask(i13, false));
testing.expectEqual(@as(i13, -1), boolMask(i13, true));
testing.expectEqual(@as(u32, 0), boolMask(u32, false));
testing.expectEqual(@as(u32, 0xFFFF_FFFF), boolMask(u32, true));
testing.expectEqual(@as(i32, 0), boolMask(i32, false));
testing.expectEqual(@as(i32, -1), boolMask(i32, true));
}
}.runTest;
runTest();
comptime runTest();
}

View File

@ -25,6 +25,14 @@ pub const page_size = switch (builtin.arch) {
else => 4 * 1024,
};
/// The standard library currently thoroughly depends on byte size
/// being 8 bits. (see the use of u8 throughout allocation code as
/// the "byte" type.) Code which depends on this can reference this
/// declaration. If we ever try to port the standard library to a
/// non-8-bit-byte platform, this will allow us to search for things
/// which need to be updated.
pub const byte_size_in_bits = 8;
pub const Allocator = @import("mem/Allocator.zig");
/// Detects and asserts if the std.mem.Allocator interface is violated by the caller

View File

@ -18,6 +18,8 @@ pub const BufSet = @import("buf_set.zig").BufSet;
pub const ChildProcess = @import("child_process.zig").ChildProcess;
pub const ComptimeStringMap = @import("comptime_string_map.zig").ComptimeStringMap;
pub const DynLib = @import("dynamic_library.zig").DynLib;
pub const DynamicBitSet = bit_set.DynamicBitSet;
pub const DynamicBitSetUnmanaged = bit_set.DynamicBitSetUnmanaged;
pub const HashMap = hash_map.HashMap;
pub const HashMapUnmanaged = hash_map.HashMapUnmanaged;
pub const MultiArrayList = @import("multi_array_list.zig").MultiArrayList;
@ -29,6 +31,7 @@ pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;
pub const Progress = @import("Progress.zig");
pub const SemanticVersion = @import("SemanticVersion.zig");
pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
pub const StaticBitSet = bit_set.StaticBitSet;
pub const StringHashMap = hash_map.StringHashMap;
pub const StringHashMapUnmanaged = hash_map.StringHashMapUnmanaged;
pub const StringArrayHashMap = array_hash_map.StringArrayHashMap;
@ -40,6 +43,7 @@ pub const Thread = @import("Thread.zig");
pub const array_hash_map = @import("array_hash_map.zig");
pub const atomic = @import("atomic.zig");
pub const base64 = @import("base64.zig");
pub const bit_set = @import("bit_set.zig");
pub const build = @import("build.zig");
pub const builtin = @import("builtin.zig");
pub const c = @import("c.zig");