1 // Copyright (C) 2020 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // <charconv> is supported in C++14 as a GNU extension
19 // { dg-do run { target c++14 } }
26 #include <testsuite_hooks.h>
28 // Test std::from_chars floating-point conversions.
35 std::from_chars_result res
;
37 for (auto fmt
: { std::chars_format::fixed
, std::chars_format::scientific
,
38 std::chars_format::general
, std::chars_format::hex
})
41 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
42 VERIFY( std::isinf(d
) );
43 VERIFY( res
.ptr
== s
.data() + 3 );
44 VERIFY( res
.ec
== std::errc
{} );
47 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
48 VERIFY( std::isinf(d
) );
50 VERIFY( res
.ptr
== s
.data() + 4 );
51 VERIFY( res
.ec
== std::errc
{} );
53 s
= "InFiNiTy aNd BeYoNd";
54 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
55 VERIFY( std::isinf(d
) );
56 VERIFY( res
.ptr
== s
.data() + 8 );
57 VERIFY( res
.ec
== std::errc
{} );
60 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
61 VERIFY( std::isnan(d
) );
62 VERIFY( res
.ptr
== s
.data() + 3 );
63 VERIFY( res
.ec
== std::errc
{} );
66 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
67 VERIFY( std::isnan(d
) );
68 VERIFY( res
.ptr
== s
.data() + s
.length() );
69 VERIFY( res
.ec
== std::errc
{} );
78 std::from_chars_result res
;
81 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
83 VERIFY( res
.ptr
== s
.data() + 1 );
84 VERIFY( res
.ec
== std::errc
{} );
87 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
88 std::chars_format::fixed
);
90 VERIFY( res
.ptr
== s
.data() + 1 );
91 VERIFY( res
.ec
== std::errc
{} );
94 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
95 std::chars_format::scientific
);
97 VERIFY( res
.ptr
== s
.data() );
98 VERIFY( res
.ec
== std::errc::invalid_argument
);
101 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
102 std::chars_format::general
);
104 VERIFY( res
.ptr
== s
.data() + 1 );
105 VERIFY( res
.ec
== std::errc
{} );
108 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
109 std::chars_format::hex
);
111 VERIFY( res
.ptr
== s
.data() + 1 );
112 VERIFY( res
.ec
== std::errc
{} );
120 std::from_chars_result res
;
123 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
124 VERIFY( d
== 0.5e+2 );
125 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
126 VERIFY( res
.ec
== std::errc
{} );
128 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
129 std::chars_format::fixed
);
131 VERIFY( res
.ptr
== s
.data() + 3 );
132 VERIFY( res
.ec
== std::errc
{} );
135 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
136 std::chars_format::scientific
);
137 VERIFY( d
== 0.5e+2 );
138 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
139 VERIFY( res
.ec
== std::errc
{} );
142 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
143 std::chars_format::general
);
144 VERIFY( d
== 0.5e+2 );
145 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
146 VERIFY( res
.ec
== std::errc
{} );
149 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
150 std::chars_format::hex
);
151 VERIFY( d
== 0x0.5Ep0
);
152 VERIFY( res
.ptr
== s
.data() + 4 );
153 VERIFY( res
.ec
== std::errc
{} );
156 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
157 std::chars_format::hex
);
158 VERIFY( d
== 0.40625 );
159 VERIFY( res
.ptr
== s
.data() + s
.length() - 3 );
160 VERIFY( res
.ec
== std::errc
{} );
166 // Huge input strings
167 std::string
s(1000, '0');
169 std::from_chars_result res
;
170 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
171 VERIFY( res
.ptr
== s
.data() + s
.length() );
172 VERIFY( res
.ec
== std::errc
{} );
176 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
177 VERIFY( res
.ptr
== s
.data() + s
.length() );
178 VERIFY( res
.ec
== std::errc
{} );
182 auto len
= s
.length();
183 s
+= std::string(1000, 'a');
184 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
185 VERIFY( res
.ptr
== s
.data() + len
);
186 VERIFY( res
.ec
== std::errc
{} );
190 using std::to_string
;
192 #ifdef __GLIBCXX_TYPE_INT_N_0
194 to_string(unsigned __GLIBCXX_TYPE_INT_N_0 val
)
196 using Limits
= std::numeric_limits
<unsigned __GLIBCXX_TYPE_INT_N_0
>;
197 std::string
s(Limits::digits10
+2, '0');
198 for (auto iter
= s
.end(); val
!= 0; val
/= 10)
199 *--iter
= '0' + (val
% 10);
207 std::from_chars_result res
;
212 // Small integer values that are exactly representable
214 for (int i
= 0; i
< 100; ++i
)
216 std::string s
= to_string(i
);
217 int len
= s
.length();
219 const char* s1
= s
.c_str();
220 const char* s1_end
= s1
+ len
;
222 for (auto fmt
: { std::chars_format::fixed
,
223 std::chars_format::general
,
224 std::chars_format::hex
})
226 if (fmt
== std::chars_format::hex
&& i
> 9)
229 res
= std::from_chars(s1
, s1_end
, flt
, fmt
);
230 VERIFY( res
.ec
== std::errc
{} );
231 VERIFY( res
.ptr
== s1_end
);
234 res
= std::from_chars(s1
, s1_end
, dbl
, fmt
);
235 VERIFY( res
.ec
== std::errc
{} );
236 VERIFY( res
.ptr
== s1_end
);
239 res
= std::from_chars(s1
, s1_end
, ldbl
, fmt
);
240 VERIFY( res
.ec
== std::errc
{} );
241 VERIFY( res
.ptr
== s1_end
);
248 // Test single-digit integers with small exponents.
250 const char s2
[] = { '.', *s1
, 'e', '0', '0', '0', '1' };
251 const char* s2_end
= s2
+ sizeof(s2
);
253 const char s3
[] = { *s1
, '0', 'e', '-', '0', '0', '1' };
254 const char* s3_end
= s3
+ sizeof(s3
);
256 for (auto fmt
: { std::chars_format::scientific
,
257 std::chars_format::general
})
259 res
= std::from_chars(s2
, s2_end
, flt
, fmt
);
260 VERIFY( res
.ec
== std::errc
{} );
261 VERIFY( res
.ptr
== s2_end
);
264 res
= std::from_chars(s3
, s3_end
, flt
, fmt
);
265 VERIFY( res
.ec
== std::errc
{} );
266 VERIFY( res
.ptr
== s3_end
);
269 res
= std::from_chars(s2
, s2_end
, dbl
, fmt
);
270 VERIFY( res
.ec
== std::errc
{} );
271 VERIFY( res
.ptr
== s2_end
);
274 res
= std::from_chars(s3
, s3_end
, dbl
, fmt
);
275 VERIFY( res
.ec
== std::errc
{} );
276 VERIFY( res
.ptr
== s3_end
);
279 res
= std::from_chars(s2
, s2_end
, ldbl
, fmt
);
280 VERIFY( res
.ec
== std::errc
{} );
281 VERIFY( res
.ptr
== s2_end
);
284 res
= std::from_chars(s3
, s3_end
, ldbl
, fmt
);
285 VERIFY( res
.ec
== std::errc
{} );
286 VERIFY( res
.ptr
== s3_end
);
292 template<typename FloatT
, typename UIntT
>
296 using Float_limits
= std::numeric_limits
<FloatT
>;
297 using UInt_limits
= std::numeric_limits
<UIntT
>;
299 if constexpr (Float_limits::is_iec559
300 && Float_limits::digits
< UInt_limits::digits
)
302 std::printf("Testing %d-bit float, using %zu-bit integer\n",
303 Float_limits::digits
+ (int)std::log2(Float_limits::max_exponent
) + 1,
304 sizeof(UIntT
) * __CHAR_BIT__
);
306 std::from_chars_result res
;
309 for (int i
= 0; i
< 10; ++i
)
311 // (1 << digits) - 1 is the maximum value of the mantissa
312 const auto val
= ((UIntT
)1 << Float_limits::digits
) - 1 - i
;
313 std::string s
= to_string(val
);
314 auto len
= s
.length();
315 s
+= "000"; // these should be ignored
316 for (auto fmt
: { std::chars_format::fixed
,
317 std::chars_format::general
})
319 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
320 VERIFY( res
.ec
== std::errc
{} );
321 VERIFY( res
.ptr
== s
.data() + len
);
322 VERIFY( flt
== val
);
325 const auto orig_len
= len
;
329 for (auto fmt
: { std::chars_format::scientific
,
330 std::chars_format::general
})
332 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
333 VERIFY( res
.ec
== std::errc
{} );
334 VERIFY( res
.ptr
== s
.data() + len
);
335 VERIFY( flt
== val
);
337 std::string s2
= s
.substr(0, len
- 5);
338 s2
.insert(s2
.cbegin() + orig_len
- 1, '.');
339 s2
+= "e000000000001";
340 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
341 VERIFY( res
.ec
== std::errc
{} );
342 VERIFY( res
.ptr
== s
.data() + len
);
343 VERIFY( flt
== val
);
352 test_max_mantissa
<float, unsigned long>();
353 test_max_mantissa
<double, unsigned long long>();
354 #ifdef __GLIBCXX_TYPE_INT_N_0
355 test_max_mantissa
<long double, unsigned __GLIBCXX_TYPE_INT_N_0
>();