Another tweak.

This commit is contained in:
Daniel Lemire 2020-10-21 16:56:44 -04:00
parent 59f4535adf
commit 609c48c2a2
3 changed files with 75 additions and 4 deletions

View File

@ -4,6 +4,25 @@
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
// Anything at all that is related to cygwin, msys and so forth will
// always use this fallback because we cannot rely on it behaving as normal
// gcc.
#include <locale>
#include <sstream>
// workaround for CYGWIN
double cygwin_strtod_l(const char* start, char** end) {
double d;
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << start;
ss >> d;
size_t nread = ss.tellg();
*end = const_cast<char*>(start) + nread;
return d;
}
#endif
template <typename T> char *to_string(T d, char *buffer) { template <typename T> char *to_string(T d, char *buffer) {
auto written = std::snprintf(buffer, 64, "%.*e", auto written = std::snprintf(buffer, 64, "%.*e",
std::numeric_limits<T>::max_digits10 - 1, d); std::numeric_limits<T>::max_digits10 - 1, d);
@ -12,7 +31,9 @@ template <typename T> char *to_string(T d, char *buffer) {
void strtod_from_string(const char * st, float& d) { void strtod_from_string(const char * st, float& d) {
char *pr = (char *)st; char *pr = (char *)st;
#ifdef _WIN32 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
d = cygwin_strtod_l(st, &pr, c_locale);
#elif defined(_WIN32)
static _locale_t c_locale = _create_locale(LC_ALL, "C"); static _locale_t c_locale = _create_locale(LC_ALL, "C");
d = _strtof_l(st, &pr, c_locale); d = _strtof_l(st, &pr, c_locale);
#else #else
@ -73,6 +94,9 @@ void allvalues() {
} }
int main() { int main() {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
#endif
allvalues(); allvalues();
std::cout << std::endl; std::cout << std::endl;
std::cout << "all ok" << std::endl; std::cout << "all ok" << std::endl;

View File

@ -2,6 +2,25 @@
#include <cstdint> #include <cstdint>
#include <random> #include <random>
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
// Anything at all that is related to cygwin, msys and so forth will
// always use this fallback because we cannot rely on it behaving as normal
// gcc.
#include <locale>
#include <sstream>
// workaround for CYGWIN
double cygwin_strtod_l(const char* start, char** end) {
double d;
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << start;
ss >> d;
size_t nread = ss.tellg();
*end = const_cast<char*>(start) + nread;
return d;
}
#endif
class RandomEngine { class RandomEngine {
public: public:
RandomEngine() = delete; RandomEngine() = delete;
@ -103,7 +122,9 @@ std::pair<double, bool> strtod_from_string(char *st) {
std::pair<float, bool> strtof_from_string(char *st) { std::pair<float, bool> strtof_from_string(char *st) {
float d; float d;
char *pr; char *pr;
#ifdef _WIN32 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
d = cygwin_strtod_l(st, &pr, c_locale);
#elif defined(_WIN32)
static _locale_t c_locale = _create_locale(LC_ALL, "C"); static _locale_t c_locale = _create_locale(LC_ALL, "C");
d = _strtof_l(st, &pr, c_locale); d = _strtof_l(st, &pr, c_locale);
#else #else
@ -178,6 +199,9 @@ bool tester(int seed, size_t volume) {
} }
int main() { int main() {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
#endif
if (tester(1234344, 100000000)) { if (tester(1234344, 100000000)) {
std::cout << "All tests ok." << std::endl; std::cout << "All tests ok." << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -2,6 +2,25 @@
#include <vector> #include <vector>
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
// Anything at all that is related to cygwin, msys and so forth will
// always use this fallback because we cannot rely on it behaving as normal
// gcc.
#include <locale>
#include <sstream>
// workaround for CYGWIN
double cygwin_strtod_l(const char* start, char** end) {
double d;
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << start;
ss >> d;
size_t nread = ss.tellg();
*end = const_cast<char*>(start) + nread;
return d;
}
#endif
inline void Assert(bool Assertion) { inline void Assert(bool Assertion) {
if (!Assertion) if (!Assertion)
throw std::runtime_error("bug"); throw std::runtime_error("bug");
@ -66,7 +85,9 @@ void strtod_from_string(const std::string &st, double& d) {
template <> template <>
void strtod_from_string(const std::string &st, float& d) { void strtod_from_string(const std::string &st, float& d) {
char *pr = (char *)st.data(); char *pr = (char *)st.data();
#ifdef _WIN32 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
d = cygwin_strtod_l(st, &pr, c_locale);
#elif defined(_WIN32)
static _locale_t c_locale = _create_locale(LC_ALL, "C"); static _locale_t c_locale = _create_locale(LC_ALL, "C");
d = _strtof_l(st.data(), &pr, c_locale); d = _strtof_l(st.data(), &pr, c_locale);
#else #else
@ -215,7 +236,9 @@ bool partow_test() {
int main() { int main() {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
#endif
std::cout << "32 bits checks" << std::endl; std::cout << "32 bits checks" << std::endl;
Assert(partow_test<float>()); Assert(partow_test<float>());
Assert(test<float>()); Assert(test<float>());