Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-2941-gbd3c83c843 2025-03-25 23:50:00+00:00
\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}} \newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=} \newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]} \newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
exception_macros.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2012 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_exception_macros_h
16#define dealii_exception_macros_h
17
18#include <deal.II/base/config.h>
19
20
21/**********************************************************************
22 * Preprocessor definitions in support of declaring exception classes.
23 *
24 * These make reference to classes and functions that are declared in
25 * exceptions.h. This is ok as far as concerning preprocessor defines
26 * is concerned, but in order to use the material below, you also need
27 * to have `#include <deal.II/base/exceptions.h>`.
28 */
29#ifndef DOXYGEN
30
47# define DeclException0(Exception0) \
48 class Exception0 : public ::ExceptionBase \
49 {}
50
51
71# define DeclExceptionMsg(Exception, defaulttext) \
72 class Exception : public ::ExceptionBase \
73 { \
74 public: \
75 Exception(const std::string &msg = defaulttext) \
76 : arg(msg) \
77 {} \
78 virtual ~Exception() noexcept \
79 {} \
80 virtual void \
81 print_info(std::ostream &out) const override \
82 { \
83 out << " " << arg << std::endl; \
84 } \
85 \
86 private: \
87 const std::string arg; \
88 }
89
107# define DeclException1(Exception1, type1, outsequence) \
108 class Exception1 : public ::ExceptionBase \
109 { \
110 public: \
111 Exception1(type1 const &a1) \
112 : arg1(a1) \
113 {} \
114 virtual ~Exception1() noexcept \
115 {} \
116 virtual void \
117 print_info(std::ostream &out) const override \
118 { \
119 out << " " outsequence << std::endl; \
120 } \
121 \
122 private: \
123 type1 const arg1; \
124 }
125
126
144# define DeclException2(Exception2, type1, type2, outsequence) \
145 class Exception2 : public ::ExceptionBase \
146 { \
147 public: \
148 Exception2(type1 const &a1, type2 const &a2) \
149 : arg1(a1) \
150 , arg2(a2) \
151 {} \
152 virtual ~Exception2() noexcept \
153 {} \
154 virtual void \
155 print_info(std::ostream &out) const override \
156 { \
157 out << " " outsequence << std::endl; \
158 } \
159 \
160 private: \
161 type1 const arg1; \
162 type2 const arg2; \
163 }
164
165
183# define DeclException3(Exception3, type1, type2, type3, outsequence) \
184 class Exception3 : public ::ExceptionBase \
185 { \
186 public: \
187 Exception3(type1 const &a1, type2 const &a2, type3 const &a3) \
188 : arg1(a1) \
189 , arg2(a2) \
190 , arg3(a3) \
191 {} \
192 virtual ~Exception3() noexcept \
193 {} \
194 virtual void \
195 print_info(std::ostream &out) const override \
196 { \
197 out << " " outsequence << std::endl; \
198 } \
199 \
200 private: \
201 type1 const arg1; \
202 type2 const arg2; \
203 type3 const arg3; \
204 }
205
206
224# define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
225 class Exception4 : public ::ExceptionBase \
226 { \
227 public: \
228 Exception4(type1 const &a1, \
229 type2 const &a2, \
230 type3 const &a3, \
231 type4 const &a4) \
232 : arg1(a1) \
233 , arg2(a2) \
234 , arg3(a3) \
235 , arg4(a4) \
236 {} \
237 virtual ~Exception4() noexcept \
238 {} \
239 virtual void \
240 print_info(std::ostream &out) const override \
241 { \
242 out << " " outsequence << std::endl; \
243 } \
244 \
245 private: \
246 type1 const arg1; \
247 type2 const arg2; \
248 type3 const arg3; \
249 type4 const arg4; \
250 }
251
252
270# define DeclException5( \
271 Exception5, type1, type2, type3, type4, type5, outsequence) \
272 class Exception5 : public ::ExceptionBase \
273 { \
274 public: \
275 Exception5(type1 const &a1, \
276 type2 const &a2, \
277 type3 const &a3, \
278 type4 const &a4, \
279 type5 const &a5) \
280 : arg1(a1) \
281 , arg2(a2) \
282 , arg3(a3) \
283 , arg4(a4) \
284 , arg5(a5) \
285 {} \
286 virtual ~Exception5() noexcept \
287 {} \
288 virtual void \
289 print_info(std::ostream &out) const override \
290 { \
291 out << " " outsequence << std::endl; \
292 } \
293 \
294 private: \
295 type1 const arg1; \
296 type2 const arg2; \
297 type3 const arg3; \
298 type4 const arg4; \
299 type5 const arg5; \
300 }
301
302#else /*ifndef DOXYGEN*/
303
304// Dummy definitions for doxygen:
305
322# define DeclException0(Exception0) \
323 \
324 static ::ExceptionBase &Exception0()
325
345# define DeclExceptionMsg(Exception, defaulttext) \
346 \
347 \
348 static ::ExceptionBase &Exception()
349
367# define DeclException1(Exception1, type1, outsequence) \
368 \
369 \
370 static ::ExceptionBase &Exception1(type1 arg1)
371
372
390# define DeclException2(Exception2, type1, type2, outsequence) \
391 \
392 \
393 static ::ExceptionBase &Exception2(type1 arg1, type2 arg2)
394
395
413# define DeclException3(Exception3, type1, type2, type3, outsequence) \
414 \
415 \
416 static ::ExceptionBase &Exception3(type1 arg1, type2 arg2, type3 arg3)
417
418
436# define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
437 \
438 \
439 static ::ExceptionBase &Exception4(type1 arg1, \
440 type2 arg2, \
441 type3 arg3, \
442 type4 arg4)
443
444
462# define DeclException5( \
463 Exception5, type1, type2, type3, type4, type5, outsequence) \
464 \
465 \
466 static ::ExceptionBase &Exception5( \
467 type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)
468
469#endif /*ifndef DOXYGEN*/
470
471
472
473/**********************************************************************
474 * Preprocessor definitions in support of assertions.
475 *
476 * These make reference to classes and functions that are declared in
477 * exceptions.h. This is ok as far as concerning preprocessor defines
478 * is concerned, but in order to use the material below, you also need
479 * to have `#include <deal.II/base/exceptions.h>`.
480 */
481
507#ifdef DEBUG
508# if KOKKOS_VERSION >= 30600
509# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
510# define Assert(cond, exc) \
511 do \
512 { \
513 KOKKOS_IF_ON_HOST(({ \
514 if (__builtin_expect(!(cond), false)) \
515 ::deal_II_exceptions::internals::issue_error_noreturn( \
516 ::deal_II_exceptions::internals::ExceptionHandling:: \
517 abort_or_throw_on_exception, \
518 __FILE__, \
519 __LINE__, \
520 __PRETTY_FUNCTION__, \
521 #cond, \
522 #exc, \
523 exc); \
524 })) \
525 KOKKOS_IF_ON_DEVICE(({ \
526 if (!(cond)) \
527 Kokkos::abort(#cond); \
528 })) \
529 } \
530 while (false)
531# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
532# define Assert(cond, exc) \
533 do \
534 { \
535 KOKKOS_IF_ON_HOST(({ \
536 if (!(cond)) \
537 ::deal_II_exceptions::internals::issue_error_noreturn( \
538 ::deal_II_exceptions::internals::ExceptionHandling:: \
539 abort_or_throw_on_exception, \
540 __FILE__, \
541 __LINE__, \
542 __PRETTY_FUNCTION__, \
543 #cond, \
544 #exc, \
545 exc); \
546 })) \
547 KOKKOS_IF_ON_DEVICE(({ \
548 if (!(cond)) \
549 Kokkos::abort(#cond); \
550 })) \
551 } \
552 while (false)
553# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
554# else /*if KOKKOS_VERSION >= 30600*/
555# ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
556# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
557# define Assert(cond, exc) \
558 do \
559 { \
560 if (__builtin_expect(!(cond), false)) \
561 ::deal_II_exceptions::internals::issue_error_noreturn( \
562 ::deal_II_exceptions::internals::ExceptionHandling:: \
563 abort_or_throw_on_exception, \
564 __FILE__, \
565 __LINE__, \
566 __PRETTY_FUNCTION__, \
567 #cond, \
568 #exc, \
569 exc); \
570 } \
571 while (false)
572# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
573# define Assert(cond, exc) \
574 do \
575 { \
576 if (!(cond)) \
577 ::deal_II_exceptions::internals::issue_error_noreturn( \
578 ::deal_II_exceptions::internals::ExceptionHandling:: \
579 abort_or_throw_on_exception, \
580 __FILE__, \
581 __LINE__, \
582 __PRETTY_FUNCTION__, \
583 #cond, \
584 #exc, \
585 exc); \
586 } \
587 while (false)
588# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
589# else /*#ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
590# define Assert(cond, exc) \
591 do \
592 { \
593 if (!(cond)) \
594 Kokkos::abort(#cond); \
595 } \
596 while (false)
597# endif /*ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
598# endif /*KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
599#else /*ifdef DEBUG*/
600# ifdef DEAL_II_HAVE_CXX20
601/*
602 * In order to avoid unused parameters (etc.) warnings we need to use cond
603 * and exc without actually evaluating the expression and generating code.
604 * We accomplish this by using decltype(...) and create a dummy pointer
605 * with these signatures. Notably, this approach works with C++20 onwards.
606 */
607# define Assert(cond, exc) \
608 do \
609 { \
610 std::remove_reference_t<decltype(cond)> *dealii_assert_variable_a = \
611 nullptr; \
612 std::remove_reference_t<decltype(exc)> *dealii_assert_variable_b = \
613 nullptr; \
614 (void)dealii_assert_variable_a; \
615 (void)dealii_assert_variable_b; \
616 } \
617 while (false)
618# else
619# define Assert(cond, exc) \
620 do \
621 { \
622 if constexpr (false) \
623 if (!(cond)) \
624 { \
625 } \
626 } \
627 while (false)
628# endif
629#endif /*ifdef DEBUG*/
630
631
632
659#ifdef DEBUG
660# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
661# define AssertNothrow(cond, exc) \
662 do \
663 { \
664 if (__builtin_expect(!(cond), false)) \
665 ::deal_II_exceptions::internals::issue_error_nothrow( \
666 __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
667 } \
668 while (false)
669# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
670# define AssertNothrow(cond, exc) \
671 do \
672 { \
673 if (!(cond)) \
674 ::deal_II_exceptions::internals::issue_error_nothrow( \
675 __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
676 } \
677 while (false)
678# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
679#else
680# define AssertNothrow(cond, exc) \
681 do \
682 { \
683 } \
684 while (false)
685#endif
686
714#ifdef DEAL_II_HAVE_BUILTIN_EXPECT
715# define AssertThrow(cond, exc) \
716 do \
717 { \
718 if (__builtin_expect(!(cond), false)) \
719 ::deal_II_exceptions::internals::issue_error_noreturn( \
720 ::deal_II_exceptions::internals::ExceptionHandling:: \
721 throw_on_exception, \
722 __FILE__, \
723 __LINE__, \
724 __PRETTY_FUNCTION__, \
725 #cond, \
726 #exc, \
727 exc); \
728 } \
729 while (false)
730#else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
731# define AssertThrow(cond, exc) \
732 do \
733 { \
734 if (!(cond)) \
735 ::deal_II_exceptions::internals::issue_error_noreturn( \
736 ::deal_II_exceptions::internals::ExceptionHandling:: \
737 throw_on_exception, \
738 __FILE__, \
739 __LINE__, \
740 __PRETTY_FUNCTION__, \
741 #cond, \
742 #exc, \
743 exc); \
744 } \
745 while (false)
746#endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
747
748
790#define DEAL_II_NOT_IMPLEMENTED() \
791 ::deal_II_exceptions::internals::issue_error_noreturn( \
792 ::deal_II_exceptions::internals::ExceptionHandling:: \
793 abort_or_throw_on_exception, \
794 __FILE__, \
795 __LINE__, \
796 __PRETTY_FUNCTION__, \
797 nullptr, \
798 nullptr, \
799 ::StandardExceptions::ExcNotImplemented())
800
801
873#define DEAL_II_ASSERT_UNREACHABLE() \
874 ::deal_II_exceptions::internals::issue_error_noreturn( \
875 ::deal_II_exceptions::internals::ExceptionHandling:: \
876 abort_or_throw_on_exception, \
877 __FILE__, \
878 __LINE__, \
879 __PRETTY_FUNCTION__, \
880 nullptr, \
881 nullptr, \
882 ::StandardExceptions::ExcMessage( \
883 "The program has hit a line of code that the programmer " \
884 "marked with the macro DEAL_II_ASSERT_UNREACHABLE() to " \
885 "indicate that the program should never reach this " \
886 "location. You will have to find out (best done in a " \
887 "debugger) why that happened. Typical reasons include " \
888 "passing invalid arguments to functions (for example, if " \
889 "a function takes an 'enum' with two possible values " \
890 "as argument, but you call the function with a third " \
891 "value), or if the programmer of the code that triggered " \
892 "the error believed that a variable can only have " \
893 "specific values, but either that assumption is wrong " \
894 "or the computation of that value is buggy." \
895 "\n\n" \
896 "In those latter conditions, where some internal " \
897 "assumption is not satisfied, there may not be very " \
898 "much you can do if you encounter such an exception, " \
899 "since it indicates an error in deal.II, not in your " \
900 "own program. If that is the situation you encounter, " \
901 "try to come up with " \
902 "the smallest possible program that still demonstrates " \
903 "the error and contact the deal.II mailing lists with it " \
904 "to obtain help."))
905
906
927#define AssertDimension(dim1, dim2) \
928 Assert(::deal_II_exceptions::internals::compare_for_equality(dim1, \
929 dim2), \
930 ::ExcDimensionMismatch((dim1), (dim2)))
931
940#define AssertIntegerConversion(index1, index2) \
941 Assert(::deal_II_exceptions::internals::compare_for_equality( \
942 index1, index2), \
943 ::ExcInvalidIntegerConversion((index1), (index2)))
944
949#define AssertThrowIntegerConversion(index1, index2) \
950 AssertThrow(::deal_II_exceptions::internals::compare_for_equality( \
951 index1, index2), \
952 ::ExcInvalidIntegerConversion((index1), (index2)))
953
971#define AssertVectorVectorDimension(VEC, DIM1, DIM2) \
972 AssertDimension(VEC.size(), DIM1); \
973 for (const auto &subvector : VEC) \
974 { \
975 (void)subvector; \
976 AssertDimension(subvector.size(), DIM2); \
977 }
978
979
999#define AssertIndexRange(index, range) \
1000 Assert(::deal_II_exceptions::internals::compare_less_than(index, \
1001 range), \
1002 ExcIndexRangeType<::internal::argument_type_t<void( \
1003 std::common_type_t<decltype(index), decltype(range)>)>>((index), \
1004 0, \
1005 (range)))
1006
1026#define AssertIsFinite(number) \
1027 Assert(::numbers::is_finite(number), \
1028 ::ExcNumberNotFinite(std::complex<double>(number)))
1029
1035#define AssertIsNotUsed(obj) Assert((obj)->used() == false, ExcInternalError())
1036
1037#ifdef DEAL_II_WITH_MPI
1058# define AssertThrowMPI(error_code) \
1059 AssertThrow(error_code == MPI_SUCCESS, ::ExcMPI(error_code))
1060#else
1061# define AssertThrowMPI(error_code) \
1062 do \
1063 { \
1064 } \
1065 while (false)
1066#endif // DEAL_II_WITH_MPI
1067
1068#ifdef DEAL_II_TRILINOS_WITH_SEACAS
1086# define AssertThrowExodusII(error_code) \
1087 AssertThrow(error_code == 0, \
1088 ::StandardExceptions::ExcExodusII(error_code));
1089#endif // DEAL_II_TRILINOS_WITH_SEACAS
1090
1091
1092#ifdef DEAL_II_WITH_SUNDIALS
1110# define AssertARKode(code) Assert(code >= 0, ExcARKodeError(code))
1111
1129# define AssertKINSOL(code) Assert(code >= 0, ExcKINSOLError(code))
1130
1148# define AssertIDA(code) Assert(code >= 0, ExcIDAError(code))
1149#endif
1150
1151
1152#endif