Select Git revision
test_UnaryExpressionProcessor.cpp
FPEManager.cpp 2.18 KiB
#include <FPEManager.hpp>
#include <PastisMacros.hpp>
#include <pastis_config.hpp>
#include <rang.hpp>
#ifdef PASTIS_HAS_FENV_H
#include <fenv.h>
#define MANAGED_FPE (FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW)
#ifdef SYSTEM_IS_DARWIN
// MacOS-X requires definition of feenableexcept and fedisableexcept
// Public domain polyfill for feenableexcept on OS X
// http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
PASTIS_INLINE
int feenableexcept(unsigned int excepts)
{
static fenv_t fenv;
unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
// previous masks
unsigned int old_excepts;
if (fegetenv(&fenv)) {
return -1;
}
old_excepts = fenv.__control & FE_ALL_EXCEPT;
// unmask
fenv.__control &= ~new_excepts;
fenv.__mxcsr &= ~(new_excepts << 7);
return fesetenv(&fenv) ? -1 : old_excepts;
}
PASTIS_INLINE
int fedisableexcept(unsigned int excepts)
{
static fenv_t fenv;
unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
// all previous masks
unsigned int old_excepts;
if (fegetenv(&fenv)) {
return -1;
}
old_excepts = fenv.__control & FE_ALL_EXCEPT;
// mask
fenv.__control |= new_excepts;
fenv.__mxcsr |= new_excepts << 7;
return fesetenv(&fenv) ? -1 : old_excepts;
}
#endif // SYSTEM_IS_DARWIN
void FPEManager::enable()
{
std::cout << "FE management: "
<< rang::style::bold
<< rang::fgB::green
<< "enabled"
<< rang::fg::reset
<< rang::style::reset << '\n';
::feenableexcept(MANAGED_FPE);
}
void FPEManager::disable()
{
std::cout << "FE management: "
<< rang::style::bold
<< rang::fgB::red
<< "disabled"
<< rang::fg::reset
<< rang::style::reset << '\n';
::fedisableexcept(MANAGED_FPE);
}
#else // PASTIS_HAS_FENV_H
void FPEManager::enable()
{
std::cout << "FE management: enabled "
<< rang::fg::red
<< "[not supported]"
<< rang::fg::reset << '\n';
}
void FPEManager::disable()
{
std::cout << "FE management: disable "
<< rang::fg::red
<< "[not supported]"
<< rang::fg::reset << '\n';
}
#endif // PASTIS_HAS_FENV_H
void FPEManager::init(const bool& enable)
{
if (enable) {
FPEManager::enable();
} else {
FPEManager::disable();
}
}