@@ -38,38 +38,172 @@ extension SIMDMask where Storage == ${Vector} {
38
38
return zero .== zero
39
39
}
40
40
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
+ /// ```
42
50
@_alwaysEmitIntoClient
43
51
public static prefix func .! ( a: Self ) -> Self {
44
52
a .^ . allTrue
45
53
}
46
54
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.
48
67
@_alwaysEmitIntoClient
49
68
public static func .& ( a: Self , b: Self ) -> Self {
50
69
Self ( ${ Vector} ( Builtin . and_ ${ Builtin} (
51
70
a. _storage. _storage. _value,
52
71
b. _storage. _storage. _value
53
72
) ) )
54
73
}
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
+ }
55
87
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
+ /// ```
57
97
@_alwaysEmitIntoClient
58
98
public static func .^ ( a: Self , b: Self ) -> Self {
59
99
Self ( ${ Vector} ( Builtin . xor_ ${ Builtin} (
60
100
a. _storage. _storage. _value,
61
101
b. _storage. _storage. _value
62
102
) ) )
63
103
}
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
+ }
64
117
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.
66
130
@_alwaysEmitIntoClient
67
131
public static func .| ( a: Self , b: Self ) -> Self {
68
132
Self ( ${ Vector} ( Builtin . or_ ${ Builtin} (
69
133
a. _storage. _storage. _value,
70
134
b. _storage. _storage. _value
71
135
) ) )
72
136
}
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
+ }
73
207
}
74
208
75
209
% end
0 commit comments