@@ -149,3 +149,89 @@ bool has_properties_to_check(const propertiest &properties)
149
149
}
150
150
return false ;
151
151
}
152
+
153
+ // / Update with the preference order
154
+ // / 1. old non-UNKNOWN/non-NOT_REACHED result
155
+ // / 2. new non-UNKNOWN/non-NOT_REACHED result
156
+ // / 3. UNKNOWN
157
+ // / 4. NOT_REACHED
158
+ // / Suitable for updating property results
159
+ property_resultt &operator |=(property_resultt &a, property_resultt const &b)
160
+ {
161
+ // non-monotonic use is likely a bug
162
+ PRECONDITION (
163
+ a == property_resultt::NOT_REACHED ||
164
+ (a == property_resultt::UNKNOWN && b != property_resultt::NOT_REACHED) ||
165
+ a == b);
166
+ switch (a)
167
+ {
168
+ case property_resultt::NOT_REACHED:
169
+ case property_resultt::UNKNOWN:
170
+ a = b;
171
+ return a;
172
+ case property_resultt::ERROR:
173
+ case property_resultt::PASS:
174
+ case property_resultt::NOT_REACHABLE:
175
+ case property_resultt::FAIL:
176
+ return a;
177
+ }
178
+ UNREACHABLE;
179
+ }
180
+
181
+ // / Update with the preference order
182
+ // / 1. ERROR
183
+ // / 2. FAIL
184
+ // / 3. UNKNOWN
185
+ // / 4. NOT_REACHED
186
+ // / 5. NOT_REACHABLE
187
+ // / 6. PASS
188
+ // / Suitable for computing overall results
189
+ property_resultt &operator &=(property_resultt &a, property_resultt const &b)
190
+ {
191
+ switch (a)
192
+ {
193
+ case property_resultt::ERROR:
194
+ a = b;
195
+ return a;
196
+ case property_resultt::FAIL:
197
+ a = (b == property_resultt::ERROR ? b : a);
198
+ return a;
199
+ case property_resultt::UNKNOWN:
200
+ a = (b == property_resultt::ERROR || b == property_resultt::FAIL ? b : a);
201
+ return a;
202
+ case property_resultt::NOT_REACHED:
203
+ a = (b != property_resultt::PASS && b != property_resultt::NOT_REACHABLE? b : a);
204
+ return a;
205
+ case property_resultt::NOT_REACHABLE:
206
+ a = (b != property_resultt::PASS ? b : a);
207
+ return a;
208
+ case property_resultt::PASS:
209
+ a = (b == property_resultt::PASS ? a : b);
210
+ return a;
211
+ }
212
+ UNREACHABLE;
213
+ }
214
+
215
+ // / Determines the overall result corresponding from the given properties
216
+ // / That is PASS if all properties are PASS or NOT_REACHED,
217
+ // / FAIL if at least one property is FAIL and no property is ERROR,
218
+ // / UNKNOWN if no property is FAIL or ERROR and
219
+ // / at least one property is UNKNOWN,
220
+ // / ERROR if at least one property is error.
221
+ resultt determine_result (const propertiest &properties)
222
+ {
223
+ property_resultt result = property_resultt::PASS;
224
+ for (const auto &property_pair : properties)
225
+ {
226
+ result &= property_pair.second .result ;
227
+ }
228
+ // If we haven't reached anything or nothing is reachable
229
+ // then overall it's still a PASS.
230
+ if (
231
+ result == property_resultt::NOT_REACHED ||
232
+ result == property_resultt::NOT_REACHABLE)
233
+ {
234
+ result = property_resultt::PASS;
235
+ }
236
+ return static_cast <resultt>(result);
237
+ }
0 commit comments