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