• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11
11 
12 // XFAIL: with_system_cxx_lib=macosx10.14
13 // XFAIL: with_system_cxx_lib=macosx10.13
14 // XFAIL: with_system_cxx_lib=macosx10.12
15 // XFAIL: with_system_cxx_lib=macosx10.11
16 // XFAIL: with_system_cxx_lib=macosx10.10
17 // XFAIL: with_system_cxx_lib=macosx10.9
18 // XFAIL: with_system_cxx_lib=macosx10.8
19 // XFAIL: with_system_cxx_lib=macosx10.7
20 
21 // <charconv>
22 
23 // from_chars_result from_chars(const char* first, const char* last,
24 //                              Integral& value, int base = 10)
25 
26 #include "charconv_test_helpers.h"
27 
28 template <typename T>
29 struct test_basics : roundtrip_test_base<T>
30 {
31     using roundtrip_test_base<T>::test;
32 
operator ()test_basics33     void operator()()
34     {
35         test(0);
36         test(42);
37         test(32768);
38         test(0, 10);
39         test(42, 10);
40         test(32768, 10);
41         test(0xf, 16);
42         test(0xdeadbeaf, 16);
43         test(0755, 8);
44 
45         for (int b = 2; b < 37; ++b)
46         {
47             using xl = std::numeric_limits<T>;
48 
49             test(1, b);
50             test(-1, b);
51             test(xl::lowest(), b);
52             test((xl::max)(), b);
53             test((xl::max)() / 2, b);
54         }
55 
56         using std::from_chars;
57         std::from_chars_result r;
58         T x;
59 
60         {
61             char s[] = "001x";
62 
63             // the expected form of the subject sequence is a sequence of
64             // letters and digits representing an integer with the radix
65             // specified by base (C11 7.22.1.4/3)
66             r = from_chars(s, s + sizeof(s), x);
67             assert(r.ec == std::errc{});
68             assert(r.ptr == s + 3);
69             assert(x == 1);
70         }
71 
72         {
73             char s[] = "0X7BAtSGHDkEIXZg ";
74 
75             // The letters from a (or A) through z (or Z) are ascribed the
76             // values 10 through 35; (C11 7.22.1.4/3)
77             r = from_chars(s, s + sizeof(s), x, 36);
78             assert(r.ec == std::errc::result_out_of_range);
79             // The member ptr of the return value points to the first character
80             // not matching the pattern
81             assert(r.ptr == s + sizeof(s) - 2);
82             assert(x == 1);
83 
84             // no "0x" or "0X" prefix shall appear if the value of base is 16
85             r = from_chars(s, s + sizeof(s), x, 16);
86             assert(r.ec == std::errc{});
87             assert(r.ptr == s + 1);
88             assert(x == 0);
89 
90             // only letters and digits whose ascribed values are less than that
91             // of base are permitted. (C11 7.22.1.4/3)
92             r = from_chars(s + 2, s + sizeof(s), x, 12);
93             // If the parsed value is not in the range representable by the type
94             // of value,
95             if (!fits_in<T>(1150))
96             {
97                 // value is unmodified and
98                 assert(x == 0);
99                 // the member ec of the return value is equal to
100                 // errc::result_out_of_range
101                 assert(r.ec == std::errc::result_out_of_range);
102             }
103             else
104             {
105                 // Otherwise, value is set to the parsed value,
106                 assert(x == 1150);
107                 // and the member ec is value-initialized.
108                 assert(r.ec == std::errc{});
109             }
110             assert(r.ptr == s + 5);
111         }
112     }
113 };
114 
115 template <typename T>
116 struct test_signed : roundtrip_test_base<T>
117 {
118     using roundtrip_test_base<T>::test;
119 
operator ()test_signed120     void operator()()
121     {
122         test(-1);
123         test(-12);
124         test(-1, 10);
125         test(-12, 10);
126         test(-21734634, 10);
127         test(-2647, 2);
128         test(-0xcc1, 16);
129 
130         for (int b = 2; b < 37; ++b)
131         {
132             using xl = std::numeric_limits<T>;
133 
134             test(0, b);
135             test(xl::lowest(), b);
136             test((xl::max)(), b);
137         }
138 
139         using std::from_chars;
140         std::from_chars_result r;
141         T x;
142 
143         {
144             // If the pattern allows for an optional sign,
145             // but the string has no digit characters following the sign,
146             char s[] = "- 9+12";
147             r = from_chars(s, s + sizeof(s), x);
148             // no characters match the pattern.
149             assert(r.ptr == s);
150             assert(r.ec == std::errc::invalid_argument);
151         }
152 
153         {
154             char s[] = "9+12";
155             r = from_chars(s, s + sizeof(s), x);
156             assert(r.ec == std::errc{});
157             // The member ptr of the return value points to the first character
158             // not matching the pattern,
159             assert(r.ptr == s + 1);
160             assert(x == 9);
161         }
162 
163         {
164             char s[] = "12";
165             r = from_chars(s, s + 2, x);
166             assert(r.ec == std::errc{});
167             // or has the value last if all characters match.
168             assert(r.ptr == s + 2);
169             assert(x == 12);
170         }
171 
172         {
173             // '-' is the only sign that may appear
174             char s[] = "+30";
175             // If no characters match the pattern,
176             r = from_chars(s, s + sizeof(s), x);
177             // value is unmodified,
178             assert(x == 12);
179             // the member ptr of the return value is first and
180             assert(r.ptr == s);
181             // the member ec is equal to errc::invalid_argument.
182             assert(r.ec == std::errc::invalid_argument);
183         }
184     }
185 };
186 
main()187 int main()
188 {
189     run<test_basics>(integrals);
190     run<test_signed>(all_signed);
191 }
192