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