]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/20_util/from_chars/8.cc
Match: Support form 2 for vector signed integer .SAT_ADD
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / from_chars / 8.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
29ef50b6
JJ
2//
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)
7// any later version.
8
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.
13
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/>.
17
29ef50b6
JJ
18// { dg-do run { target c++23 } }
19// { dg-add-options ieee }
6c3b01db 20// { dg-additional-options "-DSKIP_LONG_DOUBLE" { target aarch64-*-vxworks* aarch64-*-rtems* } }
29ef50b6
JJ
21
22#include <charconv>
23#include <string>
24#include <limits>
25#include <stdfloat>
26#include <cmath>
27#include <cstdlib>
28#include <testsuite_hooks.h>
29
30// Test std::from_chars floating-point conversions.
31
32#if __cpp_lib_to_chars >= 201611L
33#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
34void
35test01()
36{
37 std::string s;
38 std::float64_t f64;
39 std::from_chars_result res;
40
41 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
42 std::chars_format::general, std::chars_format::hex })
43 {
44 s = "Info";
45 res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
46 VERIFY( std::isinf(f64) );
47 VERIFY( res.ptr == s.data() + 3 );
48 VERIFY( res.ec == std::errc{} );
49
50 s = "-INFIN";
51 res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
52 VERIFY( std::isinf(f64) );
53 VERIFY( f64 < 0 );
54 VERIFY( res.ptr == s.data() + 4 );
55 VERIFY( res.ec == std::errc{} );
56
57 s = "InFiNiTy aNd BeYoNd";
58 res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
59 VERIFY( std::isinf(f64) );
60 VERIFY( res.ptr == s.data() + 8 );
61 VERIFY( res.ec == std::errc{} );
62
63 s = "nAn";
64 res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
65 VERIFY( std::isnan(f64) );
66 VERIFY( res.ptr == s.data() + 3 );
67 VERIFY( res.ec == std::errc{} );
68
69 s = "-NAN()";
70 res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
71 VERIFY( std::isnan(f64) );
72 VERIFY( res.ptr == s.data() + s.length() );
73 VERIFY( res.ec == std::errc{} );
74 }
75}
76
77void
78test02()
79{
80 std::string s;
81 std::float64_t f64 = 1.0f64;
82 std::from_chars_result res;
83
84 s = "0x123";
85 res = std::from_chars(s.data(), s.data() + s.length(), f64);
86 VERIFY( f64 == 0.0f64 );
87 VERIFY( res.ptr == s.data() + 1 );
88 VERIFY( res.ec == std::errc{} );
89
90 f64 = 1.0f64;
91 res = std::from_chars(s.data(), s.data() + s.length(), f64,
92 std::chars_format::fixed);
93 VERIFY( f64 == 0.0f64 );
94 VERIFY( res.ptr == s.data() + 1 );
95 VERIFY( res.ec == std::errc{} );
96
97 f64 = 1.0f64;
98 res = std::from_chars(s.data(), s.data() + s.length(), f64,
99 std::chars_format::scientific);
100 VERIFY( f64 == 1.0f64 );
101 VERIFY( res.ptr == s.data() );
102 VERIFY( res.ec == std::errc::invalid_argument );
103
104 f64 = 1.0f64;
105 res = std::from_chars(s.data(), s.data() + s.length(), f64,
106 std::chars_format::general);
107 VERIFY( f64 == 0.0f64 );
108 VERIFY( res.ptr == s.data() + 1 );
109 VERIFY( res.ec == std::errc{} );
110
111 f64 = 1.0f64;
112 res = std::from_chars(s.data(), s.data() + s.length(), f64,
113 std::chars_format::hex);
114 VERIFY( f64 == 0.0f64 );
115 VERIFY( res.ptr == s.data() + 1 );
116 VERIFY( res.ec == std::errc{} );
117}
118
119void
120test03()
121{
122 std::string s;
123 std::float64_t f64 = 1.0f64;
124 std::from_chars_result res;
125
126 s = "0.5e+2azzz";
127 res = std::from_chars(s.data(), s.data() + s.length(), f64);
128 VERIFY( f64 == 0.5e+2f64 );
129 VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
130 VERIFY( res.ec == std::errc{} );
131
132 res = std::from_chars(s.data(), s.data() + s.length(), f64,
133 std::chars_format::fixed);
134 VERIFY( f64 == 0.5f64 );
135 VERIFY( res.ptr == s.data() + 3 );
136 VERIFY( res.ec == std::errc{} );
137
138 f64 = 1.0f64;
139 res = std::from_chars(s.data(), s.data() + s.length(), f64,
140 std::chars_format::scientific);
141 VERIFY( f64 == 0.5e+2f64 );
142 VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
143 VERIFY( res.ec == std::errc{} );
144
145 f64 = 1.0f64;
146 res = std::from_chars(s.data(), s.data() + s.length(), f64,
147 std::chars_format::general);
148 VERIFY( f64 == 0.5e+2f64 );
149 VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
150 VERIFY( res.ec == std::errc{} );
151
152 f64 = 1.0;
153 res = std::from_chars(s.data(), s.data() + s.length(), f64,
154 std::chars_format::hex);
155 VERIFY( f64 == 0x0.5Ep0f64 );
156 VERIFY( res.ptr == s.data() + 4 );
157 VERIFY( res.ec == std::errc{} );
158
159 s = "1.Ap-2zzz";
160 res = std::from_chars(s.data(), s.data() + s.length(), f64,
161 std::chars_format::hex);
162 VERIFY( f64 == 0.40625f64 );
163 VERIFY( res.ptr == s.data() + s.length() - 3 );
164 VERIFY( res.ec == std::errc{} );
165}
166
167void
168test04()
169{
170 // Huge input strings
171 std::string s(1000, '0');
172 std::float64_t f64 = 1.0f64;
173 std::from_chars_result res;
174 res = std::from_chars(s.data(), s.data() + s.length(), f64);
175 VERIFY( res.ptr == s.data() + s.length() );
176 VERIFY( res.ec == std::errc{} );
177 VERIFY( f64 == 0.0f64 );
178
179 s += ".5";
180 res = std::from_chars(s.data(), s.data() + s.length(), f64);
181 VERIFY( res.ptr == s.data() + s.length() );
182 VERIFY( res.ec == std::errc{} );
183 VERIFY( f64 == 0.5f64 );
184
185 s += "e2";
186 auto len = s.length();
187 s += std::string(1000, 'a');
188 res = std::from_chars(s.data(), s.data() + s.length(), f64);
189 VERIFY( res.ptr == s.data() + len );
190 VERIFY( res.ec == std::errc{} );
191 VERIFY( f64 == 50.f64 );
192}
193#endif
194
195using std::to_string;
196
197#ifdef __GLIBCXX_TYPE_INT_N_0
198std::string
199to_string(unsigned __GLIBCXX_TYPE_INT_N_0 val)
200{
201 using Limits = std::numeric_limits<unsigned __GLIBCXX_TYPE_INT_N_0>;
202 std::string s(Limits::digits10+2, '0');
203 for (auto iter = s.end(); val != 0; val /= 10)
204 *--iter = '0' + (val % 10);
205 return s;
206}
207#endif
208
209template<typename FloatT>
210void
211test_small_num()
212{
213 std::from_chars_result res;
214 FloatT flt;
215
216 // Small integer values that are exactly representable
217
218 for (int i = 0; i < 100; ++i)
219 {
220 std::string s = to_string(i);
221 int len = s.length();
222 s += "123";
223 const char* s1 = s.c_str();
224 const char* s1_end = s1 + len;
225
226 for (auto fmt : { std::chars_format::fixed,
227 std::chars_format::general,
228 std::chars_format::hex })
229 {
230 if (fmt == std::chars_format::hex && i > 9)
231 continue;
232
233 res = std::from_chars(s1, s1_end, flt, fmt);
234 VERIFY( res.ec == std::errc{} );
235 VERIFY( res.ptr == s1_end );
236 VERIFY( flt == i );
237 }
238
239 if (i > 9)
240 continue;
241
242 // Test single-digit integers with small exponents.
243
244 const char s2[] = { '.', *s1, 'e', '0', '0', '0', '1' };
245 const char* s2_end = s2 + sizeof(s2);
246
247 const char s3[] = { *s1, '0', 'e', '-', '0', '0', '1' };
248 const char* s3_end = s3 + sizeof(s3);
249
250 for (auto fmt : { std::chars_format::scientific,
251 std::chars_format::general })
252 {
253 res = std::from_chars(s2, s2_end, flt, fmt);
254 VERIFY( res.ec == std::errc{} );
255 VERIFY( res.ptr == s2_end );
256 VERIFY( flt == i );
257
258 res = std::from_chars(s3, s3_end, flt, fmt);
259 VERIFY( res.ec == std::errc{} );
260 VERIFY( res.ptr == s3_end );
261 VERIFY( flt == i );
262 }
263 }
264}
265
266void
267test05()
268{
269#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
270 test_small_num<std::float32_t>();
271#endif
272#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
273 test_small_num<std::float64_t>();
274#endif
275#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
276 test_small_num<std::float128_t>();
277#endif
278}
279
280template<typename FloatT, typename UIntT>
281void
282test_max_mantissa()
283{
284 using Float_limits = std::numeric_limits<FloatT>;
285 using UInt_limits = std::numeric_limits<UIntT>;
286
287 if (Float_limits::is_iec559 && Float_limits::digits < UInt_limits::digits)
288 {
1f378f6d 289#ifdef _GLIBCXX_USE_C99_MATH_FUNCS
29ef50b6
JJ
290 std::printf("Testing %d-bit float, using %zu-bit integer\n",
291 Float_limits::digits + (int)std::log2(Float_limits::max_exponent) + 1,
292 sizeof(UIntT) * __CHAR_BIT__);
293#endif
294
295 std::from_chars_result res;
296 FloatT flt;
297
298 for (int i = 0; i < 10; ++i)
299 {
300 // (1 << digits) - 1 is the maximum value of the mantissa
301 const auto val = ((UIntT)1 << Float_limits::digits) - 1 - i;
302 std::string s = to_string(val);
303 auto len = s.length();
304 s += "000"; // these should be ignored
305 for (auto fmt : { std::chars_format::fixed,
306 std::chars_format::general })
307 {
308 res = std::from_chars(s.data(), s.data() + len, flt, fmt);
309 VERIFY( res.ec == std::errc{} );
310 VERIFY( res.ptr == s.data() + len );
311 VERIFY( flt == val );
312 }
313 s.resize(len);
314 const auto orig_len = len;
315 s += "e+000";
316 len = s.length();
317 s += "111";
318 for (auto fmt : { std::chars_format::scientific,
319 std::chars_format::general })
320 {
321 res = std::from_chars(s.data(), s.data() + len, flt, fmt);
322 VERIFY( res.ec == std::errc{} );
323 VERIFY( res.ptr == s.data() + len );
324 VERIFY( flt == val );
325
326 std::string s2 = s.substr(0, len - 5);
327 s2.insert(s2.begin() + orig_len - 1, '.');
328 s2 += "e000000000001";
329 res = std::from_chars(s.data(), s.data() + len, flt, fmt);
330 VERIFY( res.ec == std::errc{} );
331 VERIFY( res.ptr == s.data() + len );
332 VERIFY( flt == val );
333 }
334 }
335 }
336}
337
338void
339test06()
340{
341#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
342 test_max_mantissa<std::float32_t, unsigned long>();
343#endif
344#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
345 test_max_mantissa<std::float64_t, unsigned long long>();
346#endif
5b178179 347#if defined(__GLIBCXX_TYPE_INT_N_0) && !defined SKIP_LONG_DOUBLE \
29ef50b6
JJ
348 && defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
349 test_max_mantissa<std::float128_t, unsigned __GLIBCXX_TYPE_INT_N_0>();
350#endif
351}
352#endif
353
354int
355main()
356{
357#if __cpp_lib_to_chars >= 201611L
358#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
359 test01();
360 test02();
361 test03();
362 test04();
363#endif
364 test05();
365 test06();
366#endif
367}