@@ -25,17 +25,25 @@ class Controls {
2525 /**
2626 * @param {!int } inclusionMask.
2727 * @param {!int } desiredValueMask
28+ * @param {!int=0 } parityMask
2829 * @property {!int } inclusionMask.
2930 * @property {!int } desiredValueMask
3031 */
31- constructor ( inclusionMask , desiredValueMask ) {
32+ constructor ( inclusionMask , desiredValueMask , parityMask = 0 ) {
3233 if ( ( desiredValueMask & ~ inclusionMask ) !== 0 ) {
3334 throw new DetailedError ( "Desired un-included bits" , { inclusionMask, desiredValueMask} ) ;
3435 }
36+ if ( parityMask !== 0 && Util . popcnt ( inclusionMask & parityMask ) !== 1 ) {
37+ throw new DetailedError ( "Exactly one parity bit must be in the inclusion mask" ,
38+ { inclusionMask, parityMask} ) ;
39+ }
40+
3541 /** @type {!int } */
3642 this . inclusionMask = inclusionMask ;
3743 /** @type {!int } */
3844 this . desiredValueMask = desiredValueMask ;
45+ /** @type {!int } */
46+ this . parityMask = parityMask ;
3947 }
4048
4149 /**
@@ -57,7 +65,8 @@ class Controls {
5765 isEqualTo ( other ) {
5866 return other instanceof Controls &&
5967 this . inclusionMask === other . inclusionMask &&
60- this . desiredValueMask === other . desiredValueMask ;
68+ this . desiredValueMask === other . desiredValueMask &&
69+ this . parityMask === other . parityMask ;
6170 }
6271
6372 /**
@@ -68,12 +77,20 @@ class Controls {
6877 return "No Controls" ;
6978 }
7079
71- return "Controls: ...__" + Seq . naturals ( ) .
72- takeWhile ( i => ( 1 << i ) <= this . inclusionMask ) .
73- map ( this . desiredValueFor . bind ( this ) ) .
80+ let range = Seq . naturals ( ) . takeWhile ( i => ( 1 << i ) <= ( this . inclusionMask | this . parityMask ) ) ;
81+ let result = "Controls: ...__" + range .
82+ map ( e => this . desiredValueFor ( e ) ) .
7483 map ( e => e === undefined ? "_" : e ? "1" : "0" ) .
7584 reverse ( ) .
7685 join ( "" ) ;
86+ if ( this . parityMask !== 0 ) {
87+ result += "\n parity: ...__" + range .
88+ map ( e => this . parityMask & ( 1 << e ) ) .
89+ map ( e => e ? "1" : "_" ) .
90+ reverse ( ) .
91+ join ( "" )
92+ }
93+ return result ;
7794 }
7895
7996 /**
@@ -113,9 +130,13 @@ class Controls {
113130 if ( ( other . desiredValueMask & this . inclusionMask ) !== ( this . desiredValueMask & other . inclusionMask ) ) {
114131 throw new DetailedError ( "Contradictory controls." , { "this" : this , other} )
115132 }
133+ if ( ( other . parityMask & this . inclusionMask ) !== 0 || ( this . parityMask & other . inclusionMask ) !== 0 ) {
134+ throw new DetailedError ( "Can't intersect parity controls." , { "this" : this , other} )
135+ }
116136 return new Controls (
117137 this . inclusionMask | other . inclusionMask ,
118- this . desiredValueMask | other . desiredValueMask ) ;
138+ this . desiredValueMask | other . desiredValueMask ,
139+ this . parityMask | other . parityMask ) ;
119140 }
120141
121142 /**
@@ -125,7 +146,8 @@ class Controls {
125146 shift ( offset ) {
126147 return new Controls (
127148 this . inclusionMask << offset ,
128- this . desiredValueMask << offset )
149+ this . desiredValueMask << offset ,
150+ this . parityMask << offset )
129151 }
130152}
131153
0 commit comments