1
1
//! This module contains utilities and data structures for working with enums.
2
2
3
- const std = @import ("std.zig " );
3
+ const std = @import ("std" );
4
4
const assert = std .debug .assert ;
5
5
const testing = std .testing ;
6
6
const EnumField = std .builtin .Type .EnumField ;
@@ -369,6 +369,11 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
369
369
370
370
bits : BitSet = BitSet .initEmpty (),
371
371
372
+ /// Returns a set containing no keys.
373
+ pub fn initEmpty () Self {
374
+ return .{ .bits = BitSet .initEmpty () };
375
+ }
376
+
372
377
/// Returns a set containing all possible keys.
373
378
pub fn initFull () Self {
374
379
return .{ .bits = BitSet .initFull () };
@@ -425,6 +430,54 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
425
430
self .bits .setIntersection (other .bits );
426
431
}
427
432
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
481
/// Returns an iterator over this set, which iterates in
429
482
/// index order. Modifications to the set during iteration
430
483
/// 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
499
};
447
500
}
448
501
502
+ test "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
577
/// A map from keys to values, using an index lookup. Uses a
450
578
/// bitfield to track presence and a dense array of values.
451
579
/// This type does no allocation and can be copied by value.
0 commit comments