@@ -144,3 +144,116 @@ count_properties(const propertiest &properties, property_statust status)
144
144
}
145
145
return count;
146
146
}
147
+
148
+ bool is_property_to_check (property_statust status)
149
+ {
150
+ return status == property_statust::NOT_CHECKED ||
151
+ status == property_statust::UNKNOWN;
152
+ }
153
+
154
+ bool has_properties_to_check (const propertiest &properties)
155
+ {
156
+ for (const auto &property_pair : properties)
157
+ {
158
+ if (is_property_to_check (property_pair.second .status ))
159
+ return true ;
160
+ }
161
+ return false ;
162
+ }
163
+
164
+ // / Update with the preference order
165
+ // / 1. old non-UNKNOWN/non-NOT_CHECKED status
166
+ // / 2. new non-UNKNOWN/non-NOT_CHECKED status
167
+ // / 3. UNKNOWN
168
+ // / 4. NOT_CHECKED
169
+ // / Suitable for updating property status
170
+ property_statust &operator |=(property_statust &a, property_statust const &b)
171
+ {
172
+ // non-monotonic use is likely a bug
173
+ PRECONDITION (
174
+ a == property_statust::NOT_CHECKED ||
175
+ (a == property_statust::UNKNOWN && b != property_statust::NOT_CHECKED) ||
176
+ a == b);
177
+ switch (a)
178
+ {
179
+ case property_statust::NOT_CHECKED:
180
+ case property_statust::UNKNOWN:
181
+ a = b;
182
+ return a;
183
+ case property_statust::ERROR:
184
+ case property_statust::PASS:
185
+ case property_statust::NOT_REACHABLE:
186
+ case property_statust::FAIL:
187
+ return a;
188
+ }
189
+ UNREACHABLE;
190
+ }
191
+
192
+ // / Update with the preference order
193
+ // / 1. ERROR
194
+ // / 2. FAIL
195
+ // / 3. UNKNOWN
196
+ // / 4. NOT_CHECKED
197
+ // / 5. NOT_REACHABLE
198
+ // / 6. PASS
199
+ // / Suitable for computing overall results
200
+ property_statust &operator &=(property_statust &a, property_statust const &b)
201
+ {
202
+ switch (a)
203
+ {
204
+ case property_statust::ERROR:
205
+ a = b;
206
+ return a;
207
+ case property_statust::FAIL:
208
+ a = (b == property_statust::ERROR ? b : a);
209
+ return a;
210
+ case property_statust::UNKNOWN:
211
+ a = (b == property_statust::ERROR || b == property_statust::FAIL ? b : a);
212
+ return a;
213
+ case property_statust::NOT_CHECKED:
214
+ a =
215
+ (b != property_statust::PASS && b != property_statust::NOT_REACHABLE ? b
216
+ : a);
217
+ return a;
218
+ case property_statust::NOT_REACHABLE:
219
+ a = (b != property_statust::PASS ? b : a);
220
+ return a;
221
+ case property_statust::PASS:
222
+ a = (b == property_statust::PASS ? a : b);
223
+ return a;
224
+ }
225
+ UNREACHABLE;
226
+ }
227
+
228
+ // / Determines the overall result corresponding from the given properties
229
+ // / That is PASS if all properties are PASS or NOT_CHECKED,
230
+ // / FAIL if at least one property is FAIL and no property is ERROR,
231
+ // / UNKNOWN if no property is FAIL or ERROR and
232
+ // / at least one property is UNKNOWN,
233
+ // / ERROR if at least one property is error.
234
+ resultt determine_result (const propertiest &properties)
235
+ {
236
+ property_statust status = property_statust::PASS;
237
+ for (const auto &property_pair : properties)
238
+ {
239
+ status &= property_pair.second .status ;
240
+ }
241
+ switch (status)
242
+ {
243
+ case property_statust::NOT_CHECKED:
244
+ // If we have unchecked properties then we don't know.
245
+ return resultt::UNKNOWN;
246
+ case property_statust::UNKNOWN:
247
+ return resultt::UNKNOWN;
248
+ case property_statust::NOT_REACHABLE:
249
+ // If a property is not reachable then overall it's still a PASS.
250
+ return resultt::PASS;
251
+ case property_statust::PASS:
252
+ return resultt::PASS;
253
+ case property_statust::FAIL:
254
+ return resultt::FAIL;
255
+ case property_statust::ERROR:
256
+ return resultt::ERROR;
257
+ }
258
+ UNREACHABLE;
259
+ }
0 commit comments