authorgravatar for pyrogx1133@gmail.comRonald Chen <pyrogx1133@gmail.com> 2022-12-08 11:22:10-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-11 03:46:08-05:00
loga792e13fc08982e79cb1b08d14322be76b8cf77a
treeecf5312ccf55affd6cd6bfbf10962f34d62ed605
parent78ea270cc63197e4af312463d4f0c5490285d6ba

std: added pure fns to EnumSet


1 files changed, 129 insertions(+), 1 deletions(-)

lib/std/enums.zig+129-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1//! This module contains utilities and data structures for working with enums.1//! This module contains utilities and data structures for working with enums.
22
3const std = @import("std.zig");3const std = @import("std");
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const testing = std.testing;5const testing = std.testing;
6const EnumField = std.builtin.Type.EnumField;6const EnumField = std.builtin.Type.EnumField;
...@@ -369,6 +369,11 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {...@@ -369,6 +369,11 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
369369
370 bits: BitSet = BitSet.initEmpty(),370 bits: BitSet = BitSet.initEmpty(),
371371
372 /// Returns a set containing no keys.
373 pub fn initEmpty() Self {
374 return .{ .bits = BitSet.initEmpty() };
375 }
376
372 /// Returns a set containing all possible keys.377 /// Returns a set containing all possible keys.
373 pub fn initFull() Self {378 pub fn initFull() Self {
374 return .{ .bits = BitSet.initFull() };379 return .{ .bits = BitSet.initFull() };
...@@ -425,6 +430,54 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {...@@ -425,6 +430,54 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
425 self.bits.setIntersection(other.bits);430 self.bits.setIntersection(other.bits);
426 }431 }
427432
433 /// Returns true iff both sets have the same keys.
434 pub fn eql(self: Self, other: Self) bool {
435 return self.bits.eql(other.bits);
436 }
437
438 /// Returns true iff all the keys in this set are
439 /// in the other set. The other set may have keys
440 /// not found in this set.
441 pub fn subsetOf(self: Self, other: Self) bool {
442 return self.bits.subsetOf(other.bits);
443 }
444
445 /// Returns true iff this set contains all the keys
446 /// in the other set. This set may have keys not
447 /// found in the other set.
448 pub fn supersetOf(self: Self, other: Self) bool {
449 return self.bits.supersetOf(other.bits);
450 }
451
452 /// Returns a set with all the keys not in this set.
453 pub fn complement(self: Self) Self {
454 return .{ .bits = self.bits.complement() };
455 }
456
457 /// Returns a set with keys that are in either this
458 /// set or the other set.
459 pub fn unionWith(self: Self, other: Self) Self {
460 return .{ .bits = self.bits.unionWith(other.bits) };
461 }
462
463 /// Returns a set with keys that are in both this
464 /// set and the other set.
465 pub fn intersectWith(self: Self, other: Self) Self {
466 return .{ .bits = self.bits.intersectWith(other.bits) };
467 }
468
469 /// Returns a set with keys that are in either this
470 /// set or the other set, but not both.
471 pub fn xorWith(self: Self, other: Self) Self {
472 return .{ .bits = self.bits.xorWith(other.bits) };
473 }
474
475 /// Returns a set with keys that are in this set
476 /// except for keys in the other set.
477 pub fn differenceWith(self: Self, other: Self) Self {
478 return .{ .bits = self.bits.differenceWith(other.bits) };
479 }
480
428 /// Returns an iterator over this set, which iterates in481 /// Returns an iterator over this set, which iterates in
429 /// index order. Modifications to the set during iteration482 /// index order. Modifications to the set during iteration
430 /// may or may not be observed by the iterator, but will483 /// may or may not be observed by the iterator, but will
...@@ -446,6 +499,81 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {...@@ -446,6 +499,81 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
446 };499 };
447}500}
448501
502test "pure EnumSet fns" {
503 const Suit = enum { spades, hearts, clubs, diamonds };
504
505 const empty = EnumSet(Suit).initEmpty();
506 const full = EnumSet(Suit).initFull();
507
508 const black = black: {
509 var set = EnumSet(Suit).initEmpty();
510 set.insert(.spades);
511 set.insert(.clubs);
512 break :black set;
513 };
514
515 const red = red: {
516 var set = EnumSet(Suit).initEmpty();
517 set.insert(.hearts);
518 set.insert(.diamonds);
519 break :red set;
520 };
521
522 try testing.expect(empty.eql(empty));
523 try testing.expect(full.eql(full));
524 try testing.expect(!empty.eql(full));
525 try testing.expect(!full.eql(empty));
526 try testing.expect(!empty.eql(black));
527 try testing.expect(!full.eql(red));
528 try testing.expect(!red.eql(empty));
529 try testing.expect(!black.eql(full));
530
531 try testing.expect(empty.subsetOf(empty));
532 try testing.expect(empty.subsetOf(full));
533 try testing.expect(full.subsetOf(full));
534 try testing.expect(!black.subsetOf(red));
535 try testing.expect(!red.subsetOf(black));
536
537 try testing.expect(full.supersetOf(full));
538 try testing.expect(full.supersetOf(empty));
539 try testing.expect(empty.supersetOf(empty));
540 try testing.expect(!black.supersetOf(red));
541 try testing.expect(!red.supersetOf(black));
542
543 try testing.expect(empty.complement().eql(full));
544 try testing.expect(full.complement().eql(empty));
545 try testing.expect(black.complement().eql(red));
546 try testing.expect(red.complement().eql(black));
547
548 try testing.expect(empty.unionWith(empty).eql(empty));
549 try testing.expect(empty.unionWith(full).eql(full));
550 try testing.expect(full.unionWith(full).eql(full));
551 try testing.expect(full.unionWith(empty).eql(full));
552 try testing.expect(black.unionWith(red).eql(full));
553 try testing.expect(red.unionWith(black).eql(full));
554
555 try testing.expect(empty.intersectWith(empty).eql(empty));
556 try testing.expect(empty.intersectWith(full).eql(empty));
557 try testing.expect(full.intersectWith(full).eql(full));
558 try testing.expect(full.intersectWith(empty).eql(empty));
559 try testing.expect(black.intersectWith(red).eql(empty));
560 try testing.expect(red.intersectWith(black).eql(empty));
561
562 try testing.expect(empty.xorWith(empty).eql(empty));
563 try testing.expect(empty.xorWith(full).eql(full));
564 try testing.expect(full.xorWith(full).eql(empty));
565 try testing.expect(full.xorWith(empty).eql(full));
566 try testing.expect(black.xorWith(red).eql(full));
567 try testing.expect(red.xorWith(black).eql(full));
568
569 try testing.expect(empty.differenceWith(empty).eql(empty));
570 try testing.expect(empty.differenceWith(full).eql(empty));
571 try testing.expect(full.differenceWith(full).eql(empty));
572 try testing.expect(full.differenceWith(empty).eql(full));
573 try testing.expect(full.differenceWith(red).eql(black));
574 try testing.expect(full.differenceWith(black).eql(red));
575}
576
449/// A map from keys to values, using an index lookup. Uses a577/// A map from keys to values, using an index lookup. Uses a
450/// bitfield to track presence and a dense array of values.578/// bitfield to track presence and a dense array of values.
451/// This type does no allocation and can be copied by value.579/// This type does no allocation and can be copied by value.