authorgravatar for git@zander.xyzZander Khan <git@zander.xyz> 2021-01-16 18:06:44+00:00
committergravatar for git@zander.xyzZander Khan <git@zander.xyz> 2021-01-16 18:06:44+00:00
log4d098034141d1f6ea5874d147227979af8aaae3c
treec69665d0501f239907b34ad604c977c1d2a60899
parenta162a2194744ed9d9c095f0160e463a7a1b4e36c

Fix edge cases in fromOwnedSlice


2 files changed, 50 insertions(+), 4 deletions(-)

lib/std/priority_dequeue.zig+27-4
...@@ -349,19 +349,22 @@ pub fn PriorityDequeue(comptime T: type) type {...@@ -349,19 +349,22 @@ pub fn PriorityDequeue(comptime T: type) type {
349 /// allocated with `allocator`.349 /// allocated with `allocator`.
350 /// De-initialize with `deinit`.350 /// De-initialize with `deinit`.
351 pub fn fromOwnedSlice(allocator: *Allocator, lessThanFn: fn (T, T) bool, items: []T) Self {351 pub fn fromOwnedSlice(allocator: *Allocator, lessThanFn: fn (T, T) bool, items: []T) Self {
352 var dequeue = Self{352 var queue = Self{
353 .items = items,353 .items = items,
354 .len = items.len,354 .len = items.len,
355 .allocator = allocator,355 .allocator = allocator,
356 .lessThanFn = lessThanFn,356 .lessThanFn = lessThanFn,
357 };357 };
358 const half = (dequeue.len >> 1) - 1;358
359 if (queue.len <= 1) return queue;
360
361 const half = (queue.len >> 1) - 1;
359 var i: usize = 0;362 var i: usize = 0;
360 while (i <= half) : (i += 1) {363 while (i <= half) : (i += 1) {
361 const index = half - i;364 const index = half - i;
362 dequeue.siftDown(index);365 queue.siftDown(index);
363 }366 }
364 return dequeue;367 return queue;
365 }368 }
366369
367 pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {370 pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
...@@ -646,6 +649,26 @@ test "std.PriorityDequeue: addSlice max" {...@@ -646,6 +649,26 @@ test "std.PriorityDequeue: addSlice max" {
646 }649 }
647}650}
648651
652test "std.PriorityDequeue: fromOwnedSlice trivial case 0" {
653 const items = [0]u32{};
654 const heap_items = try testing.allocator.dupe(u32, &items);
655 var heap = Heap.fromOwnedSlice(testing.allocator, lessThanComparison, heap_items[0..]);
656 defer heap.deinit();
657 expectEqual(@as(usize, 0), heap.len);
658 expect(heap.removeMinOrNull() == null);
659}
660
661test "std.PriorityDequeue: fromOwnedSlice trivial case 1" {
662 const items = [1]u32{1};
663 const heap_items = try testing.allocator.dupe(u32, &items);
664 var heap = Heap.fromOwnedSlice(testing.allocator, lessThanComparison, heap_items[0..]);
665 defer heap.deinit();
666
667 expectEqual(@as(usize, 1), heap.len);
668 expectEqual(items[0], heap.removeMin());
669 expect(heap.removeMinOrNull() == null);
670}
671
649test "std.PriorityDequeue: fromOwnedSlice" {672test "std.PriorityDequeue: fromOwnedSlice" {
650 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };673 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
651 const heap_items = try testing.allocator.dupe(u32, items[0..]);674 const heap_items = try testing.allocator.dupe(u32, items[0..]);
lib/std/priority_queue.zig+23
...@@ -166,6 +166,9 @@ pub fn PriorityQueue(comptime T: type) type {...@@ -166,6 +166,9 @@ pub fn PriorityQueue(comptime T: type) type {
166 .allocator = allocator,166 .allocator = allocator,
167 .compareFn = compareFn,167 .compareFn = compareFn,
168 };168 };
169
170 if (queue.len <= 1) return queue;
171
169 const half = (queue.len >> 1) - 1;172 const half = (queue.len >> 1) - 1;
170 var i: usize = 0;173 var i: usize = 0;
171 while (i <= half) : (i += 1) {174 while (i <= half) : (i += 1) {
...@@ -352,6 +355,26 @@ test "std.PriorityQueue: addSlice" {...@@ -352,6 +355,26 @@ test "std.PriorityQueue: addSlice" {
352 }355 }
353}356}
354357
358test "std.PriorityQueue: fromOwnedSlice trivial case 0" {
359 const items = [0]u32{};
360 const queue_items = try testing.allocator.dupe(u32, &items);
361 var queue = PQ.fromOwnedSlice(testing.allocator, lessThan, queue_items[0..]);
362 defer queue.deinit();
363 expectEqual(@as(usize, 0), queue.len);
364 expect(queue.removeOrNull() == null);
365}
366
367test "std.PriorityQueue: fromOwnedSlice trivial case 1" {
368 const items = [1]u32{1};
369 const queue_items = try testing.allocator.dupe(u32, &items);
370 var queue = PQ.fromOwnedSlice(testing.allocator, lessThan, queue_items[0..]);
371 defer queue.deinit();
372
373 expectEqual(@as(usize, 1), queue.len);
374 expectEqual(items[0], queue.remove());
375 expect(queue.removeOrNull() == null);
376}
377
355test "std.PriorityQueue: fromOwnedSlice" {378test "std.PriorityQueue: fromOwnedSlice" {
356 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };379 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
357 const heap_items = try testing.allocator.dupe(u32, items[0..]);380 const heap_items = try testing.allocator.dupe(u32, items[0..]);