1 // Copyright (C) 2020-2021 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 } }
24 #include <testsuite_hooks.h>
26 // Test std::from_chars error handling.
28 #if __cpp_lib_to_chars >= 201611L
32 std::from_chars_result r
;
36 for (auto p
: { "", "*", ".", "-", "-*", "-.", "+", "+.", "+-", "-+", "+1",
38 "in", "inch", "+inf", "na", "nam", "+nan" })
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() );
51 for (auto p
: { ".e1", "-.e1" }) // These are valid patterns for hex format
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() );
64 // scientific format requires an exponent
65 for (auto p
: { "1.2", "-1.2", "1.2e", "-1.2e", "1.2e-", "-1.2e+" })
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() );
75 // patterns that are invalid without the final character
76 for (auto p
: { "1", ".1", "-1", "-.1",
77 "inf", "-inf", "nan", "-nan" })
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() );
94 std::from_chars_result r
;
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() );
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 );
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 );
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
);
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
);
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
;
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() );
161 #if __cpp_lib_to_chars >= 201611L