Remove signbit workaround

This commit is contained in:
Victor Zverovich 2018-10-10 09:41:01 -07:00
parent 7bebb3e128
commit 57983423c3
2 changed files with 9 additions and 23 deletions

View File

@ -278,10 +278,8 @@ struct dummy_int {
}; };
typedef std::numeric_limits<internal::dummy_int> fputil; typedef std::numeric_limits<internal::dummy_int> fputil;
// Dummy implementations of system functions such as signbit and ecvt called // Dummy implementations of system functions called if the latter are not
// if the latter are not available. // available.
inline dummy_int signbit(...) { return dummy_int(); }
inline dummy_int _ecvt_s(...) { return dummy_int(); }
inline dummy_int isinf(...) { return dummy_int(); } inline dummy_int isinf(...) { return dummy_int(); }
inline dummy_int _finite(...) { return dummy_int(); } inline dummy_int _finite(...) { return dummy_int(); }
inline dummy_int isnan(...) { return dummy_int(); } inline dummy_int isnan(...) { return dummy_int(); }
@ -321,7 +319,7 @@ namespace std {
// Standard permits specialization of std::numeric_limits. This specialization // Standard permits specialization of std::numeric_limits. This specialization
// is used to resolve ambiguity between isinf and std::isinf in glibc: // is used to resolve ambiguity between isinf and std::isinf in glibc:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
// and the same for isnan and signbit. // and the same for isnan.
template <> template <>
class numeric_limits<fmt::internal::dummy_int> : class numeric_limits<fmt::internal::dummy_int> :
public std::numeric_limits<int> { public std::numeric_limits<int> {
@ -345,19 +343,6 @@ class numeric_limits<fmt::internal::dummy_int> :
return isnan(x) != 0; return isnan(x) != 0;
return _isnan(static_cast<double>(x)) != 0; return _isnan(static_cast<double>(x)) != 0;
} }
// Portable version of signbit.
static bool isnegative(double x) {
using namespace fmt::internal;
if (const_check(sizeof(signbit(x)) != sizeof(fmt::internal::dummy_int)))
return signbit(x) != 0;
if (x < 0) return true;
if (!isnotanumber(x)) return false;
int dec = 0, sign = 0;
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
_ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
return sign != 0;
}
}; };
} // namespace std } // namespace std
@ -2862,9 +2847,9 @@ void basic_writer<Range>::write_double(T value, const format_specs &spec) {
internal::handle_float_type_spec(handler.type, handler); internal::handle_float_type_spec(handler.type, handler);
char sign = 0; char sign = 0;
// Use isnegative instead of value < 0 because the latter is always // Use signbit instead of value < 0 because the latter is always
// false for NaN. // false for NaN.
if (internal::fputil::isnegative(static_cast<double>(value))) { if (std::signbit(value)) {
sign = '-'; sign = '-';
value = -value; value = -value;
} else if (spec.flag(SIGN_FLAG)) { } else if (spec.flag(SIGN_FLAG)) {

View File

@ -129,7 +129,7 @@ TEST(FormatTest, ArgConverter) {
TEST(FormatTest, FormatNegativeNaN) { TEST(FormatTest, FormatNegativeNaN) {
double nan = std::numeric_limits<double>::quiet_NaN(); double nan = std::numeric_limits<double>::quiet_NaN();
if (fmt::internal::fputil::isnegative(-nan)) if (std::signbit(-nan))
EXPECT_EQ("-nan", fmt::format("{}", -nan)); EXPECT_EQ("-nan", fmt::format("{}", -nan));
else else
fmt::print("Warning: compiler doesn't handle negative NaN correctly"); fmt::print("Warning: compiler doesn't handle negative NaN correctly");
@ -138,7 +138,8 @@ TEST(FormatTest, FormatNegativeNaN) {
TEST(FormatTest, StrError) { TEST(FormatTest, StrError) {
char *message = nullptr; char *message = nullptr;
char buffer[BUFFER_SIZE]; char buffer[BUFFER_SIZE];
EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = nullptr, 0), "invalid buffer"); EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = nullptr, 0),
"invalid buffer");
EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = buffer, 0), EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = buffer, 0),
"invalid buffer"); "invalid buffer");
buffer[0] = 'x'; buffer[0] = 'x';
@ -151,7 +152,7 @@ TEST(FormatTest, StrError) {
#endif #endif
int result = fmt::safe_strerror(error_code, message = buffer, BUFFER_SIZE); int result = fmt::safe_strerror(error_code, message = buffer, BUFFER_SIZE);
EXPECT_EQ(0, result); EXPECT_EQ(result, 0);
std::size_t message_size = std::strlen(message); std::size_t message_size = std::strlen(message);
EXPECT_GE(BUFFER_SIZE - 1u, message_size); EXPECT_GE(BUFFER_SIZE - 1u, message_size);
EXPECT_EQ(get_system_error(error_code), message); EXPECT_EQ(get_system_error(error_code), message);