1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 
30 #pragma once
31 
32 // appleseed.foundation headers.
33 #include "foundation/math/scalar.h"
34 #include "foundation/utility/countof.h"
35 #include "foundation/utility/string.h"
36 #include "foundation/utility/test/exceptionassertionfailure.h"
37 #include "foundation/utility/test/testlistenerhelper.h"
38 #include "foundation/utility/test/testmessage.h"
39 #include "foundation/utility/test/testresult.h"
40 
41 // Standard headers.
42 #include <string>
43 
44 namespace foundation
45 {
46 
47 //
48 // Emit an error message signaling that an assertion failed.
49 //
50 
51 #define FOUNDATION_ASSERTION_FAILURE(op, expected, expr, stop)                          \
52     do {                                                                                \
53         case_result.signal_assertion_failure();                                         \
54                                                                                         \
55         foundation::TestListenerHelper::write(                                          \
56             test_listener,                                                              \
57             current_test_suite__(),                                                     \
58             get_name(),                                                                 \
59             __FILE__,                                                                   \
60             __LINE__,                                                                   \
61             foundation::TestMessage::AssertionFailure,                                  \
62             "expected: %s %s %s\n"                                                      \
63             "received: %s == %s",                                                       \
64             #expr, op, foundation::to_string(expected).c_str(),                         \
65             #expr, foundation::to_string(expr).c_str());                                \
66                                                                                         \
67         if (stop)                                                                       \
68             throw foundation::ExceptionAssertionFailure();                              \
69     } while (0)
70 
71 
72 //
73 // Expect a true boolean expression.
74 //
75 
76 #define FOUNDATION_EXPECT_TRUE_IMPL(expr, stop)                                         \
77     do {                                                                                \
78         case_result.signal_assertion_execution();                                       \
79         if (!(expr))                                                                    \
80             FOUNDATION_ASSERTION_FAILURE("==", true, expr, stop);                       \
81     } while (0)
82 
83 #define EXPECT_TRUE(expr)                                                               \
84     FOUNDATION_EXPECT_TRUE_IMPL(expr, false)
85 
86 #define ASSERT_TRUE(expr)                                                               \
87     FOUNDATION_EXPECT_TRUE_IMPL(expr, true)
88 
89 
90 //
91 // Expect a false boolean expression.
92 //
93 
94 #define FOUNDATION_EXPECT_FALSE_IMPL(expr, stop)                                        \
95     do {                                                                                \
96         case_result.signal_assertion_execution();                                       \
97         if (expr)                                                                       \
98             FOUNDATION_ASSERTION_FAILURE("==", false, expr, stop);                      \
99     } while (0)
100 
101 #define EXPECT_FALSE(expr)                                                              \
102     FOUNDATION_EXPECT_FALSE_IMPL(expr, false)
103 
104 #define ASSERT_FALSE(expr)                                                              \
105     FOUNDATION_EXPECT_FALSE_IMPL(expr, true)
106 
107 
108 //
109 // Expect exact equality of single objects.
110 //
111 
112 #define FOUNDATION_EXPECT_EQ_IMPL(expected, expr, stop)                                 \
113     do {                                                                                \
114         case_result.signal_assertion_execution();                                       \
115         if (!((expr) == (expected)))                                                    \
116             FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop);                   \
117     } while (0)
118 
119 #define EXPECT_EQ(expected, expr)                                                       \
120     FOUNDATION_EXPECT_EQ_IMPL(expected, expr, false)
121 
122 #define ASSERT_EQ(expected, expr)                                                       \
123     FOUNDATION_EXPECT_EQ_IMPL(expected, expr, true)
124 
125 
126 //
127 // Expect exact equality of C arrays of objects.
128 //
129 
130 #define FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, stop)                           \
131     do {                                                                                \
132         case_result.signal_assertion_execution();                                       \
133                                                                                         \
134         const size_t expected_count__ = countof(expected);                              \
135         const size_t expr_count__ = countof(expr);                                      \
136                                                                                         \
137         bool are_equal__ = expected_count__ == expr_count__;                            \
138         if (are_equal__)                                                                \
139         {                                                                               \
140             for (size_t i__ = 0; i__ < expected_count__; ++i__)                         \
141             {                                                                           \
142                 if (!((expr)[i__] == (expected)[i__]))                                  \
143                 {                                                                       \
144                     are_equal__ = false;                                                \
145                     break;                                                              \
146                 }                                                                       \
147             }                                                                           \
148         }                                                                               \
149                                                                                         \
150         if (!are_equal__)                                                               \
151         {                                                                               \
152             case_result.signal_assertion_failure();                                     \
153                                                                                         \
154             foundation::TestListenerHelper::write(                                      \
155                 test_listener,                                                          \
156                 current_test_suite__(),                                                 \
157                 get_name(),                                                             \
158                 __FILE__,                                                               \
159                 __LINE__,                                                               \
160                 foundation::TestMessage::AssertionFailure,                              \
161                 "expected: %s == %s\n"                                                  \
162                 "received: %s == %s",                                                   \
163                 #expr, foundation::to_string((expected), countof(expected)).c_str(),    \
164                 #expr, foundation::to_string((expr), countof(expr)).c_str());           \
165                                                                                         \
166             if (stop)                                                                   \
167                 throw foundation::ExceptionAssertionFailure();                          \
168         }                                                                               \
169     } while (0)
170 
171 #define EXPECT_ARRAY_EQ(expected, expr)                                                 \
172     FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, false)
173 
174 #define ASSERT_ARRAY_EQ(expected, expr)                                                 \
175     FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, true)
176 
177 
178 //
179 // Expect exact equality of sequences of objects.
180 //
181 
182 #define FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, stop)                 \
183     do {                                                                                \
184         case_result.signal_assertion_execution();                                       \
185                                                                                         \
186         bool are_equal__ = true;                                                        \
187         for (size_t i__ = 0; i__ < count; ++i__)                                        \
188         {                                                                               \
189             if (!((expr)[i__] == (expected)[i__]))                                      \
190             {                                                                           \
191                 are_equal__ = false;                                                    \
192                 break;                                                                  \
193             }                                                                           \
194         }                                                                               \
195                                                                                         \
196         if (!are_equal__)                                                               \
197         {                                                                               \
198             case_result.signal_assertion_failure();                                     \
199                                                                                         \
200             foundation::TestListenerHelper::write(                                      \
201                 test_listener,                                                          \
202                 current_test_suite__(),                                                 \
203                 get_name(),                                                             \
204                 __FILE__,                                                               \
205                 __LINE__,                                                               \
206                 foundation::TestMessage::AssertionFailure,                              \
207                 "expected: %s == %s\n"                                                  \
208                 "received: %s == %s",                                                   \
209                 #expr, foundation::to_string((expected), count).c_str(),                \
210                 #expr, foundation::to_string((expr), count).c_str());                   \
211                                                                                         \
212             if (stop)                                                                   \
213                 throw foundation::ExceptionAssertionFailure();                          \
214         }                                                                               \
215     } while (0)
216 
217 #define EXPECT_SEQUENCE_EQ(count, expected, expr)                                       \
218     FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, false)
219 
220 #define ASSERT_SEQUENCE_EQ(count, expected, expr)                                       \
221     FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, true)
222 
223 
224 //
225 // Expect exact inequality.
226 //
227 
228 #define FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, stop)                                \
229     do {                                                                                \
230         case_result.signal_assertion_execution();                                       \
231         if (!((expr) != (expected)))                                                    \
232             FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop);                   \
233     } while (0)
234 
235 #define EXPECT_NEQ(expected, expr)                                                      \
236     FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, false)
237 
238 #define ASSERT_NEQ(expected, expr)                                                      \
239     FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, true)
240 
241 
242 //
243 // Expect less-than inequality.
244 //
245 
246 #define FOUNDATION_EXPECT_LT_IMPL(expected, expr, stop)                                 \
247     do {                                                                                \
248         case_result.signal_assertion_execution();                                       \
249         if (!((expr) < (expected)))                                                     \
250             FOUNDATION_ASSERTION_FAILURE("<", expected, expr, stop);                    \
251     } while (0)
252 
253 #define EXPECT_LT(expected, expr)                                                       \
254     FOUNDATION_EXPECT_LT_IMPL(expected, expr, false)
255 
256 #define ASSERT_LT(expected, expr)                                                       \
257     FOUNDATION_EXPECT_LT_IMPL(expected, expr, true)
258 
259 
260 //
261 // Expect greater-than inequality.
262 //
263 
264 #define FOUNDATION_EXPECT_GT_IMPL(expected, expr, stop)                                 \
265     do {                                                                                \
266         case_result.signal_assertion_execution();                                       \
267         if (!((expr) > (expected)))                                                     \
268             FOUNDATION_ASSERTION_FAILURE(">", expected, expr, stop);                    \
269     } while (0)
270 
271 #define EXPECT_GT(expected, expr)                                                       \
272     FOUNDATION_EXPECT_GT_IMPL(expected, expr, false)
273 
274 #define ASSERT_GT(expected, expr)                                                       \
275     FOUNDATION_EXPECT_GT_IMPL(expected, expr, true)
276 
277 
278 //
279 // Expect approximate floating-point equality.
280 //
281 
282 #define FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, stop)                                \
283     do {                                                                                \
284         using namespace foundation;                                                     \
285         case_result.signal_assertion_execution();                                       \
286         if (!feq((expr), (expected)))                                                   \
287             FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop);                   \
288     } while (0)
289 
290 #define EXPECT_FEQ(expected, expr)                                                      \
291     FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, false)
292 
293 #define ASSERT_FEQ(expected, expr)                                                      \
294     FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, true)
295 
296 
297 //
298 // Expect approximate floating-point equality of C arrays of objects.
299 //
300 
301 #define FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, stop)                          \
302     do {                                                                                \
303         case_result.signal_assertion_execution();                                       \
304                                                                                         \
305         const size_t expected_count__ = countof(expected);                              \
306         const size_t expr_count__ = countof(expr);                                      \
307                                                                                         \
308         bool are_equal__ = expected_count__ == expr_count__;                            \
309         if (are_equal__)                                                                \
310         {                                                                               \
311             for (size_t i__ = 0; i__ < expected_count__; ++i__)                         \
312             {                                                                           \
313                 if (!feq((expr)[i__], (expected)[i__]))                                 \
314                 {                                                                       \
315                     are_equal__ = false;                                                \
316                     break;                                                              \
317                 }                                                                       \
318             }                                                                           \
319         }                                                                               \
320                                                                                         \
321         if (!are_equal__)                                                               \
322         {                                                                               \
323             case_result.signal_assertion_failure();                                     \
324                                                                                         \
325             foundation::TestListenerHelper::write(                                      \
326                 test_listener,                                                          \
327                 current_test_suite__(),                                                 \
328                 get_name(),                                                             \
329                 __FILE__,                                                               \
330                 __LINE__,                                                               \
331                 foundation::TestMessage::AssertionFailure,                              \
332                 "expected: %s == %s\n"                                                  \
333                 "received: %s == %s",                                                   \
334                 #expr, foundation::to_string((expected), countof(expected)).c_str(),    \
335                 #expr, foundation::to_string((expr), countof(expr)).c_str());           \
336                                                                                         \
337             if (stop)                                                                   \
338                 throw foundation::ExceptionAssertionFailure();                          \
339         }                                                                               \
340     } while (0)
341 
342 #define EXPECT_ARRAY_FEQ(expected, expr)                                                \
343     FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, false)
344 
345 #define ASSERT_ARRAY_FEQ(expected, expr)                                                \
346     FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, true)
347 
348 
349 //
350 // Expect approximate floating-point equality of sequences of objects.
351 //
352 
353 #define FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, stop)                \
354     do {                                                                                \
355         case_result.signal_assertion_execution();                                       \
356                                                                                         \
357         bool are_equal__ = true;                                                        \
358         for (size_t i__ = 0; i__ < count; ++i__)                                        \
359         {                                                                               \
360             if (!feq((expr)[i__], (expected)[i__]))                                     \
361             {                                                                           \
362                 are_equal__ = false;                                                    \
363                 break;                                                                  \
364             }                                                                           \
365         }                                                                               \
366                                                                                         \
367         if (!are_equal__)                                                               \
368         {                                                                               \
369             case_result.signal_assertion_failure();                                     \
370                                                                                         \
371             foundation::TestListenerHelper::write(                                      \
372                 test_listener,                                                          \
373                 current_test_suite__(),                                                 \
374                 get_name(),                                                             \
375                 __FILE__,                                                               \
376                 __LINE__,                                                               \
377                 foundation::TestMessage::AssertionFailure,                              \
378                 "expected: %s == %s\n"                                                  \
379                 "received: %s == %s",                                                   \
380                 #expr, foundation::to_string((expected), count).c_str(),                \
381                 #expr, foundation::to_string((expr), count).c_str());                   \
382                                                                                         \
383             if (stop)                                                                   \
384                 throw foundation::ExceptionAssertionFailure();                          \
385         }                                                                               \
386     } while (0)
387 
388 #define EXPECT_SEQUENCE_FEQ(count, expected, expr)                                      \
389     FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, false)
390 
391 #define ASSERT_SEQUENCE_FEQ(count, expected, expr)                                      \
392     FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, true)
393 
394 
395 //
396 // Expect approximate floating-point equality with custom epsilon value.
397 //
398 
399 #define FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, stop)                       \
400     do {                                                                                \
401         using namespace foundation;                                                     \
402         case_result.signal_assertion_execution();                                       \
403         if (!feq((expr), (expected), (eps)))                                            \
404             FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop);                   \
405     } while (0)
406 
407 #define EXPECT_FEQ_EPS(expected, expr, eps)                                             \
408     FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, false)
409 
410 #define ASSERT_FEQ_EPS(expected, expr, eps)                                             \
411     FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, true)
412 
413 
414 //
415 // Expect approximate floating-point equality of C arrays of objects with custom epsilon value.
416 //
417 
418 #define FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, stop)                 \
419     do {                                                                                \
420         case_result.signal_assertion_execution();                                       \
421                                                                                         \
422         const size_t expected_count__ = countof(expected);                              \
423         const size_t expr_count__ = countof(expr);                                      \
424                                                                                         \
425         bool are_equal__ = expected_count__ == expr_count__;                            \
426         if (are_equal__)                                                                \
427         {                                                                               \
428             for (size_t i__ = 0; i__ < expected_count__; ++i__)                         \
429             {                                                                           \
430                 if (!feq((expr)[i__], (expected)[i__], (eps)))                          \
431                 {                                                                       \
432                     are_equal__ = false;                                                \
433                     break;                                                              \
434                 }                                                                       \
435             }                                                                           \
436         }                                                                               \
437                                                                                         \
438         if (!are_equal__)                                                               \
439         {                                                                               \
440             case_result.signal_assertion_failure();                                     \
441                                                                                         \
442             foundation::TestListenerHelper::write(                                      \
443                 test_listener,                                                          \
444                 current_test_suite__(),                                                 \
445                 get_name(),                                                             \
446                 __FILE__,                                                               \
447                 __LINE__,                                                               \
448                 foundation::TestMessage::AssertionFailure,                              \
449                 "expected: %s == %s\n"                                                  \
450                 "received: %s == %s",                                                   \
451                 #expr, foundation::to_string((expected), countof(expected)).c_str(),    \
452                 #expr, foundation::to_string((expr), countof(expr)).c_str());           \
453                                                                                         \
454             if (stop)                                                                   \
455                 throw foundation::ExceptionAssertionFailure();                          \
456         }                                                                               \
457     } while (0)
458 
459 #define EXPECT_ARRAY_FEQ_EPS(expected, expr, eps)                                       \
460     FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, false)
461 
462 #define ASSERT_ARRAY_FEQ_EPS(expected, expr, eps)                                       \
463     FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, true)
464 
465 
466 //
467 // Expect approximate floating-point equality of sequences of objects with custom epsilon value.
468 //
469 
470 #define FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, stop)       \
471     do {                                                                                \
472         case_result.signal_assertion_execution();                                       \
473                                                                                         \
474         bool are_equal__ = true;                                                        \
475         for (size_t i__ = 0; i__ < count; ++i__)                                        \
476         {                                                                               \
477             if (!feq((expr)[i__], (expected)[i__], (eps)))                              \
478             {                                                                           \
479                 are_equal__ = false;                                                    \
480                 break;                                                                  \
481             }                                                                           \
482         }                                                                               \
483                                                                                         \
484         if (!are_equal__)                                                               \
485         {                                                                               \
486             case_result.signal_assertion_failure();                                     \
487                                                                                         \
488             foundation::TestListenerHelper::write(                                      \
489                 test_listener,                                                          \
490                 current_test_suite__(),                                                 \
491                 get_name(),                                                             \
492                 __FILE__,                                                               \
493                 __LINE__,                                                               \
494                 foundation::TestMessage::AssertionFailure,                              \
495                 "expected: %s == %s\n"                                                  \
496                 "received: %s == %s",                                                   \
497                 #expr, foundation::to_string((expected), count).c_str(),                \
498                 #expr, foundation::to_string((expr), count).c_str());                   \
499                                                                                         \
500             if (stop)                                                                   \
501                 throw foundation::ExceptionAssertionFailure();                          \
502         }                                                                               \
503     } while (0)
504 
505 #define EXPECT_SEQUENCE_FEQ_EPS(count, expected, expr, eps)                             \
506     FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, false)
507 
508 #define ASSERT_SEQUENCE_FEQ_EPS(count, expected, expr, eps)                             \
509     FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, true)
510 
511 
512 //
513 // Expect approximate floating-point inequality.
514 //
515 
516 #define FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, stop)                               \
517     do {                                                                                \
518         using namespace foundation;                                                     \
519         case_result.signal_assertion_execution();                                       \
520         if (feq((expr), (expected)))                                                    \
521             FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop);                   \
522     } while (0)
523 
524 #define EXPECT_FNEQ(expected, expr)                                                     \
525     FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, false)
526 
527 #define ASSERT_FNEQ(expected, expr)                                                     \
528     FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, true)
529 
530 
531 //
532 // Expect approximate floating-point inequality with custom epsilon value.
533 //
534 
535 #define FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, stop)                      \
536     do {                                                                                \
537         using namespace foundation;                                                     \
538         case_result.signal_assertion_execution();                                       \
539         if (feq((expr), (expected), (eps)))                                             \
540             FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop);                   \
541     } while (0)
542 
543 #define EXPECT_FNEQ_EPS(expected, expr, eps)                                            \
544     FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, false)
545 
546 #define ASSERT_FNEQ_EPS(expected, expr, eps)                                            \
547     FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, true)
548 
549 
550 //
551 // Expect a given exception to be thrown.
552 //
553 
554 #define FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, stop)                         \
555     do {                                                                                \
556         case_result.signal_assertion_execution();                                       \
557                                                                                         \
558         bool caught_exception__ = false;                                                \
559         try                                                                             \
560         {                                                                               \
561             expr;                                                                       \
562         }                                                                               \
563         catch (const exception&)                                                        \
564         {                                                                               \
565             caught_exception__ = true;                                                  \
566         }                                                                               \
567                                                                                         \
568         if (!caught_exception__)                                                        \
569         {                                                                               \
570             case_result.signal_assertion_failure();                                     \
571                                                                                         \
572             foundation::TestListenerHelper::write(                                      \
573                 test_listener,                                                          \
574                 current_test_suite__(),                                                 \
575                 get_name(),                                                             \
576                 __FILE__,                                                               \
577                 __LINE__,                                                               \
578                 foundation::TestMessage::AssertionFailure,                              \
579                 "expected: %s throws exception %s\n"                                    \
580                 "received: no exception",                                               \
581                 #expr, #exception);                                                     \
582                                                                                         \
583             if (stop)                                                                   \
584                 throw foundation::ExceptionAssertionFailure();                          \
585         }                                                                               \
586     } while (0)
587 
588 #define EXPECT_EXCEPTION(exception, expr)                                               \
589     FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, false)
590 
591 #define ASSERT_EXCEPTION(exception, expr)                                               \
592     FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, true)
593 
594 }   // namespace foundation
595