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