]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/20_util/from_chars/5.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / from_chars / 5.cc
CommitLineData
99dee823 1// Copyright (C) 2020-2021 Free Software Foundation, Inc.
932fbc86
JW
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
18// <charconv> is supported in C++14 as a GNU extension
19// { dg-do run { target c++14 } }
20
21#include <charconv>
22#include <string>
23#include <cmath>
24#include <testsuite_hooks.h>
25
26// Test std::from_chars error handling.
27
2251b4a5
JW
28// As of July 2020 __cpp_lib_to_chars is not defined, but std::from_chars
29// works for floating-point types when _GLIBCXX_HAVE_USELOCALE is defined.
30#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE
932fbc86
JW
31void
32test01()
33{
34 std::from_chars_result r;
35 double d = 3.2;
36 std::string s;
37
38 for (auto p : { "", "*", ".", "-", "-*", "-.", "+", "+.", "+-", "-+", "+1",
39 ".p1", "-.p1",
40 "in", "inch", "+inf", "na", "nam", "+nan" })
41 {
42 s = p;
43 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
44 std::chars_format::general, std::chars_format::hex })
45 {
46 r = std::from_chars(s.data(), s.data() + s.length(), d, fmt);
47 VERIFY( r.ec == std::errc::invalid_argument );
48 VERIFY( r.ptr == s.data() );
49 VERIFY( d == 3.2 );
50 }
51 }
52
53 for (auto p : { ".e1", "-.e1" }) // These are valid patterns for hex format
54 {
55 s = p;
56 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
57 std::chars_format::general })
58 {
59 r = std::from_chars(s.data(), s.data() + s.length(), d, fmt);
60 VERIFY( r.ec == std::errc::invalid_argument );
61 VERIFY( r.ptr == s.data() );
62 VERIFY( d == 3.2 );
63 }
64 }
65
66 // scientific format requires an exponent
67 for (auto p : { "1.2", "-1.2", "1.2e", "-1.2e", "1.2e-", "-1.2e+" })
68 {
69 s = p;
70 r = std::from_chars(s.data(), s.data() + s.length(), d,
71 std::chars_format::scientific);
72 VERIFY( r.ec == std::errc::invalid_argument );
73 VERIFY( r.ptr == s.data() );
74 VERIFY( d == 3.2 );
75 }
76
77 // patterns that are invalid without the final character
78 for (auto p : { "1", ".1", "-1", "-.1",
79 "inf", "-inf", "nan", "-nan" })
80 {
81 s = p;
82 for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
83 std::chars_format::general, std::chars_format::hex })
84 {
85 r = std::from_chars(s.data(), s.data() + s.length() - 1, d, fmt);
86 VERIFY( r.ec == std::errc::invalid_argument );
87 VERIFY( r.ptr == s.data() );
88 VERIFY( d == 3.2 );
89 }
90 }
91}
92
93void
94test02()
95{
96 std::from_chars_result r;
97 std::string s;
98
99 float f = 0.5;
100 // Overflow
101 s = "99999999999999999e999999999999999999";
102 r = std::from_chars(s.data(), s.data() + s.length(), f);
103 VERIFY( r.ec == std::errc::result_out_of_range );
104 VERIFY( r.ptr == s.data() + s.length() );
105 VERIFY( f == 0.5 );
106
107 s += '*';
108 r = std::from_chars(s.data(), s.data() + s.length(), f);
109 VERIFY( r.ec == std::errc::result_out_of_range );
110 VERIFY( r.ptr == s.data() + s.length() - 1 );
111 VERIFY( f == 0.5 );
112
113 s.insert(s.begin(), '-');
114 r = std::from_chars(s.data(), s.data() + s.length(), f);
115 VERIFY( r.ec == std::errc::result_out_of_range );
116 VERIFY( r.ptr == s.data() + s.length() - 1 );
117 VERIFY( f == 0.5 );
118}
119
120void
121test03()
122{
123 double d = 0.5;
124 // Underflow
125 std::string s("-1.2345e-9999zzz");
126 std::from_chars_result res;
127 res = std::from_chars(s.data(), s.data() + s.length(), d);
128 VERIFY( res.ptr == s.data() + s.length() - 3 );
129 VERIFY( res.ec == std::errc::result_out_of_range );
130 VERIFY( d == 0.5 );
131
132 res = std::from_chars(s.data() + 1, s.data() + s.length(), d);
133 VERIFY( res.ptr == s.data() + s.length() - 3 );
134 VERIFY( res.ec == std::errc::result_out_of_range );
135 VERIFY( d == 0.5 );
136}
137
138void
139test04()
140{
141 std::from_chars_result res;
142 std::string z(2000, '0');
143 // Invalid inputs for scientific format
144 for (const char* s : { "", "1", ".", ".0", ".5", "1e+", "1e+-1" })
145 {
146 for (auto len : { 0, 10, 100, 1000, 2000 })
147 {
148 auto str = z.substr(len) + s;
149 double d = 99.0;
150 res = std::from_chars(str.data(), str.data() + str.length(), d,
151 std::chars_format::scientific);
152 VERIFY( res.ec == std::errc::invalid_argument );
153 VERIFY( res.ptr == str.data() );
154 VERIFY( d == 99.0 );
155 }
156 }
157}
2251b4a5 158#endif
932fbc86
JW
159
160int
161main()
162{
2251b4a5 163#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE
932fbc86
JW
164 test01();
165 test02();
166 test03();
167 test04();
2251b4a5 168#endif
932fbc86 169}