@@ -106,26 +106,38 @@ impl AsciiSet {
106106 mask[ byte as usize / BITS_PER_CHUNK ] &= !( 1 << ( byte as usize % BITS_PER_CHUNK ) ) ;
107107 AsciiSet { mask }
108108 }
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+ }
109126}
110127
111128impl ops:: Add for AsciiSet {
112129 type Output = Self ;
113130
114131 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)
120133 }
121134}
122135
123136impl ops:: Not for AsciiSet {
124137 type Output = Self ;
125138
126139 fn not ( self ) -> Self {
127- let mask = self . mask . map ( |chunk| !chunk) ;
128- AsciiSet { mask }
140+ self . complement ( )
129141 }
130142}
131143
@@ -511,18 +523,40 @@ mod tests {
511523 use super :: * ;
512524
513525 #[ test]
514- fn add ( ) {
526+ fn add_op ( ) {
515527 let left = AsciiSet :: EMPTY . add ( b'A' ) ;
516528 let right = AsciiSet :: EMPTY . add ( b'B' ) ;
517529 let expected = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
518530 assert_eq ! ( left + right, expected) ;
519531 }
520532
521533 #[ test]
522- fn not ( ) {
534+ fn not_op ( ) {
523535 let set = AsciiSet :: EMPTY . add ( b'A' ) . add ( b'B' ) ;
524536 let not_set = !set;
525537 assert ! ( !not_set. contains( b'A' ) ) ;
526538 assert ! ( not_set. contains( b'C' ) ) ;
527539 }
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+ }
528562}
0 commit comments