Remove signbit workaround
This commit is contained in:
parent
7bebb3e128
commit
57983423c3
@ -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)) {
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user