SpECTRE Documentation Coverage Report
Current view: top level - Utilities/ErrorHandling - Error.hpp Hit Total Coverage
Commit: 9ddc33268b29014a4956c8f0c24ca90b397463e1 Lines: 4 4 100.0 %
Date: 2024-04-26 20:00:04
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : /// \file
       5             : /// Defines macro ERROR.
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <iomanip>
      10             : #include <string>
      11             : 
      12             : #include "Utilities/ErrorHandling/AbortWithErrorMessage.hpp"
      13             : #include "Utilities/ErrorHandling/Breakpoint.hpp"
      14             : #include "Utilities/ErrorHandling/Exceptions.hpp"
      15             : #include "Utilities/ErrorHandling/FloatingPointExceptions.hpp"
      16             : #include "Utilities/ForceInline.hpp"
      17             : #include "Utilities/Literals.hpp"
      18             : #include "Utilities/MakeString.hpp"
      19             : #include "Utilities/System/Abort.hpp"
      20             : 
      21             : namespace Error_detail {
      22             : // You can't use ScopedFpeState (a non-literal type) in a constexpr
      23             : // function, but you can call another function that uses it.
      24             : template <typename ExceptionTypeToThrow, typename F>
      25             : [[noreturn]] SPECTRE_ALWAYS_INLINE void abort_without_fpes(
      26             :     const char* file, const int line, const char* const pretty_function,
      27             :     F&& message) {
      28             :   const ScopedFpeState disable_fpes(false);
      29             :   abort_with_error_message<ExceptionTypeToThrow>(file, line, pretty_function,
      30             :                                                  message());
      31             : }
      32             : }  // namespace Error_detail
      33             : 
      34             : /*!
      35             :  * \ingroup ErrorHandlingGroup
      36             :  * \brief prints an error message to the standard error stream and aborts the
      37             :  * program.
      38             :  *
      39             :  * ERROR should not be used for coding errors, but instead for user errors
      40             :  * or failure modes of numerical algorithms. An acceptable use for error is also
      41             :  * in the default case of a switch statement.
      42             :  *
      43             :  * \details
      44             :  * The implementation is specialized so that in compile time contexts, a short
      45             :  * error message will be thrown, but in runtime contexts, a more verbose error
      46             :  * will be printed. This specialization of throwing a short error at compile
      47             :  * time greatly reduces the compile time and memory consumption during debug
      48             :  * builds of deep and heavily inlined `TensorExpression` tree traversals.
      49             :  *
      50             :  * To accomplish this, `__builtin_is_constant_evaluated()` is used directly
      51             :  * instead of calling a wrapper function because calling a wrapper was found to
      52             :  * slightly increase the compile time and memory usage of large
      53             :  * `TensorExpression`s when compiling in debug mode.
      54             :  *
      55             :  * \param m an arbitrary output stream.
      56             :  */
      57             : // isocpp.org recommends using an `if (true)` instead of a `do
      58             : // while(false)` for macros because the latter can mess with inlining
      59             : // in some (old?) compilers:
      60             : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts
      61             : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if
      62             : // However, Intel's reachability analyzer (as of version 16.0.3
      63             : // 20160415) can't figure out that the else branch and everything
      64             : // after it is unreachable, causing warnings (and possibly suboptimal
      65             : // code generation).
      66           1 : #define ERROR(m)                                                             \
      67             :   do {                                                                       \
      68             :     if (__builtin_is_constant_evaluated()) {                                 \
      69             :       throw std::runtime_error("Failed");                                    \
      70             :     } else {                                                                 \
      71             :       Error_detail::abort_without_fpes<SpectreError>(                        \
      72             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
      73             :           [&]() -> std::string {                                             \
      74             :             return MakeString{} << std::setprecision(18) << std::scientific  \
      75             :                                 << m;                                        \
      76             :           });                                                                \
      77             :     }                                                                        \
      78             :   } while (false)
      79             : 
      80             : /*!
      81             :  * \ingroup ErrorHandlingGroup
      82             :  * \brief Same as ERROR but will throw `EXCEPTION_TYPE` instead of
      83             :  * `SpectreError`.
      84             :  *
      85             :  * \note Any exception types used must have an associated explicit
      86             :  * instantiation in `Utilities/ErrorHandling/AbortWithErrorMessage.cpp`
      87             :  */
      88           1 : #define ERROR_AS(m, EXCEPTION_TYPE)                                          \
      89             :   do {                                                                       \
      90             :     if (__builtin_is_constant_evaluated()) {                                 \
      91             :       throw std::runtime_error("Failed");                                    \
      92             :     } else {                                                                 \
      93             :       Error_detail::abort_without_fpes<EXCEPTION_TYPE>(                      \
      94             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
      95             :           [&]() -> std::string {                                             \
      96             :             return MakeString{} << std::setprecision(18) << std::scientific  \
      97             :                                 << m;                                        \
      98             :           });                                                                \
      99             :     }                                                                        \
     100             :   } while (false)
     101             : 
     102             : /*!
     103             :  * \ingroup ErrorHandlingGroup
     104             :  * \brief Same as ERROR but does not print a backtrace. Intended to be used for
     105             :  * user errors, such as incorrect values in an input file.
     106             :  */
     107           1 : #define ERROR_NO_TRACE(m)                                                    \
     108             :   do {                                                                       \
     109             :     if (__builtin_is_constant_evaluated()) {                                 \
     110             :       throw std::runtime_error("Failed");                                    \
     111             :     } else {                                                                 \
     112             :       const ScopedFpeState disable_fpes_ERROR(false);                        \
     113             :       abort_with_error_message_no_trace(                                     \
     114             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
     115             :           MakeString{} << std::setprecision(18) << std::scientific << m);    \
     116             :     }                                                                        \
     117             :   } while (false)

Generated by: LCOV version 1.14