-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbit_set.jai
More file actions
107 lines (93 loc) · 3.02 KB
/
bit_set.jai
File metadata and controls
107 lines (93 loc) · 3.02 KB
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
101
102
103
104
105
106
Int_Bit_Set :: struct(MIN: int, MAX: int) {
MASK_SIZE :: ((MAX - MIN + 1) / 8) + cast(int) ((MAX - MIN + 1) % 8 != 0);
mask: [MASK_SIZE] u8;
}
check_bit :: (using bit_set: Int_Bit_Set, check_bits: ..int) -> bool {
for check_bits {
byte_index := (it - MIN) / 8;
bit_index := cast(u8) 1 << ((it - MIN) % 8);
if it < MIN || it > MAX || bit_index & mask[byte_index] == 0 {
log("Bit % was not set", it);
return false;
}
}
return true;
}
set_bit :: (using bit_set: *Int_Bit_Set, set_bits: ..int) -> bool {
for set_bits {
if it < MIN || it > MAX {
log("Failed to set bit %", it);
return false;
}
byte_index := (it - MIN) / 8;
bit_index := cast(u8) 1 << ((it - MIN) % 8);
mask[byte_index] |= bit_index;
}
return true;
}
Enum_Bit_Set :: struct($T: Type) {
MIN :: #run -> int {
min := type_info(T).values[0];
for type_info(T).values if it < min min = it;
return min;
};
MAX :: #run -> int {
max := type_info(T).values[0];
for type_info(T).values if it > max max = it;
return max;
};
MASK_SIZE :: ((MAX - MIN + 1) / 8) + cast(int) ((MAX - MIN + 1) % 8 != 0);
mask: [MASK_SIZE] u8;
from :: #procedure_of_call make_bit_set((0).(T));
}
check_bit :: (using bit_set: Enum_Bit_Set, bit: bit_set.T) -> bool {
byte_index := (bit - MIN) / 8;
bit_index := cast(u8) 1 << ((bit - MIN) % 8);
return bit < MIN || bit > MAX || bit_index & mask[byte_index] == 0;
}
check_bits :: (using bit_set: Enum_Bit_Set, check_bits: ..bit_set.T) -> bool {
for check_bits {
byte_index := (it - MIN) / 8;
bit_index := cast(u8) 1 << ((it - MIN) % 8);
if it < MIN || it > MAX || bit_index & mask[byte_index] == 0 {
log("Bit % was not set", it);
return false;
}
}
return true;
}
set_bit :: (using bit_set: *Enum_Bit_Set, bit: bit_set.T) -> bool {
if bit < MIN || bit > MAX {
log("Failed to set bit %", bit);
return false;
}
byte_index := (bit - MIN) / 8;
bit_index := cast(u8) 1 << ((bit - MIN) % 8);
mask[byte_index] |= bit_index;
}
set_bits :: (using bit_set: *Enum_Bit_Set, bits_to_set: ..bit_set.T) -> bool {
for bits_to_set {
if it < MIN || it > MAX {
log("Failed to set bit %", it);
return false;
}
byte_index := (it - MIN) / 8;
bit_index := cast(u8) 1 << ((it - MIN) % 8);
mask[byte_index] |= bit_index;
}
return true;
}
make_bit_set :: (bits_to_set: ..$T) -> Enum_Bit_Set(T) #modify {
ti := cast(*Type_Info_Enum) T;
return ti.type == .ENUM && !(ti.enum_type_flags & .FLAGS);
} {
set: Enum_Bit_Set(T);
for bits_to_set {
if it >= set.MIN && it <= set.MAX {
byte_index := (it - set.MIN) / 8;
bit_index := cast(u8) 1 << ((it - set.MIN) % 8);
set.mask[byte_index] |= bit_index;
}
}
return set;
}