@@ -38,38 +38,172 @@ extension SIMDMask where Storage == ${Vector} {
3838 return zero .== zero
3939 }
4040
41- /// A vector mask that is the boolean negation of the input.
41+ /// A vector mask that is the pointwise logical negation of the input.
42+ ///
43+ /// Equivalent to:
44+ /// ```
45+ /// var result = SIMDMask<${Vector}>()
46+ /// for i in result.indices {
47+ /// result[i] = !a[i]
48+ /// }
49+ /// ```
4250 @_alwaysEmitIntoClient
4351 public static prefix func .! ( a: Self ) -> Self {
4452 a .^ . allTrue
4553 }
4654
47- /// A vector mask that is the boolean conjunction of the inputs.
55+ /// A vector mask that is the pointwise logical conjunction of the inputs.
56+ ///
57+ /// Equivalent to:
58+ /// ```
59+ /// var result = SIMDMask<${Vector}>()
60+ /// for i in result.indices {
61+ /// result[i] = a[i] && b[i]
62+ /// }
63+ /// ```
64+ ///
65+ /// Note that unlike the scalar `&&` operator, the SIMD `.&` operator
66+ /// always fully evaluates both arguments.
4867 @_alwaysEmitIntoClient
4968 public static func .& ( a: Self , b: Self ) -> Self {
5069 Self ( ${ Vector} ( Builtin . and_ ${ Builtin} (
5170 a. _storage. _storage. _value,
5271 b. _storage. _storage. _value
5372 ) ) )
5473 }
74+
75+ /// Replaces `a` with the pointwise logical conjuction of `a` and `b`.
76+ ///
77+ /// Equivalent to:
78+ /// ```
79+ /// for i in a.indices {
80+ /// a[i] = a[i] && b[i]
81+ /// }
82+ /// ```
83+ @_alwaysEmitIntoClient
84+ public static func .&= ( a: inout Self , b: Self ) {
85+ a = a .& b
86+ }
5587
56- /// A vector mask that is the exclusive or of the inputs.
88+ /// A vector mask that is the pointwise exclusive or of the inputs.
89+ ///
90+ /// Equivalent to:
91+ /// ```
92+ /// var result = SIMDMask<${Vector}>()
93+ /// for i in result.indices {
94+ /// result[i] = a[i] != b[i]
95+ /// }
96+ /// ```
5797 @_alwaysEmitIntoClient
5898 public static func .^ ( a: Self , b: Self ) -> Self {
5999 Self ( ${ Vector} ( Builtin . xor_ ${ Builtin} (
60100 a. _storage. _storage. _value,
61101 b. _storage. _storage. _value
62102 ) ) )
63103 }
104+
105+ /// Replaces `a` with the pointwise exclusive or of `a` and `b`.
106+ ///
107+ /// Equivalent to:
108+ /// ```
109+ /// for i in a.indices {
110+ /// a[i] = a[i] != b[i]
111+ /// }
112+ /// ```
113+ @_alwaysEmitIntoClient
114+ public static func .^= ( a: inout Self , b: Self ) {
115+ a = a .^ b
116+ }
64117
65- /// A vector mask that is the boolean disjunction of the inputs.
118+ /// A vector mask that is the pointwise logical disjunction of the inputs.
119+ ///
120+ /// Equivalent to:
121+ /// ```
122+ /// var result = SIMDMask<${Vector}>()
123+ /// for i in result.indices {
124+ /// result[i] = a[i] || b[i]
125+ /// }
126+ /// ```
127+ ///
128+ /// Note that unlike the scalar `||` operator, the SIMD `.|` operator
129+ /// always fully evaluates both arguments.
66130 @_alwaysEmitIntoClient
67131 public static func .| ( a: Self , b: Self ) -> Self {
68132 Self ( ${ Vector} ( Builtin . or_ ${ Builtin} (
69133 a. _storage. _storage. _value,
70134 b. _storage. _storage. _value
71135 ) ) )
72136 }
137+
138+ /// Replaces `a` with the pointwise logical disjunction of `a` and `b`.
139+ ///
140+ /// Equivalent to:
141+ /// ```
142+ /// for i in a.indices {
143+ /// a[i] = a[i] || b[i]
144+ /// }
145+ /// ```
146+ @_alwaysEmitIntoClient
147+ public static func .|= ( a: inout Self , b: Self ) {
148+ a = a .| b
149+ }
150+
151+ /// A vector mask with the result of a pointwise equality comparison.
152+ ///
153+ /// Equivalent to:
154+ /// ```
155+ /// var result = SIMDMask<${Vector}>()
156+ /// for i in result.indices {
157+ /// result[i] = a[i] == b[i]
158+ /// }
159+ /// ```
160+ @_alwaysEmitIntoClient
161+ public static func .== ( a: Self , b: Self ) -> Self {
162+ .! ( a .^ b)
163+ }
164+
165+ /// A vector mask with the result of a pointwise inequality comparison.
166+ ///
167+ /// Equivalent to:
168+ /// ```
169+ /// var result = SIMDMask<${Vector}>()
170+ /// for i in result.indices {
171+ /// result[i] = a[i] != b[i]
172+ /// }
173+ /// ```
174+ @_alwaysEmitIntoClient
175+ public static func .!= ( a: Self , b: Self ) -> Self {
176+ a .^ b
177+ }
178+
179+ /// Replaces elements of this vector with elements of `other` in the lanes
180+ /// where `mask` is `true`.
181+ ///
182+ /// Equivalent to:
183+ /// ```
184+ /// for i in indices {
185+ /// if mask[i] { self[i] = other[i] }
186+ /// }
187+ /// ```
188+ @_alwaysEmitIntoClient
189+ public mutating func replace( with other: Self , where mask: Self ) {
190+ self = replacing ( with: other, where: mask)
191+ }
192+
193+ /// Returns a copy of this vector, with elements replaced by elements of
194+ /// `other` in the lanes where `mask` is `true`.
195+ ///
196+ /// Equivalent to:
197+ /// ```
198+ /// var result = Self()
199+ /// for i in indices {
200+ /// result[i] = mask[i] ? other[i] : self[i]
201+ /// }
202+ /// ```
203+ @_alwaysEmitIntoClient
204+ public func replacing( with other: Self , where mask: Self ) -> Self {
205+ ( self .& .! mask) .| ( other .& mask)
206+ }
73207}
74208
75209% end
0 commit comments