ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
|
Floating-point exception trap. More...
#include <fe_trap.hpp>
Public Member Functions | |
fe_trap (fe_trap const &)=delete | |
fe_trap (fe_trap &&) noexcept=delete | |
fe_trap & | operator= (fe_trap const &)=delete |
fe_trap & | operator= (fe_trap &&) noexcept=delete |
int | get_flags () const |
Get floating-point exception flags. | |
bool | is_unique () const |
Check if this handle is a unique handle. | |
Static Public Member Functions | |
static scoped_instance | make_unique_scoped (std::optional< int > excepts=std::nullopt) |
Generate a unique trap with the lifetime of the current scope. | |
static scoped_instance | make_shared_scoped (std::optional< int > excepts=std::nullopt) |
Generate a shared trap with the lifetime of the current scope. | |
Floating-point exception trap.
Thread-safe RAII-style mechanism to trap floating-point exceptions (on platforms that support floating-point environment management) for the duration of a scoped block. Exception traps are set when the object is created; when getting out-of-scope, either normally or during stack unwinding, the exception traps are automatically reset.
Please note "exception" and "exception handling" have a specific meaning in this context and are completely unrelated to C++ exceptions. For more details, see annex F IEC 60559 "floating-point arithmetic" in ISO/EIC 9899 [24] and chapter 7 "Exceptions and default exception handling" in ISO/IEC 60559:2020(E) [25].
The exception handling behavior is implementation-defined. For example, GNU libc sends the SIGFPE
signal on x86 architectures; it can be caught by a signal handler that leverages stack environments and long jumps via sigsetjmp()
. On Armv8, trapping is controlled by FPCR flags; for more details, see section C5.2.8 "FPCR, Floating-point Control Register" in the Armv8 manual [5]. AppleClang sends the SIGILL
signal on Apple Silicon architectures.
A modified singleton pattern is leveraged to guarantee only one trap is active at any time; once expired, a new trap can be instantiated. The make_unique_scoped function returns a wrapper object whose lifetime determines the trap duration. To set a trap in a recursive function, use make_shared_scoped instead.
Usage:
Build the code without fast-math and without any optimization (optimizations always assume divisions by zero cannot happen):
Definition at line 87 of file fe_trap.hpp.
|
delete |
|
deletenoexcept |
|
inline |
Get floating-point exception flags.
Definition at line 127 of file fe_trap.hpp.
|
inline |
Check if this handle is a unique handle.
Definition at line 129 of file fe_trap.hpp.
|
static |
Generate a shared trap with the lifetime of the current scope.
Subsequent calls to this function will yield the same trap handle, as long as they have the same parameter excepts
.
excepts | Combination of floating-point exception flags. |
Definition at line 121 of file fe_trap.cpp.
Referenced by ScriptInterface::ObjectHandle::call_method(), and ScriptInterface::ObjectHandle::set_parameter().
|
static |
Generate a unique trap with the lifetime of the current scope.
excepts | Combination of floating-point exception flags. |
Definition at line 109 of file fe_trap.cpp.