Skip to content

Instantly share code, notes, and snippets.

@socantre
Created October 29, 2015 20:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save socantre/07f93decf8a0de53ea9c to your computer and use it in GitHub Desktop.
Save socantre/07f93decf8a0de53ea9c to your computer and use it in GitHub Desktop.
playing with system_error and error codes
#include <system_error>
#include <cfenv>
#include <cassert>
namespace fe {
enum class rounding_mode : int {
downward = FE_DOWNWARD,
to_nearest = FE_TONEAREST,
toward_zero = FE_TOWARDZERO,
upward = FE_UPWARD
};
inline rounding_mode get_rounding(std::system_error &ec) {
int mode = fegetround();
if (mode < 0) {
ec = std::make_error_code(static_cast<std::errc>(mode));
return static_cast<rounding_mode>(-1);
}
assert(mode == FE_DOWNWARD || mode == FE_TONEAREST || mode == FE_TOWARDZERO || mode == FE_UPWARD);
return static_cast<rounding_mode>(mode);
}
inline rounding_mode get_rounding() {
int mode = fegetround();
if (mode < 0) {
throw std::system_error(std::make_error_code(static_cast<std::errc>(mode)), "no such rounding mode or the current rounding mode cannot be determined");
}
assert(mode == FE_DOWNWARD || mode == FE_TONEAREST || mode == FE_TOWARDZERO || mode == FE_UPWARD);
return static_cast<rounding_mode>(mode);
}
inline void set_rounding(rounding_mode m, std::error_code &ec) {
int result = fesetround(static_cast<int>(m));
if (result != 0) {
ec = std::make_error_code(static_cast<std::errc>(result));
}
}
inline void set_rounding(rounding_mode m) {
std::error_code ec;
set_rounding(m, ec);
if (ec) {
throw std::system_error(ec, "failed to set rounding mode");
}
}
struct rounding_mode_setter {
rounding_mode saved_mode;
rounding_mode_setter(rounding_mode m) : saved_mode(get_rounding()) { set_rounding(m); }
~rounding_mode_setter() noexcept(false) {set_rounding(saved_mode);}
rounding_mode_setter(rounding_mode_setter const &) = delete;
rounding_mode_setter(rounding_mode_setter &&) = delete;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment