mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Remove isinf workaround
This commit is contained in:
@ -286,17 +286,6 @@ template <typename Result> struct function {
|
|||||||
template <typename T> struct result { typedef Result type; };
|
template <typename T> struct result { typedef Result type; };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dummy_int {
|
|
||||||
int data[2];
|
|
||||||
operator int() const { return 0; }
|
|
||||||
};
|
|
||||||
typedef std::numeric_limits<internal::dummy_int> fputil;
|
|
||||||
|
|
||||||
// Dummy implementations of system functions called if the latter are not
|
|
||||||
// available.
|
|
||||||
inline dummy_int isinf(...) { return dummy_int(); }
|
|
||||||
inline dummy_int _finite(...) { return dummy_int(); }
|
|
||||||
|
|
||||||
template <typename Allocator>
|
template <typename Allocator>
|
||||||
typename Allocator::value_type* allocate(Allocator& alloc, std::size_t n) {
|
typename Allocator::value_type* allocate(Allocator& alloc, std::size_t n) {
|
||||||
#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
|
#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
|
||||||
@ -305,34 +294,9 @@ typename Allocator::value_type* allocate(Allocator& alloc, std::size_t n) {
|
|||||||
return alloc.allocate(n);
|
return alloc.allocate(n);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper function to suppress bogus "conditional expression is constant"
|
|
||||||
// warnings.
|
|
||||||
template <typename T> inline T const_check(T value) { return value; }
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
namespace std {
|
|
||||||
// Standard permits specialization of std::numeric_limits. This specialization
|
|
||||||
// is used to resolve ambiguity between isinf and std::isinf in glibc:
|
|
||||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
|
|
||||||
// and the same for isnan.
|
|
||||||
template <>
|
|
||||||
class numeric_limits<fmt::internal::dummy_int>
|
|
||||||
: public std::numeric_limits<int> {
|
|
||||||
public:
|
|
||||||
// Portable version of isinf.
|
|
||||||
template <typename T> static bool isinfinity(T x) {
|
|
||||||
using namespace fmt::internal;
|
|
||||||
// The resolution "priority" is:
|
|
||||||
// isinf macro > std::isinf > ::isinf > fmt::internal::isinf
|
|
||||||
if (const_check(sizeof(isinf(x)) != sizeof(fmt::internal::dummy_int)))
|
|
||||||
return isinf(x) != 0;
|
|
||||||
return !_finite(static_cast<double>(x));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
template <typename Range> class basic_writer;
|
template <typename Range> class basic_writer;
|
||||||
|
|
||||||
@ -2841,9 +2805,8 @@ void basic_writer<Range>::write_double(T value, const format_specs& spec) {
|
|||||||
if (!std::isfinite(value)) {
|
if (!std::isfinite(value)) {
|
||||||
// Format infinity and NaN ourselves because sprintf's output is not
|
// Format infinity and NaN ourselves because sprintf's output is not
|
||||||
// consistent across platforms.
|
// consistent across platforms.
|
||||||
const char* str = internal::fputil::isinfinity(value)
|
const char* str = std::isinf(value) ? (handler.upper ? "INF" : "inf")
|
||||||
? (handler.upper ? "INF" : "inf")
|
: (handler.upper ? "NAN" : "nan");
|
||||||
: (handler.upper ? "NAN" : "nan");
|
|
||||||
return write_padded(spec,
|
return write_padded(spec,
|
||||||
inf_or_nan_writer{sign, handler.as_percentage, str});
|
inf_or_nan_writer{sign, handler.as_percentage, str});
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
// A helper function to suppress bogus "conditional expression is constant"
|
||||||
|
// warnings.
|
||||||
|
template <typename T> inline T const_check(T value) { return value; }
|
||||||
|
|
||||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||||
// signed and unsigned integers.
|
// signed and unsigned integers.
|
||||||
template <bool IsSigned> struct int_checker {
|
template <bool IsSigned> struct int_checker {
|
||||||
|
@ -1107,6 +1107,7 @@ TEST(FormatterTest, Width) {
|
|||||||
EXPECT_EQ("x ", format("{0:11}", 'x'));
|
EXPECT_EQ("x ", format("{0:11}", 'x'));
|
||||||
EXPECT_EQ("str ", format("{0:12}", "str"));
|
EXPECT_EQ("str ", format("{0:12}", "str"));
|
||||||
}
|
}
|
||||||
|
template <typename T> inline T const_check(T value) { return value; }
|
||||||
|
|
||||||
TEST(FormatterTest, RuntimeWidth) {
|
TEST(FormatterTest, RuntimeWidth) {
|
||||||
char format_str[BUFFER_SIZE];
|
char format_str[BUFFER_SIZE];
|
||||||
@ -1135,7 +1136,7 @@ TEST(FormatterTest, RuntimeWidth) {
|
|||||||
EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1u)), format_error,
|
EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1u)), format_error,
|
||||||
"number is too big");
|
"number is too big");
|
||||||
EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), format_error, "negative width");
|
EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), format_error, "negative width");
|
||||||
if (fmt::internal::const_check(sizeof(long) > sizeof(int))) {
|
if (const_check(sizeof(long) > sizeof(int))) {
|
||||||
long value = INT_MAX;
|
long value = INT_MAX;
|
||||||
EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), format_error,
|
EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), format_error,
|
||||||
"number is too big");
|
"number is too big");
|
||||||
@ -1257,7 +1258,7 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
"number is too big");
|
"number is too big");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), format_error,
|
EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), format_error,
|
||||||
"negative precision");
|
"negative precision");
|
||||||
if (fmt::internal::const_check(sizeof(long) > sizeof(int))) {
|
if (const_check(sizeof(long) > sizeof(int))) {
|
||||||
long value = INT_MAX;
|
long value = INT_MAX;
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), format_error,
|
EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), format_error,
|
||||||
"number is too big");
|
"number is too big");
|
||||||
|
Reference in New Issue
Block a user