@@ -106,26 +106,38 @@ impl AsciiSet {
106
106
mask[ byte as usize / BITS_PER_CHUNK ] &= !( 1 << ( byte as usize % BITS_PER_CHUNK ) ) ;
107
107
AsciiSet { mask }
108
108
}
109
+
110
+ /// Return the union of two sets.
111
+ pub const fn union ( & self , other : & Self ) -> Self {
112
+ let mask = [
113
+ self . mask [ 0 ] | other. mask [ 0 ] ,
114
+ self . mask [ 1 ] | other. mask [ 1 ] ,
115
+ self . mask [ 2 ] | other. mask [ 2 ] ,
116
+ self . mask [ 3 ] | other. mask [ 3 ] ,
117
+ ] ;
118
+ AsciiSet { mask }
119
+ }
120
+
121
+ /// Return the negation of the set.
122
+ pub const fn complement ( & self ) -> Self {
123
+ let mask = [ !self . mask [ 0 ] , !self . mask [ 1 ] , !self . mask [ 2 ] , !self . mask [ 3 ] ] ;
124
+ AsciiSet { mask }
125
+ }
109
126
}
110
127
111
128
impl ops:: Add for AsciiSet {
112
129
type Output = Self ;
113
130
114
131
fn add ( self , other : Self ) -> Self {
115
- let mut mask = self . mask . clone ( ) ;
116
- for i in 0 ..mask. len ( ) {
117
- mask[ i] |= other. mask [ i] ;
118
- }
119
- AsciiSet { mask }
132
+ self . union ( & other)
120
133
}
121
134
}
122
135
123
136
impl ops:: Not for AsciiSet {
124
137
type Output = Self ;
125
138
126
139
fn not ( self ) -> Self {
127
- let mask = self . mask . map ( |chunk| !chunk) ;
128
- AsciiSet { mask }
140
+ self . complement ( )
129
141
}
130
142
}
131
143
@@ -511,18 +523,40 @@ mod tests {
511
523
use super :: * ;
512
524
513
525
#[ test]
514
- fn add ( ) {
526
+ fn add_op ( ) {
515
527
let left = AsciiSet :: EMPTY . add ( b'A' ) ;
516
528
let right = AsciiSet :: EMPTY . add ( b'B' ) ;
517
529
let expected = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
518
530
assert_eq ! ( left + right, expected) ;
519
531
}
520
532
521
533
#[ test]
522
- fn not ( ) {
534
+ fn not_op ( ) {
523
535
let set = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
524
536
let not_set = !set;
525
537
assert ! ( !not_set. contains( b'A' ) ) ;
526
538
assert ! ( not_set. contains( b'C' ) ) ;
527
539
}
540
+
541
+ /// This test ensures that we can get the union of two sets as a constant value, which is
542
+ /// useful for defining sets in a modular way.
543
+ #[ test]
544
+ fn union ( ) {
545
+ const A : AsciiSet = AsciiSet :: EMPTY . add ( b'A' ) ;
546
+ const B : AsciiSet = AsciiSet :: EMPTY . add ( b'B' ) ;
547
+ const UNION : AsciiSet = A . union ( & B ) ;
548
+ const EXPECTED : AsciiSet = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
549
+ assert_eq ! ( UNION , EXPECTED ) ;
550
+ }
551
+
552
+ /// This test ensures that we can get the complement of a set as a constant value, which is
553
+ /// useful for defining sets in a modular way.
554
+ #[ test]
555
+ fn complement ( ) {
556
+ const BOTH : AsciiSet = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
557
+ const COMPLEMENT : AsciiSet = BOTH . complement ( ) ;
558
+ assert ! ( !COMPLEMENT . contains( b'A' ) ) ;
559
+ assert ! ( !COMPLEMENT . contains( b'B' ) ) ;
560
+ assert ! ( COMPLEMENT . contains( b'C' ) ) ;
561
+ }
528
562
}
0 commit comments