Commit c1a8dfe5 authored by vitaut's avatar vitaut

Improve detection of signbit

parent d9e0f5c0
...@@ -579,18 +579,45 @@ class FixedBuffer : public fmt::Buffer<Char> { ...@@ -579,18 +579,45 @@ class FixedBuffer : public fmt::Buffer<Char> {
void grow(std::size_t size); void grow(std::size_t size);
}; };
#ifndef _MSC_VER template <typename T = void>
struct Null {};
// Dummy implementations of signbit and _ecvt_s called if corresponding system
// functions are not available.
inline Null<> signbit(...) { return Null<>(); }
inline Null<> _ecvt_s(...) { return Null<>(); }
// Portable version of signbit. // Portable version of signbit.
inline int getsign(double x) { inline int getsign(double x) {
// When compiled in C++11 mode signbit is no longer a macro but a function class SignBit {
// defined in namespace std and the macro is undefined. private:
# ifdef signbit double value_;
return signbit(x);
# else int handle(int result) { return result; }
return std::signbit(x);
# endif int handle(fmt::internal::Null<>) {
if (value_ < 0) return 1;
if (value_ == value_) return 0;
int dec = 0, sign = 0;
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
_ecvt_s(buffer, sizeof(buffer), value_, 0, &dec, &sign);
return sign;
}
public:
SignBit(double value) : value_(value) {}
int call() {
// When compiled in C++11 mode signbit is no longer a macro but a
// function defined in namespace std and the macro is undefined.
using namespace std;
return handle(signbit(value_));
}
};
return SignBit(x).call();
} }
#ifndef _MSC_VER
// Portable version of isinf. // Portable version of isinf.
# ifdef isinf # ifdef isinf
inline int isinfinity(double x) { return isinf(x); } inline int isinfinity(double x) { return isinf(x); }
...@@ -609,14 +636,6 @@ inline int isnotanumber(double x) { return std::isnan(x); } ...@@ -609,14 +636,6 @@ inline int isnotanumber(double x) { return std::isnan(x); }
inline int isnotanumber(long double x) { return std::isnan(x); } inline int isnotanumber(long double x) { return std::isnan(x); }
# endif # endif
#else #else
inline int getsign(double value) {
if (value < 0) return 1;
if (value == value) return 0;
int dec = 0, sign = 0;
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
_ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign);
return sign;
}
inline int isinfinity(double x) { return !_finite(x); } inline int isinfinity(double x) { return !_finite(x); }
inline int isinfinity(long double x) { inline int isinfinity(long double x) {
return !_finite(static_cast<double>(x)); return !_finite(static_cast<double>(x));
...@@ -895,9 +914,6 @@ struct Arg : Value { ...@@ -895,9 +914,6 @@ struct Arg : Value {
template <typename Char> template <typename Char>
struct NamedArg; struct NamedArg;
template <typename T = void>
struct Null {};
// A helper class template to enable or disable overloads taking wide // A helper class template to enable or disable overloads taking wide
// characters and strings in MakeValue. // characters and strings in MakeValue.
template <typename T, typename Char> template <typename T, typename Char>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment