@@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) {
17
17
ss.imbue (std::locale::classic ());
18
18
ss << start;
19
19
ss >> d;
20
- size_t nread = ss.tellg ();
20
+ if (ss.fail ()) { *end = nullptr ; }
21
+ if (ss.eof ()) { ss.clear (); }
22
+ auto nread = ss.tellg ();
23
+ *end = const_cast <char *>(start) + nread;
24
+ return d;
25
+ }
26
+ float cygwin_strtof_l (const char * start, char ** end) {
27
+ float d;
28
+ std::stringstream ss;
29
+ ss.imbue (std::locale::classic ());
30
+ ss << start;
31
+ ss >> d;
32
+ if (ss.fail ()) { *end = nullptr ; }
33
+ if (ss.eof ()) { ss.clear (); }
34
+ auto nread = ss.tellg ();
21
35
*end = const_cast <char *>(start) + nread;
22
36
return d;
23
37
}
@@ -29,10 +43,10 @@ template <typename T> char *to_string(T d, char *buffer) {
29
43
return buffer + written;
30
44
}
31
45
32
- void strtod_from_string (const char * st, float & d) {
46
+ void strtof_from_string (const char * st, float & d) {
33
47
char *pr = (char *)st;
34
48
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
35
- d = cygwin_strtod_l (st, &pr);
49
+ d = cygwin_strtof_l (st, &pr);
36
50
#elif defined(_WIN32)
37
51
static _locale_t c_locale = _create_locale (LC_ALL, " C" );
38
52
d = _strtof_l (st, &pr, c_locale);
@@ -45,7 +59,7 @@ void strtod_from_string(const char * st, float& d) {
45
59
}
46
60
}
47
61
48
- void allvalues () {
62
+ bool allvalues () {
49
63
char buffer[64 ];
50
64
for (uint64_t w = 0 ; w <= 0xFFFFFFFF ; w++) {
51
65
float v;
@@ -68,32 +82,32 @@ void allvalues() {
68
82
69
83
const char *string_end = to_string (midv, buffer);
70
84
float str_answer;
71
- strtod_from_string (buffer, str_answer);
85
+ strtof_from_string (buffer, str_answer);
72
86
73
87
float result_value;
74
88
auto result = fast_float::from_chars (buffer, string_end, result_value);
75
89
if (result.ec != std::errc ()) {
76
90
std::cerr << " parsing error ? " << buffer << std::endl;
77
- abort () ;
91
+ return false ;
78
92
}
79
- if (copysign (1 ,result_value) != copysign (1 ,v)) {
80
- std::cerr << buffer << std::endl;
81
- std::cerr << " v " << std::hexfloat << v << std::endl;
82
- std::cerr << " v2 " << std::hexfloat << v2 << std::endl;
83
- std::cerr << " midv " << std::hexfloat << midv << std::endl;
84
- std::cerr << " expected_midv " << std::hexfloat << expected_midv << std::endl;
85
- std::cerr << " I got " << std::hexfloat << result_value << " but I was expecting " << v
86
- << std::endl;
87
- abort ();
88
- } else if (std::isnan (v)) {
93
+ if (std::isnan (v)) {
89
94
if (!std::isnan (result_value)) {
90
95
std::cerr << " not nan" << buffer << std::endl;
91
96
std::cerr << " v " << std::hexfloat << v << std::endl;
92
97
std::cerr << " v2 " << std::hexfloat << v2 << std::endl;
93
98
std::cerr << " midv " << std::hexfloat << midv << std::endl;
94
99
std::cerr << " expected_midv " << std::hexfloat << expected_midv << std::endl;
95
- abort () ;
100
+ return false ;
96
101
}
102
+ } else if (copysign (1 ,result_value) != copysign (1 ,v)) {
103
+ std::cerr << buffer << std::endl;
104
+ std::cerr << " v " << std::hexfloat << v << std::endl;
105
+ std::cerr << " v2 " << std::hexfloat << v2 << std::endl;
106
+ std::cerr << " midv " << std::hexfloat << midv << std::endl;
107
+ std::cerr << " expected_midv " << std::hexfloat << expected_midv << std::endl;
108
+ std::cerr << " I got " << std::hexfloat << result_value << " but I was expecting " << v
109
+ << std::endl;
110
+ return false ;
97
111
} else if (result_value != str_answer) {
98
112
std::cerr << " no match ? " << buffer << std::endl;
99
113
std::cerr << " v " << std::hexfloat << v << std::endl;
@@ -104,18 +118,26 @@ void allvalues() {
104
118
std::cout << " round down to " << std::hexfloat << str_answer << std::endl;
105
119
std::cout << " got back " << std::hexfloat << result_value << std::endl;
106
120
std::cout << std::dec;
107
- abort () ;
121
+ return false ;
108
122
}
109
123
}
110
124
}
111
125
std::cout << std::endl;
126
+ return true ;
112
127
}
113
128
129
+ inline void Assert (bool Assertion) {
130
+ #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
131
+ if (!Assertion) { std::cerr << " Omitting hard falure on msys/cygwin/sun systems." ; }
132
+ #else
133
+ if (!Assertion) { throw std::runtime_error (" bug" ); }
134
+ #endif
135
+ }
114
136
int main () {
115
137
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
116
- 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;
138
+ 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;
117
139
#endif
118
- allvalues ();
140
+ Assert ( allvalues () );
119
141
std::cout << std::endl;
120
142
std::cout << " all ok" << std::endl;
121
143
return EXIT_SUCCESS;
0 commit comments