mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Minor tweaks to better handle cygwin/clang.
This commit is contained in:
parent
b0e417cdde
commit
a1a7347464
@ -5,18 +5,18 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|
#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
|
||||||
|| defined(__arm__) \
|
|
||||||
|| defined(__MINGW32__))
|
|
||||||
#define FASTFLOAT_32BIT
|
|
||||||
#elif (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
|
|
||||||
|| defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
|
|| defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
|
||||||
|| defined(__MINGW64__) \
|
|| defined(__MINGW64__) \
|
||||||
|| defined(__s390x__) \
|
|| defined(__s390x__) \
|
||||||
|| (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)))
|
|| (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)))
|
||||||
#define FASTFLOAT_64BIT
|
#define FASTFLOAT_64BIT
|
||||||
|
#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|
||||||
|
|| defined(__arm__) \
|
||||||
|
|| defined(__MINGW32__))
|
||||||
|
#define FASTFLOAT_32BIT
|
||||||
#else
|
#else
|
||||||
#error Unknown platform
|
#error Unknown platform (not 32-bit, not 64-bit?)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
|
#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
|
||||||
@ -164,7 +164,7 @@ fastfloat_really_inline value128 full_multiplication(uint64_t a,
|
|||||||
// ARM64 has native support for 64-bit multiplications, no need to emulate
|
// ARM64 has native support for 64-bit multiplications, no need to emulate
|
||||||
answer.high = __umulh(a, b);
|
answer.high = __umulh(a, b);
|
||||||
answer.low = a * b;
|
answer.low = a * b;
|
||||||
#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64))
|
#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
|
||||||
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
|
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
|
||||||
#elif defined(FASTFLOAT_64BIT)
|
#elif defined(FASTFLOAT_64BIT)
|
||||||
__uint128_t r = ((__uint128_t)a) * b;
|
__uint128_t r = ((__uint128_t)a) * b;
|
||||||
|
|||||||
@ -30,15 +30,15 @@ void allvalues() {
|
|||||||
std::cerr << "parsing error ? " << buffer << std::endl;
|
std::cerr << "parsing error ? " << buffer << std::endl;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,v)) {
|
if (std::isnan(v)) {
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
|
||||||
<< std::endl;
|
|
||||||
abort();
|
|
||||||
} else if (std::isnan(v)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
if (!std::isnan(result_value)) {
|
||||||
std::cerr << "not nan" << buffer << std::endl;
|
std::cerr << "not nan" << buffer << std::endl;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,v)) {
|
||||||
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
||||||
|
<< std::endl;
|
||||||
|
abort();
|
||||||
} else if (result_value != v) {
|
} else if (result_value != v) {
|
||||||
std::cerr << "no match ? " << buffer << std::endl;
|
std::cerr << "no match ? " << buffer << std::endl;
|
||||||
std::cout << "started with " << std::hexfloat << v << std::endl;
|
std::cout << "started with " << std::hexfloat << v << std::endl;
|
||||||
|
|||||||
@ -20,16 +20,16 @@ bool basic_test_64bit(std::string vals, double val) {
|
|||||||
std::cerr << " I could not parse " << vals << std::endl;
|
std::cerr << " I could not parse " << vals << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,val)) {
|
if (std::isnan(val)) {
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
|
|
||||||
<< std::endl;
|
|
||||||
return false;
|
|
||||||
} else if (std::isnan(val)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
if (!std::isnan(result_value)) {
|
||||||
std::cerr << vals << std::endl;
|
std::cerr << vals << std::endl;
|
||||||
std::cerr << "not nan" << result_value << std::endl;
|
std::cerr << "not nan" << result_value << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,val)) {
|
||||||
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
} else if (result_value != val) {
|
} else if (result_value != val) {
|
||||||
std::cerr << vals << std::endl;
|
std::cerr << vals << std::endl;
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
|
||||||
|
|||||||
@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
ss.imbue(std::locale::classic());
|
ss.imbue(std::locale::classic());
|
||||||
ss << start;
|
ss << start;
|
||||||
ss >> d;
|
ss >> d;
|
||||||
size_t nread = ss.tellg();
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
|
*end = const_cast<char*>(start) + nread;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
float cygwin_strtof_l(const char* start, char** end) {
|
||||||
|
float d;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale::classic());
|
||||||
|
ss << start;
|
||||||
|
ss >> d;
|
||||||
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
*end = const_cast<char*>(start) + nread;
|
*end = const_cast<char*>(start) + nread;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -29,10 +43,10 @@ template <typename T> char *to_string(T d, char *buffer) {
|
|||||||
return buffer + written;
|
return buffer + written;
|
||||||
}
|
}
|
||||||
|
|
||||||
void strtod_from_string(const char * st, float& d) {
|
void strtof_from_string(const char * st, float& d) {
|
||||||
char *pr = (char *)st;
|
char *pr = (char *)st;
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
d = cygwin_strtod_l(st, &pr);
|
d = cygwin_strtof_l(st, &pr);
|
||||||
#elif defined(_WIN32)
|
#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);
|
||||||
@ -45,7 +59,7 @@ void strtod_from_string(const char * st, float& d) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void allvalues() {
|
bool allvalues() {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
|
for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
|
||||||
float v;
|
float v;
|
||||||
@ -68,15 +82,24 @@ void allvalues() {
|
|||||||
|
|
||||||
const char *string_end = to_string(midv, buffer);
|
const char *string_end = to_string(midv, buffer);
|
||||||
float str_answer;
|
float str_answer;
|
||||||
strtod_from_string(buffer, str_answer);
|
strtof_from_string(buffer, str_answer);
|
||||||
|
|
||||||
float result_value;
|
float result_value;
|
||||||
auto result = fast_float::from_chars(buffer, string_end, result_value);
|
auto result = fast_float::from_chars(buffer, string_end, result_value);
|
||||||
if (result.ec != std::errc()) {
|
if (result.ec != std::errc()) {
|
||||||
std::cerr << "parsing error ? " << buffer << std::endl;
|
std::cerr << "parsing error ? " << buffer << std::endl;
|
||||||
abort();
|
return false;
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,v)) {
|
if (std::isnan(v)) {
|
||||||
|
if (!std::isnan(result_value)) {
|
||||||
|
std::cerr << "not nan" << buffer << std::endl;
|
||||||
|
std::cerr << "v " << std::hexfloat << v << std::endl;
|
||||||
|
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
|
||||||
|
std::cerr << "midv " << std::hexfloat << midv << std::endl;
|
||||||
|
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,v)) {
|
||||||
std::cerr << buffer << std::endl;
|
std::cerr << buffer << std::endl;
|
||||||
std::cerr << "v " << std::hexfloat << v << std::endl;
|
std::cerr << "v " << std::hexfloat << v << std::endl;
|
||||||
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
|
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
|
||||||
@ -84,16 +107,7 @@ void allvalues() {
|
|||||||
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
|
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
abort();
|
return false;
|
||||||
} else if (std::isnan(v)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
|
||||||
std::cerr << "not nan" << buffer << std::endl;
|
|
||||||
std::cerr << "v " << std::hexfloat << v << std::endl;
|
|
||||||
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
|
|
||||||
std::cerr << "midv " << std::hexfloat << midv << std::endl;
|
|
||||||
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
} else if (result_value != str_answer) {
|
} else if (result_value != str_answer) {
|
||||||
std::cerr << "no match ? " << buffer << std::endl;
|
std::cerr << "no match ? " << buffer << std::endl;
|
||||||
std::cerr << "v " << std::hexfloat << v << std::endl;
|
std::cerr << "v " << std::hexfloat << v << std::endl;
|
||||||
@ -104,18 +118,26 @@ void allvalues() {
|
|||||||
std::cout << "round down to " << std::hexfloat << str_answer << std::endl;
|
std::cout << "round down to " << std::hexfloat << str_answer << std::endl;
|
||||||
std::cout << "got back " << std::hexfloat << result_value << std::endl;
|
std::cout << "got back " << std::hexfloat << result_value << std::endl;
|
||||||
std::cout << std::dec;
|
std::cout << std::dec;
|
||||||
abort();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Assert(bool Assertion) {
|
||||||
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
|
if (!Assertion) { std::cerr << "Omitting hard falure on msys/cygwin/sun systems."; }
|
||||||
|
#else
|
||||||
|
if (!Assertion) { throw std::runtime_error("bug"); }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
int main() {
|
int main() {
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
|
std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library as a gold standard." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
allvalues();
|
Assert(allvalues());
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "all ok" << std::endl;
|
std::cout << "all ok" << std::endl;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@ -30,16 +30,16 @@ void allvalues() {
|
|||||||
std::cerr << "parsing error ? " << buffer << std::endl;
|
std::cerr << "parsing error ? " << buffer << std::endl;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,v)) {
|
if (std::isnan(v)) {
|
||||||
std::cerr << buffer << std::endl;
|
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
|
||||||
<< std::endl;
|
|
||||||
abort();
|
|
||||||
} else if (std::isnan(v)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
if (!std::isnan(result_value)) {
|
||||||
std::cerr << "not nan" << buffer << std::endl;
|
std::cerr << "not nan" << buffer << std::endl;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,v)) {
|
||||||
|
std::cerr << buffer << std::endl;
|
||||||
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
||||||
|
<< std::endl;
|
||||||
|
abort();
|
||||||
} else if (result_value != v) {
|
} else if (result_value != v) {
|
||||||
std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl;
|
std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl;
|
||||||
std::cout << "started with " << std::hexfloat << v << std::endl;
|
std::cout << "started with " << std::hexfloat << v << std::endl;
|
||||||
|
|||||||
@ -60,12 +60,7 @@ void random_values(size_t N) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,v)) {
|
if (std::isnan(v)) {
|
||||||
std::cerr << buffer << std::endl;
|
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
|
||||||
<< std::endl;
|
|
||||||
abort();
|
|
||||||
} else if (std::isnan(v)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
if (!std::isnan(result_value)) {
|
||||||
std::cerr << "not nan" << buffer << std::endl;
|
std::cerr << "not nan" << buffer << std::endl;
|
||||||
errors++;
|
errors++;
|
||||||
@ -73,6 +68,11 @@ void random_values(size_t N) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,v)) {
|
||||||
|
std::cerr << buffer << std::endl;
|
||||||
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
||||||
|
<< std::endl;
|
||||||
|
abort();
|
||||||
} else if (result_value != v) {
|
} else if (result_value != v) {
|
||||||
std::cerr << "no match ? '" << buffer << "'" << std::endl;
|
std::cerr << "no match ? '" << buffer << "'" << std::endl;
|
||||||
std::cout << "started with " << std::hexfloat << v << std::endl;
|
std::cout << "started with " << std::hexfloat << v << std::endl;
|
||||||
|
|||||||
@ -3,8 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
inline void Assert(bool Assertion) {
|
inline void Assert(bool Assertion) {
|
||||||
if (!Assertion)
|
if (!Assertion) { throw std::runtime_error("bug"); }
|
||||||
throw std::runtime_error("bug");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@ -19,7 +19,21 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
ss.imbue(std::locale::classic());
|
ss.imbue(std::locale::classic());
|
||||||
ss << start;
|
ss << start;
|
||||||
ss >> d;
|
ss >> d;
|
||||||
size_t nread = ss.tellg();
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
|
*end = const_cast<char*>(start) + nread;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
float cygwin_strtof_l(const char* start, char** end) {
|
||||||
|
float d;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale::classic());
|
||||||
|
ss << start;
|
||||||
|
ss >> d;
|
||||||
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
*end = const_cast<char*>(start) + nread;
|
*end = const_cast<char*>(start) + nread;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -29,7 +43,9 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
std::pair<double, bool> strtod_from_string(const char *st) {
|
std::pair<double, bool> strtod_from_string(const char *st) {
|
||||||
double d;
|
double d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#ifdef _WIN32
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
|
d = cygwin_strtod_l(st, &pr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||||
d = _strtod_l(st, &pr, c_locale);
|
d = _strtod_l(st, &pr, c_locale);
|
||||||
#else
|
#else
|
||||||
@ -47,7 +63,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
|
|||||||
float d;
|
float d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
d = cygwin_strtod_l(st, &pr);
|
d = cygwin_strtof_l(st, &pr);
|
||||||
#elif defined(_WIN32)
|
#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);
|
||||||
|
|||||||
@ -62,12 +62,7 @@ void random_values(size_t N) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(copysign(1,result_value) != copysign(1,v)) {
|
if (std::isnan(v)) {
|
||||||
std::cerr << buffer << std::endl;
|
|
||||||
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
|
||||||
<< std::endl;
|
|
||||||
abort();
|
|
||||||
} else if (std::isnan(v)) {
|
|
||||||
if (!std::isnan(result_value)) {
|
if (!std::isnan(result_value)) {
|
||||||
std::cerr << "not nan" << buffer << std::endl;
|
std::cerr << "not nan" << buffer << std::endl;
|
||||||
errors++;
|
errors++;
|
||||||
@ -75,6 +70,11 @@ void random_values(size_t N) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(copysign(1,result_value) != copysign(1,v)) {
|
||||||
|
std::cerr << buffer << std::endl;
|
||||||
|
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
|
||||||
|
<< std::endl;
|
||||||
|
abort();
|
||||||
} else if (result_value != v) {
|
} else if (result_value != v) {
|
||||||
std::cerr << "no match ? " << buffer << std::endl;
|
std::cerr << "no match ? " << buffer << std::endl;
|
||||||
std::cout << "started with " << std::hexfloat << v << std::endl;
|
std::cout << "started with " << std::hexfloat << v << std::endl;
|
||||||
|
|||||||
@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
ss.imbue(std::locale::classic());
|
ss.imbue(std::locale::classic());
|
||||||
ss << start;
|
ss << start;
|
||||||
ss >> d;
|
ss >> d;
|
||||||
size_t nread = ss.tellg();
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
|
*end = const_cast<char*>(start) + nread;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
float cygwin_strtof_l(const char* start, char** end) {
|
||||||
|
float d;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale::classic());
|
||||||
|
ss << start;
|
||||||
|
ss >> d;
|
||||||
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
*end = const_cast<char*>(start) + nread;
|
*end = const_cast<char*>(start) + nread;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -111,7 +125,9 @@ size_t build_random_string(RandomEngine &rand, char *buffer) {
|
|||||||
std::pair<double, bool> strtod_from_string(char *st) {
|
std::pair<double, bool> strtod_from_string(char *st) {
|
||||||
double d;
|
double d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#ifdef _WIN32
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
|
d = cygwin_strtod_l(st, &pr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||||
d = _strtod_l(st, &pr, c_locale);
|
d = _strtod_l(st, &pr, c_locale);
|
||||||
#else
|
#else
|
||||||
@ -129,7 +145,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
|
|||||||
float d;
|
float d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
d = cygwin_strtod_l(st, &pr);
|
d = cygwin_strtof_l(st, &pr);
|
||||||
#elif defined(_WIN32)
|
#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);
|
||||||
@ -205,13 +221,17 @@ bool tester(uint64_t seed, size_t volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
|
std::cout << "Warning: msys/cygwin or solaris detected." << std::endl;
|
||||||
#endif
|
return EXIT_SUCCESS;
|
||||||
|
#else
|
||||||
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;
|
||||||
}
|
}
|
||||||
std::cout << "Failure." << std::endl;
|
std::cout << "Failure." << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,21 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
ss.imbue(std::locale::classic());
|
ss.imbue(std::locale::classic());
|
||||||
ss << start;
|
ss << start;
|
||||||
ss >> d;
|
ss >> d;
|
||||||
size_t nread = ss.tellg();
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
|
*end = const_cast<char*>(start) + nread;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
float cygwin_strtof_l(const char* start, char** end) {
|
||||||
|
float d;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale::classic());
|
||||||
|
ss << start;
|
||||||
|
ss >> d;
|
||||||
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
*end = const_cast<char*>(start) + nread;
|
*end = const_cast<char*>(start) + nread;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -106,7 +120,9 @@ size_t build_random_string(RandomEngine &rand, char *buffer) {
|
|||||||
std::pair<double, bool> strtod_from_string(char *st) {
|
std::pair<double, bool> strtod_from_string(char *st) {
|
||||||
double d;
|
double d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#ifdef _WIN32
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
|
d = cygwin_strtod_l(st, &pr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||||
d = _strtod_l(st, &pr, c_locale);
|
d = _strtod_l(st, &pr, c_locale);
|
||||||
#else
|
#else
|
||||||
@ -124,7 +140,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
|
|||||||
float d;
|
float d;
|
||||||
char *pr;
|
char *pr;
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
d = cygwin_strtod_l(st, &pr);
|
d = cygwin_strtof_l(st, &pr);
|
||||||
#elif defined(_WIN32)
|
#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);
|
||||||
@ -202,11 +218,13 @@ bool tester(uint64_t seed, size_t volume) {
|
|||||||
int main() {
|
int main() {
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
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;
|
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
|
return EXIT_SUCCESS;
|
||||||
|
#else
|
||||||
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;
|
||||||
}
|
}
|
||||||
std::cout << "Failure." << std::endl;
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,15 +15,32 @@ double cygwin_strtod_l(const char* start, char** end) {
|
|||||||
ss.imbue(std::locale::classic());
|
ss.imbue(std::locale::classic());
|
||||||
ss << start;
|
ss << start;
|
||||||
ss >> d;
|
ss >> d;
|
||||||
size_t nread = ss.tellg();
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
|
*end = const_cast<char*>(start) + nread;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
float cygwin_strtof_l(const char* start, char** end) {
|
||||||
|
float d;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale::classic());
|
||||||
|
ss << start;
|
||||||
|
ss >> d;
|
||||||
|
if(ss.fail()) { *end = nullptr; }
|
||||||
|
if(ss.eof()) { ss.clear(); }
|
||||||
|
auto nread = ss.tellg();
|
||||||
*end = const_cast<char*>(start) + nread;
|
*end = const_cast<char*>(start) + nread;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void Assert(bool Assertion) {
|
inline void Assert(bool Assertion) {
|
||||||
if (!Assertion)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
throw std::runtime_error("bug");
|
if (!Assertion) { std::cerr << "Omitting hard falure on msys/cygwin/sun systems."; }
|
||||||
|
#else
|
||||||
|
if (!Assertion) { throw std::runtime_error("bug"); }
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> std::string to_string(T d) {
|
template <typename T> std::string to_string(T d) {
|
||||||
@ -70,7 +87,9 @@ void strtod_from_string(const std::string &st, T& d);
|
|||||||
template <>
|
template <>
|
||||||
void strtod_from_string(const std::string &st, double& d) {
|
void strtod_from_string(const std::string &st, double& d) {
|
||||||
char *pr = (char *)st.c_str();
|
char *pr = (char *)st.c_str();
|
||||||
#ifdef _WIN32
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
|
d = cygwin_strtod_l(pr, &pr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||||
d = _strtod_l(st.c_str(), &pr, c_locale);
|
d = _strtod_l(st.c_str(), &pr, c_locale);
|
||||||
#else
|
#else
|
||||||
@ -86,7 +105,7 @@ 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.c_str();
|
char *pr = (char *)st.c_str();
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
d = cygwin_strtod_l(st.c_str(), &pr);
|
d = cygwin_strtof_l(st.c_str(), &pr);
|
||||||
#elif defined(_WIN32)
|
#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.c_str(), &pr, c_locale);
|
d = _strtof_l(st.c_str(), &pr, c_locale);
|
||||||
@ -237,7 +256,7 @@ bool partow_test() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
|
||||||
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;
|
std::cout << "Warning: msys/cygwin or solaris detected." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::cout << "32 bits checks" << std::endl;
|
std::cout << "32 bits checks" << std::endl;
|
||||||
Assert(partow_test<float>());
|
Assert(partow_test<float>());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user