mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Fallback to ecvt if _ecvt_s is not available.
This commit is contained in:
68
format.h
68
format.h
@ -215,6 +215,22 @@ inline uint32_t clzll(uint64_t x) {
|
|||||||
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
namespace internal {
|
||||||
|
template <typename T = void>
|
||||||
|
struct Null {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy implementations of signbit and _ecvt_s called if corresponding system
|
||||||
|
// functions are not available. These methods are in the namespace fmt_system
|
||||||
|
// rather than fmt::internal to make sure they don't hide the potential
|
||||||
|
// overloads in the std namespace.
|
||||||
|
namespace fmt_system {
|
||||||
|
inline fmt::internal::Null<> signbit(...) { return fmt::internal::Null<>(); }
|
||||||
|
inline fmt::internal::Null<> _ecvt_s(...) { return fmt::internal::Null<>(); }
|
||||||
|
}
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt {
|
||||||
|
|
||||||
// Fix the warning about long long on older versions of GCC
|
// Fix the warning about long long on older versions of GCC
|
||||||
@ -579,42 +595,38 @@ class FixedBuffer : public fmt::Buffer<Char> {
|
|||||||
void grow(std::size_t size);
|
void grow(std::size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
||||||
class SignBit {
|
struct SignBit {
|
||||||
private:
|
double value;
|
||||||
double value_;
|
|
||||||
|
explicit SignBit(double val) : value(val) {}
|
||||||
|
|
||||||
int handle(int result) { return result; }
|
int handle(int result) { return result; }
|
||||||
|
|
||||||
int handle(fmt::internal::Null<>) {
|
int handle(Null<>) {
|
||||||
if (value_ < 0) return 1;
|
if (value < 0) return 1;
|
||||||
if (value_ == value_) return 0;
|
if (value == value) return 0;
|
||||||
int dec = 0, sign = 0;
|
|
||||||
|
struct Ecvt {
|
||||||
|
double value;
|
||||||
|
int sign;
|
||||||
|
int dec;
|
||||||
|
explicit Ecvt(double val) : value(val), sign(0), dec(0) {}
|
||||||
|
void handle(int) {}
|
||||||
|
void handle(Null<>) { ecvt(value, 0, &dec, &sign); }
|
||||||
|
} e(value);
|
||||||
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
|
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
|
||||||
_ecvt_s(buffer, sizeof(buffer), value_, 0, &dec, &sign);
|
using namespace fmt_system;
|
||||||
return sign;
|
e.handle(_ecvt_s(buffer, sizeof(buffer), value, 0, &e.dec, &e.sign));
|
||||||
}
|
return e.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();
|
// 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;
|
||||||
|
using namespace fmt_system;
|
||||||
|
return SignBit(x).handle(signbit(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
Reference in New Issue
Block a user