Daily bump.
[official-gcc.git] / libstdc++-v3 / testsuite / 20_util / from_chars / 5.cc
blobfa86ab7383cace2b5c8057d1428a1bb56b77c152
1 // Copyright (C) 2020-2021 Free Software Foundation, Inc.
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.
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 } }
21 #include <charconv>
22 #include <string>
23 #include <cmath>
24 #include <testsuite_hooks.h>
26 // Test std::from_chars error handling.
28 #if __cpp_lib_to_chars >= 201611L
29 void
30 test01()
32 std::from_chars_result r;
33 double d = 3.2;
34 std::string s;
36 for (auto p : { "", "*", ".", "-", "-*", "-.", "+", "+.", "+-", "-+", "+1",
37 ".p1", "-.p1",
38 "in", "inch", "+inf", "na", "nam", "+nan" })
40 s = p;
41 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
42 std::chars_format::general, std::chars_format::hex })
44 r = std::from_chars(s.data(), s.data() + s.length(), d, fmt);
45 VERIFY( r.ec == std::errc::invalid_argument );
46 VERIFY( r.ptr == s.data() );
47 VERIFY( d == 3.2 );
51 for (auto p : { ".e1", "-.e1" }) // These are valid patterns for hex format
53 s = p;
54 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
55 std::chars_format::general })
57 r = std::from_chars(s.data(), s.data() + s.length(), d, fmt);
58 VERIFY( r.ec == std::errc::invalid_argument );
59 VERIFY( r.ptr == s.data() );
60 VERIFY( d == 3.2 );
64 // scientific format requires an exponent
65 for (auto p : { "1.2", "-1.2", "1.2e", "-1.2e", "1.2e-", "-1.2e+" })
67 s = p;
68 r = std::from_chars(s.data(), s.data() + s.length(), d,
69 std::chars_format::scientific);
70 VERIFY( r.ec == std::errc::invalid_argument );
71 VERIFY( r.ptr == s.data() );
72 VERIFY( d == 3.2 );
75 // patterns that are invalid without the final character
76 for (auto p : { "1", ".1", "-1", "-.1",
77 "inf", "-inf", "nan", "-nan" })
79 s = p;
80 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
81 std::chars_format::general, std::chars_format::hex })
83 r = std::from_chars(s.data(), s.data() + s.length() - 1, d, fmt);
84 VERIFY( r.ec == std::errc::invalid_argument );
85 VERIFY( r.ptr == s.data() );
86 VERIFY( d == 3.2 );
91 void
92 test02()
94 std::from_chars_result r;
95 std::string s;
97 float f = 0.5;
98 // Overflow
99 s = "99999999999999999e999999999999999999";
100 r = std::from_chars(s.data(), s.data() + s.length(), f);
101 VERIFY( r.ec == std::errc::result_out_of_range );
102 VERIFY( r.ptr == s.data() + s.length() );
103 VERIFY( f == 0.5 );
105 s += '*';
106 r = std::from_chars(s.data(), s.data() + s.length(), f);
107 VERIFY( r.ec == std::errc::result_out_of_range );
108 VERIFY( r.ptr == s.data() + s.length() - 1 );
109 VERIFY( f == 0.5 );
111 s.insert(s.begin(), '-');
112 r = std::from_chars(s.data(), s.data() + s.length(), f);
113 VERIFY( r.ec == std::errc::result_out_of_range );
114 VERIFY( r.ptr == s.data() + s.length() - 1 );
115 VERIFY( f == 0.5 );
118 void
119 test03()
121 double d = 0.5;
122 // Underflow
123 std::string s("-1.2345e-9999zzz");
124 std::from_chars_result res;
125 res = std::from_chars(s.data(), s.data() + s.length(), d);
126 VERIFY( res.ptr == s.data() + s.length() - 3 );
127 VERIFY( res.ec == std::errc::result_out_of_range );
128 VERIFY( d == 0.5 );
130 res = std::from_chars(s.data() + 1, s.data() + s.length(), d);
131 VERIFY( res.ptr == s.data() + s.length() - 3 );
132 VERIFY( res.ec == std::errc::result_out_of_range );
133 VERIFY( d == 0.5 );
136 void
137 test04()
139 std::from_chars_result res;
140 std::string z(2000, '0');
141 // Invalid inputs for scientific format
142 for (const char* s : { "", "1", ".", ".0", ".5", "1e+", "1e+-1" })
144 for (auto len : { 0, 10, 100, 1000, 2000 })
146 auto str = z.substr(len) + s;
147 double d = 99.0;
148 res = std::from_chars(str.data(), str.data() + str.length(), d,
149 std::chars_format::scientific);
150 VERIFY( res.ec == std::errc::invalid_argument );
151 VERIFY( res.ptr == str.data() );
152 VERIFY( d == 99.0 );
156 #endif
159 main()
161 #if __cpp_lib_to_chars >= 201611L
162 test01();
163 test02();
164 test03();
165 test04();
166 #endif