authorgravatar for tgschultz@gmail.comtgschultz <tgschultz@gmail.com> 2019-05-04 16:19:26+00:00
committergravatar for tgschultz@gmail.comtgschultz <tgschultz@gmail.com> 2019-05-04 16:19:26+00:00
log14a00d3825df34a993d7579869aa0204400e9fde
tree789b782261be2b6b584055ad82a013144803caa1
parent8c28b5960559daef3ffc6b0777829ae3262ee8c7

zig fmt


1 files changed, 203 insertions(+), 263 deletions(-)

std/packed_int_array.zig+203-263
...@@ -3,148 +3,134 @@ const builtin = @import("builtin");...@@ -3,148 +3,134 @@ const builtin = @import("builtin");
3const debug = std.debug;3const debug = std.debug;
4const testing = std.testing;4const testing = std.testing;
55
6pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type6pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
7{
8 //The general technique employed here is to cast bytes in the array to a container7 //The general technique employed here is to cast bytes in the array to a container
9 // integer (having bits % 8 == 0) large enough to contain the number of bits we want,8 // integer (having bits % 8 == 0) large enough to contain the number of bits we want,
10 // then we can retrieve or store the new value with a relative minimum of masking9 // then we can retrieve or store the new value with a relative minimum of masking
11 // and shifting. In this worst case, this means that we'll need an integer that's10 // and shifting. In this worst case, this means that we'll need an integer that's
12 // actually 1 byte larger than the minimum required to store the bits, because it11 // actually 1 byte larger than the minimum required to store the bits, because it
13 // is possible that the bits start at the end of the first byte, continue through 12 // is possible that the bits start at the end of the first byte, continue through
14 // zero or more, then end in the beginning of the last. But, if we try to access13 // zero or more, then end in the beginning of the last. But, if we try to access
15 // a value in the very last byte of memory with that integer size, that extra byte14 // a value in the very last byte of memory with that integer size, that extra byte
16 // will be out of bounds. Depending on the circumstances of the memory, that might15 // will be out of bounds. Depending on the circumstances of the memory, that might
17 // mean the OS fatally kills the program. Thus, we use a larger container (MaxIo)16 // mean the OS fatally kills the program. Thus, we use a larger container (MaxIo)
18 // most of the time, but a smaller container (MinIo) when touching the last byte17 // most of the time, but a smaller container (MinIo) when touching the last byte
19 // of the memory.18 // of the memory.
20
21 const int_bits = comptime std.meta.bitCount(Int);19 const int_bits = comptime std.meta.bitCount(Int);
22 20
23 //in the best case, this is the number of bytes we need to touch21 //in the best case, this is the number of bytes we need to touch
24 // to read or write a value, as bits22 // to read or write a value, as bits
25 const min_io_bits = ((int_bits + 7) / 8) * 8;23 const min_io_bits = ((int_bits + 7) / 8) * 8;
26 24
27 //in the worst case, this is the number of bytes we need to touch25 //in the worst case, this is the number of bytes we need to touch
28 // to read or write a value, as bits26 // to read or write a value, as bits
29 const max_io_bits = switch(int_bits)27 const max_io_bits = switch (int_bits) {
30 {
31 0 => 0,28 0 => 0,
32 1 => 8,29 1 => 8,
33 2...9 => 16,30 2...9 => 16,
34 10...65535 => ((int_bits / 8) + 2) * 8,31 10...65535 => ((int_bits / 8) + 2) * 8,
35 else => unreachable,32 else => unreachable,
36 };33 };
37 34
38 //we bitcast the desired Int type to an unsigned version of itself35 //we bitcast the desired Int type to an unsigned version of itself
39 // to avoid issues with shifting signed ints.36 // to avoid issues with shifting signed ints.
40 const UnInt = @IntType(false, int_bits);37 const UnInt = @IntType(false, int_bits);
41 38
42 //The maximum container int type39 //The maximum container int type
43 const MinIo = @IntType(false, min_io_bits);40 const MinIo = @IntType(false, min_io_bits);
44 41
45 //The minimum container int type42 //The minimum container int type
46 const MaxIo = @IntType(false, max_io_bits);43 const MaxIo = @IntType(false, max_io_bits);
47 44
48 return struct45 return struct {
49 {46 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {
50 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int47 if (int_bits == 0) return 0;
51 {48
52 if(int_bits == 0) return 0;
53
54 const bit_index = (index * int_bits) + bit_offset;49 const bit_index = (index * int_bits) + bit_offset;
55 const max_end_byte = (bit_index + max_io_bits) / 8;50 const max_end_byte = (bit_index + max_io_bits) / 8;
56 51
57 //Using the larger container size will potentially read out of bounds52 //Using the larger container size will potentially read out of bounds
58 if(max_end_byte > bytes.len) return getBits(bytes, MinIo, bit_index);53 if (max_end_byte > bytes.len) return getBits(bytes, MinIo, bit_index);
59 return getBits(bytes, MaxIo, bit_index);54 return getBits(bytes, MaxIo, bit_index);
60 }55 }
61 56
62 fn getBits(bytes: []const u8, comptime Container: type, bit_index: usize) Int57 fn getBits(bytes: []const u8, comptime Container: type, bit_index: usize) Int {
63 {
64 const container_bits = comptime std.meta.bitCount(Container);58 const container_bits = comptime std.meta.bitCount(Container);
65 const Shift = std.math.Log2Int(Container);59 const Shift = std.math.Log2Int(Container);
66 60
67 const start_byte = bit_index / 8;61 const start_byte = bit_index / 8;
68 const head_keep_bits = bit_index - (start_byte * 8);62 const head_keep_bits = bit_index - (start_byte * 8);
69 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);63 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
70 64
71 //read bytes as container65 //read bytes as container
72 const value_ptr = @ptrCast(*const align(1) Container, &bytes[start_byte]);66 const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]);
73 var value = value_ptr.*;67 var value = value_ptr.*;
74 68
75 if(endian != builtin.endian) value = @bswap(Container, value);69 if (endian != builtin.endian) value = @bswap(Container, value);
76 70
77 switch(endian)71 switch (endian) {
78 {72 .Big => {
79 .Big =>
80 {
81 value <<= @intCast(Shift, head_keep_bits);73 value <<= @intCast(Shift, head_keep_bits);
82 value >>= @intCast(Shift, head_keep_bits);74 value >>= @intCast(Shift, head_keep_bits);
83 value >>= @intCast(Shift, tail_keep_bits);75 value >>= @intCast(Shift, tail_keep_bits);
84 },76 },
85 .Little =>77 .Little => {
86 {
87 value <<= @intCast(Shift, tail_keep_bits);78 value <<= @intCast(Shift, tail_keep_bits);
88 value >>= @intCast(Shift, tail_keep_bits);79 value >>= @intCast(Shift, tail_keep_bits);
89 value >>= @intCast(Shift, head_keep_bits);80 value >>= @intCast(Shift, head_keep_bits);
90 },81 },
91 }82 }
92 83
93 return @bitCast(Int, @truncate(UnInt, value));84 return @bitCast(Int, @truncate(UnInt, value));
94 }85 }
95 86
96 pub fn set(bytes: []u8, index: usize, bit_offset: u3, int: Int) void87 pub fn set(bytes: []u8, index: usize, bit_offset: u3, int: Int) void {
97 {88 if (int_bits == 0) return;
98 if(int_bits == 0) return;
9989
100 const bit_index = (index * int_bits) + bit_offset;90 const bit_index = (index * int_bits) + bit_offset;
101 const max_end_byte = (bit_index + max_io_bits) / 8;91 const max_end_byte = (bit_index + max_io_bits) / 8;
102 92
103 //Using the larger container size will potentially write out of bounds93 //Using the larger container size will potentially write out of bounds
104 if(max_end_byte > bytes.len) return setBits(bytes, MinIo, bit_index, int);94 if (max_end_byte > bytes.len) return setBits(bytes, MinIo, bit_index, int);
105 setBits(bytes, MaxIo, bit_index, int);95 setBits(bytes, MaxIo, bit_index, int);
106 }96 }
107 97
108 fn setBits(bytes: []u8, comptime Container: type, bit_index: usize, int: Int) void98 fn setBits(bytes: []u8, comptime Container: type, bit_index: usize, int: Int) void {
109 {
110 const container_bits = comptime std.meta.bitCount(Container);99 const container_bits = comptime std.meta.bitCount(Container);
111 const Shift = std.math.Log2Int(Container);100 const Shift = std.math.Log2Int(Container);
112 101
113 const start_byte = bit_index / 8;102 const start_byte = bit_index / 8;
114 const head_keep_bits = bit_index - (start_byte * 8);103 const head_keep_bits = bit_index - (start_byte * 8);
115 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);104 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
116 const keep_shift = switch(endian)105 const keep_shift = switch (endian) {
117 {
118 .Big => @intCast(Shift, tail_keep_bits),106 .Big => @intCast(Shift, tail_keep_bits),
119 .Little => @intCast(Shift, head_keep_bits),107 .Little => @intCast(Shift, head_keep_bits),
120 };108 };
121 109
122 //position the bits where they need to be in the container110 //position the bits where they need to be in the container
123 const value = @intCast(Container, @bitCast(UnInt, int)) << keep_shift;111 const value = @intCast(Container, @bitCast(UnInt, int)) << keep_shift;
124 112
125 //read existing bytes113 //read existing bytes
126 const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);114 const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);
127 var target = target_ptr.*;115 var target = target_ptr.*;
128 116
129 if(endian != builtin.endian) target = @bswap(Container, target);117 if (endian != builtin.endian) target = @bswap(Container, target);
130 118
131 //zero the bits we want to replace in the existing bytes119 //zero the bits we want to replace in the existing bytes
132 const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift;120 const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift;
133 const mask = ~inv_mask;121 const mask = ~inv_mask;
134 target &= mask;122 target &= mask;
135 123
136 //merge the new value124 //merge the new value
137 target |= value;125 target |= value;
138 126
139 if(endian != builtin.endian) target = @bswap(Container, target);127 if (endian != builtin.endian) target = @bswap(Container, target);
140 128
141 //save it back129 //save it back
142 target_ptr.* = target;130 target_ptr.* = target;
143 }131 }
144 132
145 fn slice(bytes: []u8, bit_offset: u3, start: usize, end: usize) 133 fn slice(bytes: []u8, bit_offset: u3, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
146 PackedIntSliceEndian(Int, endian)
147 {
148 debug.assert(end >= start);134 debug.assert(end >= start);
149135
150 const length = end - start;136 const length = end - start;
...@@ -152,28 +138,26 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type...@@ -152,28 +138,26 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type
152 const start_byte = bit_index / 8;138 const start_byte = bit_index / 8;
153 const end_byte = (bit_index + (length * int_bits) + 7) / 8;139 const end_byte = (bit_index + (length * int_bits) + 7) / 8;
154 const new_bytes = bytes[start_byte..end_byte];140 const new_bytes = bytes[start_byte..end_byte];
155 141
156 if(length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);142 if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);
157 143
158 var new_slice = PackedIntSliceEndian(Int, endian).init(new_bytes, length);144 var new_slice = PackedIntSliceEndian(Int, endian).init(new_bytes, length);
159 new_slice.bit_offset = @intCast(u3, (bit_index - (start_byte * 8)));145 new_slice.bit_offset = @intCast(u3, (bit_index - (start_byte * 8)));
160 return new_slice;146 return new_slice;
161 }147 }
162 148
163 fn sliceCast(bytes: []u8, comptime NewInt: type, comptime new_endian: builtin.Endian,149 fn sliceCast(bytes: []u8, comptime NewInt: type, comptime new_endian: builtin.Endian, bit_offset: u3, old_len: usize) PackedIntSliceEndian(NewInt, new_endian) {
164 bit_offset: u3, old_len: usize) PackedIntSliceEndian(NewInt, new_endian)
165 {
166 const new_int_bits = comptime std.meta.bitCount(NewInt);150 const new_int_bits = comptime std.meta.bitCount(NewInt);
167 const New = PackedIntSliceEndian(NewInt, new_endian);151 const New = PackedIntSliceEndian(NewInt, new_endian);
168 152
169 const total_bits = (old_len * int_bits);153 const total_bits = (old_len * int_bits);
170 const new_int_count = total_bits / new_int_bits;154 const new_int_count = total_bits / new_int_bits;
171 155
172 debug.assert(total_bits == new_int_count * new_int_bits);156 debug.assert(total_bits == new_int_count * new_int_bits);
173 157
174 var new = New.init(bytes, new_int_count);158 var new = New.init(bytes, new_int_count);
175 new.bit_offset = bit_offset;159 new.bit_offset = bit_offset;
176 160
177 return new;161 return new;
178 }162 }
179 };163 };
...@@ -182,187 +166,160 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type...@@ -182,187 +166,160 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type
182///Creates a bit-packed array of integers of type Int. Bits166///Creates a bit-packed array of integers of type Int. Bits
183/// are packed using native endianess and without storing any meta167/// are packed using native endianess and without storing any meta
184/// data. PackedIntArray(i3, 8) will occupy exactly 3 bytes of memory.168/// data. PackedIntArray(i3, 8) will occupy exactly 3 bytes of memory.
185pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type169pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type {
186{
187 return PackedIntArrayEndian(Int, builtin.endian, int_count);170 return PackedIntArrayEndian(Int, builtin.endian, int_count);
188}171}
189172
190///Creates a bit-packed array of integers of type Int. Bits173///Creates a bit-packed array of integers of type Int. Bits
191/// are packed using specified endianess and without storing any meta174/// are packed using specified endianess and without storing any meta
192/// data.175/// data.
193pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, 176pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, comptime int_count: usize) type {
194 comptime int_count: usize) type
195{
196 const int_bits = comptime std.meta.bitCount(Int);177 const int_bits = comptime std.meta.bitCount(Int);
197 const total_bits = int_bits * int_count;178 const total_bits = int_bits * int_count;
198 const total_bytes = (total_bits + 7) / 8;179 const total_bytes = (total_bits + 7) / 8;
199 180
200 const Io = PackedIntIo(Int, endian);181 const Io = PackedIntIo(Int, endian);
201 182
202 return struct183 return struct {
203 {
204 const Self = @This();184 const Self = @This();
205 185
206 bytes: [total_bytes]u8,186 bytes: [total_bytes]u8,
207 187
208 ///Returns the number of elements in the packed array188 ///Returns the number of elements in the packed array
209 pub fn len(self: Self) usize189 pub fn len(self: Self) usize {
210 {
211 return int_count;190 return int_count;
212 }191 }
213 192
214 ///Initialize a packed array using an unpacked array193 ///Initialize a packed array using an unpacked array
215 /// or, more likely, an array literal.194 /// or, more likely, an array literal.
216 pub fn init(ints: [int_count]Int) Self195 pub fn init(ints: [int_count]Int) Self {
217 {
218 var self = Self(undefined);196 var self = Self(undefined);
219 for(ints) |int, i| self.set(i, int);197 for (ints) |int, i| self.set(i, int);
220 return self;198 return self;
221 }199 }
222 200
223 ///Return the Int stored at index201 ///Return the Int stored at index
224 pub fn get(self: Self, index: usize) Int202 pub fn get(self: Self, index: usize) Int {
225 {
226 debug.assert(index < int_count);203 debug.assert(index < int_count);
227 return Io.get(self.bytes, index, 0);204 return Io.get(self.bytes, index, 0);
228 }205 }
229 206
230 ///Copy int into the array at index207 ///Copy int into the array at index
231 pub fn set(self: *Self, index: usize, int: Int) void208 pub fn set(self: *Self, index: usize, int: Int) void {
232 {
233 debug.assert(index < int_count);209 debug.assert(index < int_count);
234 return Io.set(&self.bytes, index, 0, int);210 return Io.set(&self.bytes, index, 0, int);
235 }211 }
236 212
237 ///Create a PackedIntSlice of the array from given start to given end213 ///Create a PackedIntSlice of the array from given start to given end
238 pub fn slice(self: *Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian)214 pub fn slice(self: *Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
239 {
240 debug.assert(start < int_count);215 debug.assert(start < int_count);
241 debug.assert(end <= int_count);216 debug.assert(end <= int_count);
242 return Io.slice(&self.bytes, 0, start, end);217 return Io.slice(&self.bytes, 0, start, end);
243 }218 }
244 219
245 ///Create a PackedIntSlice of the array using NewInt as the bit width integer.220 ///Create a PackedIntSlice of the array using NewInt as the bit width integer.
246 /// NewInt's bit width must fit evenly within the array's Int's total bits.221 /// NewInt's bit width must fit evenly within the array's Int's total bits.
247 pub fn sliceCast(self: *Self, comptime NewInt: type) PackedIntSlice(NewInt)222 pub fn sliceCast(self: *Self, comptime NewInt: type) PackedIntSlice(NewInt) {
248 {
249 return self.sliceCastEndian(NewInt, endian);223 return self.sliceCastEndian(NewInt, endian);
250 }224 }
251 225
252 ///Create a PackedIntSlice of the array using NewInt as the bit width integer226 ///Create a PackedIntSlice of the array using NewInt as the bit width integer
253 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within227 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within
254 /// the array's Int's total bits.228 /// the array's Int's total bits.
255 pub fn sliceCastEndian(self: *Self, comptime NewInt: type, 229 pub fn sliceCastEndian(self: *Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) {
256 comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian)
257 {
258 return Io.sliceCast(&self.bytes, NewInt, new_endian, 0, int_count);230 return Io.sliceCast(&self.bytes, NewInt, new_endian, 0, int_count);
259 }231 }
260 };232 };
261}233}
262234
263///Uses a slice as a bit-packed block of int_count integers of type Int. 235///Uses a slice as a bit-packed block of int_count integers of type Int.
264/// Bits are packed using native endianess and without storing any meta236/// Bits are packed using native endianess and without storing any meta
265/// data.237/// data.
266pub fn PackedIntSlice(comptime Int: type) type238pub fn PackedIntSlice(comptime Int: type) type {
267{
268 return PackedIntSliceEndian(Int, builtin.endian);239 return PackedIntSliceEndian(Int, builtin.endian);
269}240}
270241
271///Uses a slice as a bit-packed block of int_count integers of type Int. 242///Uses a slice as a bit-packed block of int_count integers of type Int.
272/// Bits are packed using specified endianess and without storing any meta243/// Bits are packed using specified endianess and without storing any meta
273/// data.244/// data.
274pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: builtin.Endian) type245pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: builtin.Endian) type {
275{
276 const int_bits = comptime std.meta.bitCount(Int);246 const int_bits = comptime std.meta.bitCount(Int);
277 const Io = PackedIntIo(Int, endian);247 const Io = PackedIntIo(Int, endian);
278 248
279 return struct249 return struct {
280 {
281 const Self = @This();250 const Self = @This();
282 251
283 bytes: []u8,252 bytes: []u8,
284 int_count: usize,253 int_count: usize,
285 bit_offset: u3,254 bit_offset: u3,
286 255
287 ///Returns the number of elements in the packed slice256 ///Returns the number of elements in the packed slice
288 pub fn len(self: Self) usize257 pub fn len(self: Self) usize {
289 {
290 return self.int_count;258 return self.int_count;
291 }259 }
292 260
293 ///Calculates the number of bytes required to store a desired count261 ///Calculates the number of bytes required to store a desired count
294 /// of Ints262 /// of Ints
295 pub fn bytesRequired(int_count: usize) usize263 pub fn bytesRequired(int_count: usize) usize {
296 {
297 const total_bits = int_bits * int_count;264 const total_bits = int_bits * int_count;
298 const total_bytes = (total_bits + 7) / 8;265 const total_bytes = (total_bits + 7) / 8;
299 return total_bytes;266 return total_bytes;
300 }267 }
301 268
302 ///Initialize a packed slice using the memory at bytes, with int_count269 ///Initialize a packed slice using the memory at bytes, with int_count
303 /// elements. bytes must be large enough to accomodate the requested270 /// elements. bytes must be large enough to accomodate the requested
304 /// count.271 /// count.
305 pub fn init(bytes: []u8, int_count: usize) Self272 pub fn init(bytes: []u8, int_count: usize) Self {
306 {
307 debug.assert(bytes.len >= bytesRequired(int_count));273 debug.assert(bytes.len >= bytesRequired(int_count));
308 274
309 return Self275 return Self{
310 {
311 .bytes = bytes,276 .bytes = bytes,
312 .int_count = int_count,277 .int_count = int_count,
313 .bit_offset = 0,278 .bit_offset = 0,
314 };279 };
315 }280 }
316 281
317 ///Return the Int stored at index282 ///Return the Int stored at index
318 pub fn get(self: Self, index: usize) Int283 pub fn get(self: Self, index: usize) Int {
319 {
320 debug.assert(index < self.int_count);284 debug.assert(index < self.int_count);
321 return Io.get(self.bytes, index, self.bit_offset);285 return Io.get(self.bytes, index, self.bit_offset);
322 }286 }
323 287
324 ///Copy int into the array at index288 ///Copy int into the array at index
325 pub fn set(self: *Self, index: usize, int: Int) void289 pub fn set(self: *Self, index: usize, int: Int) void {
326 {
327 debug.assert(index < self.int_count);290 debug.assert(index < self.int_count);
328 return Io.set(self.bytes, index, self.bit_offset, int);291 return Io.set(self.bytes, index, self.bit_offset, int);
329 }292 }
330 293
331 ///Create a PackedIntSlice of this slice from given start to given end294 ///Create a PackedIntSlice of this slice from given start to given end
332 pub fn slice(self: Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian)295 pub fn slice(self: Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
333 {
334 debug.assert(start < self.int_count);296 debug.assert(start < self.int_count);
335 debug.assert(end <= self.int_count);297 debug.assert(end <= self.int_count);
336 return Io.slice(self.bytes, self.bit_offset, start, end);298 return Io.slice(self.bytes, self.bit_offset, start, end);
337 }299 }
338 300
339 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer.301 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer.
340 /// NewInt's bit width must fit evenly within this slice's Int's total bits.302 /// NewInt's bit width must fit evenly within this slice's Int's total bits.
341 pub fn sliceCast(self: Self, comptime NewInt: type) PackedIntSliceEndian(NewInt, endian)303 pub fn sliceCast(self: Self, comptime NewInt: type) PackedIntSliceEndian(NewInt, endian) {
342 {
343 return self.sliceCastEndian(NewInt, endian);304 return self.sliceCastEndian(NewInt, endian);
344 }305 }
345 306
346 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer307 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer
347 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within308 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within
348 /// this slice's Int's total bits.309 /// this slice's Int's total bits.
349 pub fn sliceCastEndian(self: Self, comptime NewInt: type, 310 pub fn sliceCastEndian(self: Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) {
350 comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian)
351 {
352 return Io.sliceCast(self.bytes, NewInt, new_endian, self.bit_offset, self.int_count);311 return Io.sliceCast(self.bytes, NewInt, new_endian, self.bit_offset, self.int_count);
353 }312 }
354 };313 };
355}314}
356315
357test "PackedIntArray"316test "PackedIntArray" {
358{
359 @setEvalBranchQuota(10000);317 @setEvalBranchQuota(10000);
360 const max_bits = 256;318 const max_bits = 256;
361 const int_count = 19;319 const int_count = 19;
362 320
363 comptime var bits = 0;321 comptime var bits = 0;
364 inline while(bits <= 256):(bits += 1)322 inline while (bits <= 256) : (bits += 1) {
365 {
366 //alternate unsigned and signed323 //alternate unsigned and signed
367 const even = bits % 2 == 0;324 const even = bits % 2 == 0;
368 const I = @IntType(even, bits);325 const I = @IntType(even, bits);
...@@ -370,100 +327,90 @@ test "PackedIntArray"...@@ -370,100 +327,90 @@ test "PackedIntArray"
370 const PackedArray = PackedIntArray(I, int_count);327 const PackedArray = PackedIntArray(I, int_count);
371 const expected_bytes = ((bits * int_count) + 7) / 8;328 const expected_bytes = ((bits * int_count) + 7) / 8;
372 testing.expect(@sizeOf(PackedArray) == expected_bytes);329 testing.expect(@sizeOf(PackedArray) == expected_bytes);
373 330
374 var data = PackedArray(undefined);331 var data = PackedArray(undefined);
375 332
376 //write values, counting up333 //write values, counting up
377 var i = usize(0);334 var i = usize(0);
378 var count = I(0);335 var count = I(0);
379 while(i < data.len()):(i += 1)336 while (i < data.len()) : (i += 1) {
380 {
381 data.set(i, count);337 data.set(i, count);
382 if(bits > 0) count +%= 1;338 if (bits > 0) count +%= 1;
383 }339 }
384 340
385 //read and verify values341 //read and verify values
386 i = 0;342 i = 0;
387 count = 0;343 count = 0;
388 while(i < data.len()):(i += 1)344 while (i < data.len()) : (i += 1) {
389 {
390 const val = data.get(i);345 const val = data.get(i);
391 testing.expect(val == count);346 testing.expect(val == count);
392 if(bits > 0) count +%= 1;347 if (bits > 0) count +%= 1;
393 }348 }
394 }349 }
395}350}
396351
397test "PackedIntArray init"352test "PackedIntArray init" {
398{
399 const PackedArray = PackedIntArray(u3, 8);353 const PackedArray = PackedIntArray(u3, 8);
400 var packed_array = PackedArray.init([]u3{0,1,2,3,4,5,6,7});354 var packed_array = PackedArray.init([]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });
401 var i = usize(0);355 var i = usize(0);
402 while(i < packed_array.len()):(i += 1) testing.expect(packed_array.get(i) == i);356 while (i < packed_array.len()) : (i += 1) testing.expect(packed_array.get(i) == i);
403}357}
404358
405test "PackedIntSlice"359test "PackedIntSlice" {
406{
407 @setEvalBranchQuota(10000);360 @setEvalBranchQuota(10000);
408 const max_bits = 256;361 const max_bits = 256;
409 const int_count = 19;362 const int_count = 19;
410 const total_bits = max_bits * int_count;363 const total_bits = max_bits * int_count;
411 const total_bytes = (total_bits + 7) / 8;364 const total_bytes = (total_bits + 7) / 8;
412 365
413 var buffer: [total_bytes]u8 = undefined;366 var buffer: [total_bytes]u8 = undefined;
414 367
415 comptime var bits = 0;368 comptime var bits = 0;
416 inline while(bits <= 256):(bits += 1)369 inline while (bits <= 256) : (bits += 1) {
417 {
418 //alternate unsigned and signed370 //alternate unsigned and signed
419 const even = bits % 2 == 0;371 const even = bits % 2 == 0;
420 const I = @IntType(even, bits);372 const I = @IntType(even, bits);
421 const P = PackedIntSlice(I);373 const P = PackedIntSlice(I);
422 374
423 var data = P.init(&buffer, int_count);375 var data = P.init(&buffer, int_count);
424 376
425 //write values, counting up377 //write values, counting up
426 var i = usize(0);378 var i = usize(0);
427 var count = I(0);379 var count = I(0);
428 while(i < data.len()):(i += 1)380 while (i < data.len()) : (i += 1) {
429 {
430 data.set(i, count);381 data.set(i, count);
431 if(bits > 0) count +%= 1;382 if (bits > 0) count +%= 1;
432 }383 }
433 384
434 //read and verify values385 //read and verify values
435 i = 0;386 i = 0;
436 count = 0;387 count = 0;
437 while(i < data.len()):(i += 1)388 while (i < data.len()) : (i += 1) {
438 {
439 const val = data.get(i);389 const val = data.get(i);
440 testing.expect(val == count);390 testing.expect(val == count);
441 if(bits > 0) count +%= 1;391 if (bits > 0) count +%= 1;
442 }392 }
443 }393 }
444}394}
445395
446test "PackedIntSlice of PackedInt(Array/Slice)"396test "PackedIntSlice of PackedInt(Array/Slice)" {
447{
448 const max_bits = 16;397 const max_bits = 16;
449 const int_count = 19;398 const int_count = 19;
450 399
451 comptime var bits = 0;400 comptime var bits = 0;
452 inline while(bits <= max_bits):(bits += 1)401 inline while (bits <= max_bits) : (bits += 1) {
453 {
454 const Int = @IntType(false, bits);402 const Int = @IntType(false, bits);
455 403
456 const PackedArray = PackedIntArray(Int, int_count);404 const PackedArray = PackedIntArray(Int, int_count);
457 var packed_array = PackedArray(undefined);405 var packed_array = PackedArray(undefined);
458 406
459 const limit = (1 << bits);407 const limit = (1 << bits);
460 408
461 var i = usize(0);409 var i = usize(0);
462 while(i < packed_array.len()):(i += 1)410 while (i < packed_array.len()) : (i += 1) {
463 {
464 packed_array.set(i, @intCast(Int, i % limit));411 packed_array.set(i, @intCast(Int, i % limit));
465 }412 }
466 413
467 //slice of array414 //slice of array
468 var packed_slice = packed_array.slice(2, 5);415 var packed_slice = packed_array.slice(2, 5);
469 testing.expect(packed_slice.len() == 3);416 testing.expect(packed_slice.len() == 3);
...@@ -475,10 +422,10 @@ test "PackedIntSlice of PackedInt(Array/Slice)"...@@ -475,10 +422,10 @@ test "PackedIntSlice of PackedInt(Array/Slice)"
475 testing.expect(packed_slice.get(2) == 4 % limit);422 testing.expect(packed_slice.get(2) == 4 % limit);
476 packed_slice.set(1, 7 % limit);423 packed_slice.set(1, 7 % limit);
477 testing.expect(packed_slice.get(1) == 7 % limit);424 testing.expect(packed_slice.get(1) == 7 % limit);
478 425
479 //write through slice426 //write through slice
480 testing.expect(packed_array.get(3) == 7 % limit);427 testing.expect(packed_array.get(3) == 7 % limit);
481 428
482 //slice of a slice429 //slice of a slice
483 const packed_slice_two = packed_slice.slice(0, 3);430 const packed_slice_two = packed_slice.slice(0, 3);
484 testing.expect(packed_slice_two.len() == 3);431 testing.expect(packed_slice_two.len() == 3);
...@@ -487,7 +434,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)"...@@ -487,7 +434,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)"
487 testing.expect(packed_slice_two.bytes.len == ps2_expected_bytes);434 testing.expect(packed_slice_two.bytes.len == ps2_expected_bytes);
488 testing.expect(packed_slice_two.get(1) == 7 % limit);435 testing.expect(packed_slice_two.get(1) == 7 % limit);
489 testing.expect(packed_slice_two.get(2) == 4 % limit);436 testing.expect(packed_slice_two.get(2) == 4 % limit);
490 437
491 //size one case438 //size one case
492 const packed_slice_three = packed_slice_two.slice(1, 2);439 const packed_slice_three = packed_slice_two.slice(1, 2);
493 testing.expect(packed_slice_three.len() == 1);440 testing.expect(packed_slice_three.len() == 1);
...@@ -495,12 +442,12 @@ test "PackedIntSlice of PackedInt(Array/Slice)"...@@ -495,12 +442,12 @@ test "PackedIntSlice of PackedInt(Array/Slice)"
495 const ps3_expected_bytes = (ps3_bit_count + 7) / 8;442 const ps3_expected_bytes = (ps3_bit_count + 7) / 8;
496 testing.expect(packed_slice_three.bytes.len == ps3_expected_bytes);443 testing.expect(packed_slice_three.bytes.len == ps3_expected_bytes);
497 testing.expect(packed_slice_three.get(0) == 7 % limit);444 testing.expect(packed_slice_three.get(0) == 7 % limit);
498 445
499 //empty slice case446 //empty slice case
500 const packed_slice_empty = packed_slice.slice(0, 0);447 const packed_slice_empty = packed_slice.slice(0, 0);
501 testing.expect(packed_slice_empty.len() == 0);448 testing.expect(packed_slice_empty.len() == 0);
502 testing.expect(packed_slice_empty.bytes.len == 0);449 testing.expect(packed_slice_empty.bytes.len == 0);
503 450
504 //slicing at byte boundaries451 //slicing at byte boundaries
505 const packed_slice_edge = packed_array.slice(8, 16);452 const packed_slice_edge = packed_array.slice(8, 16);
506 testing.expect(packed_slice_edge.len() == 8);453 testing.expect(packed_slice_edge.len() == 8);
...@@ -509,135 +456,134 @@ test "PackedIntSlice of PackedInt(Array/Slice)"...@@ -509,135 +456,134 @@ test "PackedIntSlice of PackedInt(Array/Slice)"
509 testing.expect(packed_slice_edge.bytes.len == pse_expected_bytes);456 testing.expect(packed_slice_edge.bytes.len == pse_expected_bytes);
510 testing.expect(packed_slice_edge.bit_offset == 0);457 testing.expect(packed_slice_edge.bit_offset == 0);
511 }458 }
512
513}459}
514460
515test "PackedIntSlice accumulating bit offsets"461test "PackedIntSlice accumulating bit offsets" {
516{
517 //bit_offset is u3, so standard debugging asserts should catch462 //bit_offset is u3, so standard debugging asserts should catch
518 // anything463 // anything
519 {464 {
520 const PackedArray = PackedIntArray(u3, 16);465 const PackedArray = PackedIntArray(u3, 16);
521 var packed_array = PackedArray(undefined);466 var packed_array = PackedArray(undefined);
522 467
523 var packed_slice = packed_array.slice(0, packed_array.len());468 var packed_slice = packed_array.slice(0, packed_array.len());
524 var i = usize(0);469 var i = usize(0);
525 while(i < packed_array.len() - 1):(i += 1)470 while (i < packed_array.len() - 1) : (i += 1) {
526 {
527
528 packed_slice = packed_slice.slice(1, packed_slice.len());471 packed_slice = packed_slice.slice(1, packed_slice.len());
529 }472 }
530 }473 }
531 {474 {
532 const PackedArray = PackedIntArray(u11, 88);475 const PackedArray = PackedIntArray(u11, 88);
533 var packed_array = PackedArray(undefined);476 var packed_array = PackedArray(undefined);
534 477
535 var packed_slice = packed_array.slice(0, packed_array.len());478 var packed_slice = packed_array.slice(0, packed_array.len());
536 var i = usize(0);479 var i = usize(0);
537 while(i < packed_array.len() - 1):(i += 1)480 while (i < packed_array.len() - 1) : (i += 1) {
538 {
539 packed_slice = packed_slice.slice(1, packed_slice.len());481 packed_slice = packed_slice.slice(1, packed_slice.len());
540 }482 }
541 }483 }
542
543}484}
544485
545//@NOTE: As I do not have a big endian system to test this on,486//@NOTE: As I do not have a big endian system to test this on,
546// big endian values were not tested487// big endian values were not tested
547test "PackedInt(Array/Slice) sliceCast"488test "PackedInt(Array/Slice) sliceCast" {
548{
549 const PackedArray = PackedIntArray(u1, 16);489 const PackedArray = PackedIntArray(u1, 16);
550 var packed_array = PackedArray.init([]u1{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1});490 var packed_array = PackedArray.init([]u1{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 });
551 const packed_slice_cast_2 = packed_array.sliceCast(u2);491 const packed_slice_cast_2 = packed_array.sliceCast(u2);
552 const packed_slice_cast_4 = packed_slice_cast_2.sliceCast(u4);492 const packed_slice_cast_4 = packed_slice_cast_2.sliceCast(u4);
553 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);493 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);
554 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);494 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);
555 495
556 var i = usize(0);496 var i = usize(0);
557 while(i < packed_slice_cast_2.len()):(i += 1)497 while (i < packed_slice_cast_2.len()) : (i += 1) {
558 {498 const val = switch (builtin.endian) {
559 const val = switch(builtin.endian)
560 {
561 .Big => 0b01,499 .Big => 0b01,
562 .Little => 0b10,500 .Little => 0b10,
563 };501 };
564 testing.expect(packed_slice_cast_2.get(i) == val);502 testing.expect(packed_slice_cast_2.get(i) == val);
565 }503 }
566 i = 0;504 i = 0;
567 while(i < packed_slice_cast_4.len()):(i += 1)505 while (i < packed_slice_cast_4.len()) : (i += 1) {
568 {506 const val = switch (builtin.endian) {
569 const val = switch(builtin.endian)
570 {
571 .Big => 0b0101,507 .Big => 0b0101,
572 .Little => 0b1010,508 .Little => 0b1010,
573 };509 };
574 testing.expect(packed_slice_cast_4.get(i) == val);510 testing.expect(packed_slice_cast_4.get(i) == val);
575 }511 }
576 i = 0;512 i = 0;
577 while(i < packed_slice_cast_9.len()):(i += 1)513 while (i < packed_slice_cast_9.len()) : (i += 1) {
578 {
579 const val = 0b010101010;514 const val = 0b010101010;
580 testing.expect(packed_slice_cast_9.get(i) == val);515 testing.expect(packed_slice_cast_9.get(i) == val);
581 packed_slice_cast_9.set(i, 0b111000111);516 packed_slice_cast_9.set(i, 0b111000111);
582 }517 }
583 i = 0;518 i = 0;
584 while(i < packed_slice_cast_3.len()):(i += 1)519 while (i < packed_slice_cast_3.len()) : (i += 1) {
585 {520 const val = switch (builtin.endian) {
586 const val = switch(builtin.endian)521 .Big => if (i % 2 == 0) u3(0b111) else u3(0b000),
587 {522 .Little => if (i % 2 == 0) u3(0b111) else u3(0b000),
588 .Big => if(i % 2 == 0) u3(0b111) else u3(0b000),
589 .Little => if(i % 2 == 0) u3(0b111) else u3(0b000),
590 };523 };
591 testing.expect(packed_slice_cast_3.get(i) == val);524 testing.expect(packed_slice_cast_3.get(i) == val);
592 }525 }
593}526}
594527
595test "PackedInt(Array/Slice)Endian"528test "PackedInt(Array/Slice)Endian" {
596{
597 {529 {
598 const PackedArrayBe = PackedIntArrayEndian(u4, .Big, 8);530 const PackedArrayBe = PackedIntArrayEndian(u4, .Big, 8);
599 var packed_array_be = PackedArrayBe.init([]u4{0,1,2,3,4,5,6,7,});531 var packed_array_be = PackedArrayBe.init([]u4{
532 0,
533 1,
534 2,
535 3,
536 4,
537 5,
538 6,
539 7,
540 });
600 testing.expect(packed_array_be.bytes[0] == 0b00000001);541 testing.expect(packed_array_be.bytes[0] == 0b00000001);
601 testing.expect(packed_array_be.bytes[1] == 0b00100011);542 testing.expect(packed_array_be.bytes[1] == 0b00100011);
602 543
603 var i = usize(0);544 var i = usize(0);
604 while(i < packed_array_be.len()):(i += 1)545 while (i < packed_array_be.len()) : (i += 1) {
605 {
606 testing.expect(packed_array_be.get(i) == i);546 testing.expect(packed_array_be.get(i) == i);
607 }547 }
608 548
609 var packed_slice_le = packed_array_be.sliceCastEndian(u4, .Little);549 var packed_slice_le = packed_array_be.sliceCastEndian(u4, .Little);
610 i = 0;550 i = 0;
611 while(i < packed_slice_le.len()):(i += 1)551 while (i < packed_slice_le.len()) : (i += 1) {
612 {552 const val = if (i % 2 == 0) i + 1 else i - 1;
613 const val = if(i % 2 == 0) i + 1 else i - 1;
614 testing.expect(packed_slice_le.get(i) == val);553 testing.expect(packed_slice_le.get(i) == val);
615 }554 }
616 555
617 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u4, .Little);556 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u4, .Little);
618 i = 0;557 i = 0;
619 while(i < packed_slice_le_shift.len()):(i += 1)558 while (i < packed_slice_le_shift.len()) : (i += 1) {
620 {559 const val = if (i % 2 == 0) i else i + 2;
621 const val = if(i % 2 == 0) i else i + 2;
622 testing.expect(packed_slice_le_shift.get(i) == val);560 testing.expect(packed_slice_le_shift.get(i) == val);
623 }561 }
624 }562 }
625 563
626 {564 {
627 const PackedArrayBe = PackedIntArrayEndian(u11, .Big, 8);565 const PackedArrayBe = PackedIntArrayEndian(u11, .Big, 8);
628 var packed_array_be = PackedArrayBe.init([]u11{0,1,2,3,4,5,6,7,});566 var packed_array_be = PackedArrayBe.init([]u11{
567 0,
568 1,
569 2,
570 3,
571 4,
572 5,
573 6,
574 7,
575 });
629 testing.expect(packed_array_be.bytes[0] == 0b00000000);576 testing.expect(packed_array_be.bytes[0] == 0b00000000);
630 testing.expect(packed_array_be.bytes[1] == 0b00000000);577 testing.expect(packed_array_be.bytes[1] == 0b00000000);
631 testing.expect(packed_array_be.bytes[2] == 0b00000100);578 testing.expect(packed_array_be.bytes[2] == 0b00000100);
632 testing.expect(packed_array_be.bytes[3] == 0b00000001);579 testing.expect(packed_array_be.bytes[3] == 0b00000001);
633 testing.expect(packed_array_be.bytes[4] == 0b00000000);580 testing.expect(packed_array_be.bytes[4] == 0b00000000);
634 581
635 var i = usize(0);582 var i = usize(0);
636 while(i < packed_array_be.len()):(i += 1)583 while (i < packed_array_be.len()) : (i += 1) {
637 {
638 testing.expect(packed_array_be.get(i) == i);584 testing.expect(packed_array_be.get(i) == i);
639 }585 }
640 586
641 var packed_slice_le = packed_array_be.sliceCastEndian(u11, .Little);587 var packed_slice_le = packed_array_be.sliceCastEndian(u11, .Little);
642 testing.expect(packed_slice_le.get(0) == 0b00000000000);588 testing.expect(packed_slice_le.get(0) == 0b00000000000);
643 testing.expect(packed_slice_le.get(1) == 0b00010000000);589 testing.expect(packed_slice_le.get(1) == 0b00010000000);
...@@ -647,8 +593,7 @@ test "PackedInt(Array/Slice)Endian"...@@ -647,8 +593,7 @@ test "PackedInt(Array/Slice)Endian"
647 testing.expect(packed_slice_le.get(5) == 0b00000000010);593 testing.expect(packed_slice_le.get(5) == 0b00000000010);
648 testing.expect(packed_slice_le.get(6) == 0b10000010000);594 testing.expect(packed_slice_le.get(6) == 0b10000010000);
649 testing.expect(packed_slice_le.get(7) == 0b00000111001);595 testing.expect(packed_slice_le.get(7) == 0b00000111001);
650 596
651
652 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u11, .Little);597 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u11, .Little);
653 testing.expect(packed_slice_le_shift.get(0) == 0b00010000000);598 testing.expect(packed_slice_le_shift.get(0) == 0b00010000000);
654 testing.expect(packed_slice_le_shift.get(1) == 0b00000000100);599 testing.expect(packed_slice_le_shift.get(1) == 0b00000000100);
...@@ -666,44 +611,39 @@ test "PackedInt(Array/Slice)Endian"...@@ -666,44 +611,39 @@ test "PackedInt(Array/Slice)Endian"
666// and reading the last element. The assumption is that the page611// and reading the last element. The assumption is that the page
667// after this one is not mapped and will cause a segfault if we612// after this one is not mapped and will cause a segfault if we
668// don't account for the bounds.613// don't account for the bounds.
669test "PackedIntArray at end of available memory"614test "PackedIntArray at end of available memory" {
670{615 switch (builtin.os) {
671 switch(builtin.os)
672 {
673 .linux, .macosx, .ios, .freebsd, .netbsd => {},616 .linux, .macosx, .ios, .freebsd, .netbsd => {},
674 else => return,617 else => return,
675 }618 }
676 const PackedArray = PackedIntArray(u3, 8);619 const PackedArray = PackedIntArray(u3, 8);
677 620
678 const Padded = struct621 const Padded = struct {
679 {
680 _: [std.os.page_size - @sizeOf(PackedArray)]u8,622 _: [std.os.page_size - @sizeOf(PackedArray)]u8,
681 p: PackedArray,623 p: PackedArray,
682 };624 };
683 625
684 var da = std.heap.DirectAllocator.init();626 var da = std.heap.DirectAllocator.init();
685 const allocator = &da.allocator;627 const allocator = &da.allocator;
686 628
687 var pad = try allocator.create(Padded);629 var pad = try allocator.create(Padded);
688 defer allocator.destroy(pad);630 defer allocator.destroy(pad);
689 pad.p.set(7, std.math.maxInt(u3));631 pad.p.set(7, std.math.maxInt(u3));
690}632}
691633
692test "PackedIntSlice at end of available memory"634test "PackedIntSlice at end of available memory" {
693{635 switch (builtin.os) {
694 switch(builtin.os)
695 {
696 .linux, .macosx, .ios, .freebsd, .netbsd => {},636 .linux, .macosx, .ios, .freebsd, .netbsd => {},
697 else => return,637 else => return,
698 }638 }
699 const PackedSlice = PackedIntSlice(u11);639 const PackedSlice = PackedIntSlice(u11);
700 640
701 var da = std.heap.DirectAllocator.init();641 var da = std.heap.DirectAllocator.init();
702 const allocator = &da.allocator;642 const allocator = &da.allocator;
703 643
704 var page = try allocator.alloc(u8, std.os.page_size);644 var page = try allocator.alloc(u8, std.os.page_size);
705 defer allocator.free(page);645 defer allocator.free(page);
706 646
707 var p = PackedSlice.init(page[std.os.page_size - 2..], 1);647 var p = PackedSlice.init(page[std.os.page_size - 2 ..], 1);
708 p.set(0, std.math.maxInt(u11));648 p.set(0, std.math.maxInt(u11));
709}
\ No newline at end of file
649}