#endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
+/**
+ * `DEAL_II_NOT_IMPLEMENTED` is a macro (that looks like a function call
+ * when used as in `DEAL_II_NOT_IMPLEMENTED();`) that is used to raise an
+ * error in places where a piece of code is not yet implemented. If a code
+ * runs into such a place, it will be aborted with an error message that
+ * explains the situation, along with a backtrace of how the code ended
+ * up in this place.
+ *
+ * Alternatively, if
+ * deal_II_exceptions::internals::ExceptionHandling::abort_or_throw_on_exception
+ * is set to ExceptionHandling::throw_on_exception, then the corresponding
+ * error is thrown as a C++ exception that can be caught (though in
+ * many cases codes will then find it difficult to do what they wanted
+ * to do).
+ */
+#define DEAL_II_NOT_IMPLEMENTED() \
+ ::dealii::deal_II_exceptions::internals::issue_error_noreturn( \
+ ::dealii::deal_II_exceptions::internals::ExceptionHandling:: \
+ abort_or_throw_on_exception, \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ nullptr, \
+ nullptr, \
+ ExcNotImplemented())
+
+
namespace deal_II_exceptions
{
namespace internals
// print a header for the exception
out << "An error occurred in line <" << line << "> of file <" << file
<< "> in function" << std::endl
- << " " << function << std::endl
- << "The violated condition was: " << std::endl
- << " " << cond << std::endl;
-
- // print the way the additional information message was generated.
- // this is useful if the names of local variables appear in the
- // generation of the error message, because it allows the identification
- // of parts of the error text with what variables may have cause this
+ << " " << function << std::endl;
+
+ // If the exception stores a string representation of the violated
+ // condition, then output it. Not all exceptions do (e.g., when
+ // creating an exception inside DEAL_II_NOT_IMPLEMENTED()), so
+ // we have to check whether there is anything to print.
+ if (cond != nullptr)
+ out << "The violated condition was: " << std::endl
+ << " " << cond << std::endl;
+
+ // If a string representation of the exception itself is available,
+ // consider printing it as well. This is useful if the names of
+ // local variables appear in the generation of the error message,
+ // because it allows the identification of parts of the error text
+ // with what variables may have cause this.
//
// On the other hand, this is almost never the case for ExcMessage
// exceptions which would simply print the same text twice: once for
// information. Furthermore, the former of these two is often spread
// between numerous "..."-enclosed strings that the preprocessor
// collates into a single string, making it awkward to read. Consequently,
- // elide this text if the message was generated via an ExcMessage object
- if (std::strstr(cond, "dealii::ExcMessage") != nullptr)
+ // elide this text if the message was generated via an ExcMessage object.
+ //
+ // There are cases where the exception generation mechanism suppresses
+ // the string representation of the exception because it does not add
+ // anything -- e.g., DEAL_II_NOT_IMPLEMENTED does this. In those cases,
+ // also suppress the output.
+ if ((exc != nullptr) &&
+ ((cond == nullptr) ||
+ (std::strstr(cond, "dealii::ExcMessage") != nullptr)))
out << "The name and call sequence of the exception was:" << std::endl
<< " " << exc << std::endl;