1 // Copyright (C) 2017-2018 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.
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 // { dg-options "-std=gnu++17" }
19 // { dg-do run { target c++17 } }
20 
21 #include <charconv>
22 #include <string_view>
23 #include <testsuite_hooks.h>
24 
25 // Test std::from_chars error handling.
26 
27 void
test01()28 test01()
29 {
30   std::from_chars_result r;
31   int i = 999;
32   std::string_view s;
33 
34   s = "";
35   r = std::from_chars(s.begin(), s.end(), i);
36   VERIFY( r.ec == std::errc::invalid_argument );
37   VERIFY( r.ptr == s.begin() );
38   VERIFY( i == 999 );
39 
40   s = "*";
41   r = std::from_chars(s.begin(), s.end(), i);
42   VERIFY( r.ec == std::errc::invalid_argument );
43   VERIFY( r.ptr == s.begin() );
44   VERIFY( i == 999 );
45 
46   s = "-";
47   r = std::from_chars(s.begin(), s.end(), i);
48   VERIFY( r.ec == std::errc::invalid_argument );
49   VERIFY( r.ptr == s.begin() );
50   VERIFY( i == 999 );
51 
52   s = "-*";
53   r = std::from_chars(s.begin(), s.end(), i);
54   VERIFY( r.ec == std::errc::invalid_argument );
55   VERIFY( r.ptr == s.begin() );
56   VERIFY( i == 999 );
57 
58   unsigned u = 888;
59   s = "-1";
60   r = std::from_chars(s.begin(), s.end(), u);
61   VERIFY( r.ec == std::errc::invalid_argument );
62   VERIFY( r.ptr == s.begin() );
63   s = "-a";
64   r = std::from_chars(s.begin(), s.end(), u);
65   VERIFY( r.ec == std::errc::invalid_argument );
66   VERIFY( r.ptr == s.begin() );
67   s = "-";
68   r = std::from_chars(s.begin(), s.end(), u);
69   VERIFY( r.ec == std::errc::invalid_argument );
70   VERIFY( r.ptr == s.begin() );
71   VERIFY( u == 888 );
72 
73   for (int base = 2; base <= 36; ++base)
74   {
75     const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz*";
76     const char buf[2] = { '-', digits[base] };
77     r = std::from_chars(buf, buf + 1, i, base);
78     VERIFY( r.ec == std::errc::invalid_argument );
79     VERIFY( r.ptr == buf );
80     VERIFY( i == 999 );
81     r = std::from_chars(buf + 1, buf + 2, i, base);
82     VERIFY( r.ec == std::errc::invalid_argument );
83     VERIFY( r.ptr == buf + 1 );
84     VERIFY( i == 999 );
85     r = std::from_chars(buf, buf + 2, i, base);
86     VERIFY( r.ec == std::errc::invalid_argument );
87     VERIFY( r.ptr == buf );
88     VERIFY( i == 999 );
89   }
90 }
91 
92 void
test02()93 test02()
94 {
95   std::from_chars_result r;
96   std::string_view s;
97 
98   signed char c = -5;
99   s = "-10000001";
100   r = std::from_chars(s.begin(), s.end(), c, 2);
101   VERIFY( r.ec == std::errc::result_out_of_range );
102   VERIFY( r.ptr == s.end() );
103   s = "-10000001*";
104   r = std::from_chars(s.begin(), s.end(), c, 2);
105   VERIFY( r.ec == std::errc::result_out_of_range );
106   VERIFY( r.ptr == s.begin() + 9 );
107   s = "-10000001000*";
108   r = std::from_chars(s.begin(), s.end(), c, 2);
109   VERIFY( r.ec == std::errc::result_out_of_range );
110   VERIFY( r.ptr == s.begin() + 12 );
111   s = "-129";
112   r = std::from_chars(s.begin(), s.end(), c, 10);
113   VERIFY( r.ec == std::errc::result_out_of_range );
114   VERIFY( r.ptr == s.end() );
115   s = "-129*";
116   r = std::from_chars(s.begin(), s.end(), c, 10);
117   VERIFY( r.ec == std::errc::result_out_of_range );
118   VERIFY( r.ptr == s.begin() + 4 );
119   s = "-100";
120   r = std::from_chars(s.begin(), s.end(), c, 16);
121   VERIFY( r.ec == std::errc::result_out_of_range );
122   VERIFY( r.ptr == s.end() );
123   s = "-100*";
124   r = std::from_chars(s.begin(), s.end(), c, 16);
125   VERIFY( r.ec == std::errc::result_out_of_range );
126   VERIFY( r.ptr == s.begin() + 4 );
127   s = "-81";
128   r = std::from_chars(s.begin(), s.end(), c, 16);
129   VERIFY( r.ec == std::errc::result_out_of_range );
130   VERIFY( r.ptr == s.end() );
131   s = "-81*";
132   r = std::from_chars(s.begin(), s.end(), c, 16);
133   VERIFY( r.ec == std::errc::result_out_of_range );
134   VERIFY( r.ptr == s.begin() + 3 );
135   s = "128";
136   r = std::from_chars(s.begin(), s.end(), c, 10);
137   VERIFY( r.ec == std::errc::result_out_of_range );
138   VERIFY( r.ptr == s.end() );
139   s = "128*";
140   r = std::from_chars(s.begin(), s.end(), c, 10);
141   VERIFY( r.ec == std::errc::result_out_of_range );
142   VERIFY( r.ptr == s.begin() + 3 );
143   s = "80";
144   r = std::from_chars(s.begin(), s.end(), c, 16);
145   VERIFY( r.ec == std::errc::result_out_of_range );
146   VERIFY( r.ptr == s.end() );
147   s = "80*";
148   r = std::from_chars(s.begin(), s.end(), c, 16);
149   VERIFY( r.ec == std::errc::result_out_of_range );
150   VERIFY( r.ptr == s.begin() + 2 );
151   VERIFY( c == -5 );
152 
153   unsigned char uc = 9;
154   s = "100000000";
155   r = std::from_chars(s.begin(), s.end(), uc, 2);
156   VERIFY( r.ec == std::errc::result_out_of_range );
157   VERIFY( r.ptr == s.end() );
158   s = "100000000*";
159   r = std::from_chars(s.begin(), s.end(), uc, 2);
160   VERIFY( r.ec == std::errc::result_out_of_range );
161   VERIFY( r.ptr == s.begin() + 9 );
162   s = "100000000000*";
163   r = std::from_chars(s.begin(), s.end(), uc, 2);
164   VERIFY( r.ec == std::errc::result_out_of_range );
165   VERIFY( r.ptr == s.begin() + 12 );
166   s = "256";
167   r = std::from_chars(s.begin(), s.end(), uc, 10);
168   VERIFY( r.ec == std::errc::result_out_of_range );
169   VERIFY( r.ptr == s.end() );
170   s = "256**";
171   r = std::from_chars(s.begin(), s.end(), uc, 10);
172   VERIFY( r.ec == std::errc::result_out_of_range );
173   VERIFY( r.ptr == s.begin() + 3 );
174   s = "256000**";
175   r = std::from_chars(s.begin(), s.end(), uc, 10);
176   VERIFY( r.ec == std::errc::result_out_of_range );
177   VERIFY( r.ptr == s.begin() + 6 );
178   s = "100";
179   r = std::from_chars(s.begin(), s.end(), uc, 16);
180   VERIFY( r.ec == std::errc::result_out_of_range );
181   VERIFY( r.ptr == s.end() );
182   s = "100**";
183   r = std::from_chars(s.begin(), s.end(), uc, 16);
184   VERIFY( r.ec == std::errc::result_out_of_range );
185   VERIFY( r.ptr == s.begin() + 3 );
186   s = "100000**";
187   r = std::from_chars(s.begin(), s.end(), uc, 16);
188   VERIFY( r.ec == std::errc::result_out_of_range );
189   VERIFY( r.ptr == s.begin() + 6 );
190   VERIFY( uc == 9 );
191 
192   unsigned long long ull = 123;
193   s = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz****";
194   r = std::from_chars(s.begin(), s.end(), ull, 36);
195   VERIFY( r.ec == std::errc::result_out_of_range );
196   VERIFY( r.ptr == s.begin() + 42 );
197   VERIFY( ull == 123 );
198 }
199 
200 int
main()201 main()
202 {
203   test01();
204   test02();
205 }
206