[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / utilities / charconv / charconv.msvc / test.cpp
blob30ee9adcd74bf000f5ee288acc32f1d61e645fe1
1 // Copyright (c) Microsoft Corporation.
2 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4 #include "test.hpp"
6 #include <algorithm>
7 #include <array>
8 #include <assert.h>
9 #include <charconv>
10 #include <chrono>
11 #include <cmath>
12 #include <functional>
13 #include <iterator>
14 #include <limits>
15 #include <locale>
16 #include <optional>
17 #include <random>
18 #include <set>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <string>
24 #include <string_view>
25 #include <system_error>
26 #include <type_traits>
27 #include <utility>
28 #include <vector>
30 #include "double_fixed_precision_to_chars_test_cases_1.hpp"
31 #include "double_fixed_precision_to_chars_test_cases_2.hpp"
32 #include "double_fixed_precision_to_chars_test_cases_3.hpp"
33 #include "double_fixed_precision_to_chars_test_cases_4.hpp"
34 #include "double_from_chars_test_cases.hpp"
35 #include "double_general_precision_to_chars_test_cases.hpp"
36 #include "double_hex_precision_to_chars_test_cases.hpp"
37 #include "double_scientific_precision_to_chars_test_cases_1.hpp"
38 #include "double_scientific_precision_to_chars_test_cases_2.hpp"
39 #include "double_scientific_precision_to_chars_test_cases_3.hpp"
40 #include "double_scientific_precision_to_chars_test_cases_4.hpp"
41 #include "double_to_chars_test_cases.hpp"
42 #include "float_fixed_precision_to_chars_test_cases.hpp"
43 #include "float_from_chars_test_cases.hpp"
44 #include "float_general_precision_to_chars_test_cases.hpp"
45 #include "float_hex_precision_to_chars_test_cases.hpp"
46 #include "float_scientific_precision_to_chars_test_cases.hpp"
47 #include "float_to_chars_test_cases.hpp"
49 using namespace std;
51 void initialize_randomness(mt19937_64& mt64, const int argc, char** const /*argv*/) {
52 constexpr std::size_t n = mt19937_64::state_size;
53 constexpr std::size_t w = mt19937_64::word_size;
54 static_assert(w % 32 == 0);
55 constexpr std::size_t k = w / 32;
57 vector<std::uint32_t> vec(n * k);
59 puts("USAGE:");
60 puts("test.exe : generates seed data from random_device.");
62 if (argc == 1) {
63 random_device rd;
64 generate(vec.begin(), vec.end(), ref(rd));
65 puts("Generated seed data.");
66 } else {
67 puts("ERROR: Too many command-line arguments.");
68 abort();
71 puts("SEED DATA:");
72 for (const auto& elem : vec) {
73 printf("%zu ", static_cast<std::size_t>(elem));
75 printf("\n");
77 seed_seq seq(vec.cbegin(), vec.cend());
79 mt64.seed(seq);
81 puts("Successfully seeded mt64. First three values:");
82 for (int i = 0; i < 3; ++i) {
83 // libc++ uses long for 64-bit values.
84 printf("0x%016llX\n", static_cast<unsigned long long>(mt64()));
88 static_assert((chars_format::scientific & chars_format::fixed) == chars_format{});
89 static_assert((chars_format::scientific & chars_format::hex) == chars_format{});
90 static_assert((chars_format::fixed & chars_format::hex) == chars_format{});
91 static_assert(chars_format::general == (chars_format::fixed | chars_format::scientific));
93 template <typename T, typename Optional>
94 void test_common_to_chars(
95 const T value, const Optional opt_arg, const optional<int> opt_precision, const string_view correct) {
97 // Important: Test every effective buffer size from 0 through correct.size() and slightly beyond. For the sizes
98 // less than correct.size(), this verifies that the too-small buffer is correctly detected, and that we don't
99 // attempt to write outside of it, even by a single char. (This exhaustive validation is necessary because the
100 // implementation must check whenever it attempts to write. Sometimes we can calculate the total size and perform
101 // a single check, but sometimes we need to check when writing each part of the result.) Testing correct.size()
102 // verifies that we can succeed without overrunning, and testing slightly larger sizes verifies that we can succeed
103 // without attempting to write to extra chars even when they're available. Finally, we also verify that we aren't
104 // underrunning the buffer. This is a concern because sometimes we walk backwards when rounding.
106 constexpr std::size_t BufferPrefix = 20; // detect buffer underruns (specific value isn't important)
108 constexpr std::size_t Space = is_integral_v<T> ? 1 + 64 // worst case: -2^63 in binary
109 : is_same_v<T, float>
110 ? 1 + 151 // worst case: negative min subnormal float, fixed notation
111 : 1 + 1076; // worst case: negative min subnormal double, fixed notation
113 constexpr std::size_t BufferSuffix = 30; // detect buffer overruns (specific value isn't important)
115 array<char, BufferPrefix + Space + BufferSuffix> buff;
117 char* const buff_begin = buff.data();
118 char* const first = buff_begin + BufferPrefix;
119 char* const buff_end = buff_begin + buff.size();
121 constexpr std::size_t ExtraChars = 3;
122 static_assert(ExtraChars + 10 < BufferSuffix,
123 "The specific values aren't important, but there should be plenty of room to detect buffer overruns.");
125 for (std::size_t n = 0; n <= correct.size() + ExtraChars; ++n) {
126 assert(n <= static_cast<std::size_t>(buff_end - first));
127 char* const last = first + n;
129 buff.fill('@');
130 const auto is_fill_char = [](const char c) { return c == '@'; };
132 to_chars_result result{};
133 if (opt_precision.has_value()) {
134 assert(opt_arg.has_value());
136 if constexpr (is_floating_point_v<T>) {
137 result = to_chars(first, last, value, opt_arg.value(), opt_precision.value());
138 } else {
139 abort();
141 } else if (opt_arg.has_value()) {
142 result = to_chars(first, last, value, opt_arg.value());
143 } else {
144 result = to_chars(first, last, value);
147 if (n < correct.size()) {
148 assert(result.ptr == last);
149 assert(result.ec == errc::value_too_large);
150 assert(all_of(buff_begin, first, is_fill_char));
151 // [first, last) is unspecified
152 assert(all_of(last, buff_end, is_fill_char));
153 } else {
154 assert(result.ptr == first + correct.size());
155 assert(result.ec == errc{});
156 assert(all_of(buff_begin, first, is_fill_char));
157 assert(equal(first, result.ptr, correct.begin(), correct.end()));
158 assert(all_of(result.ptr, buff_end, is_fill_char));
163 template <typename T>
164 void test_integer_to_chars(const T value, const optional<int> opt_base, const string_view correct) {
166 test_common_to_chars(value, opt_base, nullopt, correct);
168 { // Also test successful from_chars() scenarios.
169 const char* const correct_first = correct.data();
170 const char* const correct_last = correct_first + correct.size();
172 T dest = 0;
174 const from_chars_result from_res =
175 (opt_base.has_value() ? from_chars(correct_first, correct_last, dest, opt_base.value())
176 : from_chars(correct_first, correct_last, dest));
178 assert(from_res.ptr == correct_last);
179 assert(from_res.ec == errc{});
180 assert(dest == value);
184 // https://www.wolframalpha.com : Table[BaseForm[n * 2 - 1, n], {n, 2, 36}]
185 constexpr const char* output_max_digit[] = {"skip0", "skip1", "11", "12", "13", "14", "15", "16", "17", "18", "19",
186 "1a", "1b", "1c", "1d", "1e", "1f", "1g", "1h", "1i", "1j", "1k", "1l", "1m", "1n", "1o", "1p", "1q", "1r", "1s",
187 "1t", "1u", "1v", "1w", "1x", "1y", "1z"};
189 // https://www.wolframalpha.com : Table[BaseForm[k, n], {k, {MEOW, MEOW, MEOW}}, {n, 2, 36}]
190 constexpr std::uint64_t stress_chunks_positive = 12000000345000678900ULL;
191 constexpr pair<std::uint64_t, array<const char*, 37>> output_positive[] = {
192 {123U, {{"skip0", "skip1", "1111011", "11120", "1323", "443", "323", "234", "173", "146", "123", "102", "a3", "96",
193 "8b", "83", "7b", "74", "6f", "69", "63", "5i", "5d", "58", "53", "4n", "4j", "4f", "4b", "47", "43",
194 "3u", "3r", "3o", "3l", "3i", "3f"}}},
195 {std::uint64_t{INT8_MAX}, {{"skip0", "skip1", "1111111", "11201", "1333", "1002", "331", "241", "177", "151", "127",
196 "106", "a7", "9a", "91", "87", "7f", "78", "71", "6d", "67", "61", "5h", "5c", "57", "52",
197 "4n", "4j", "4f", "4b", "47", "43", "3v", "3s", "3p", "3m", "3j"}}},
198 {161U, {{"skip0", "skip1", "10100001", "12222", "2201", "1121", "425", "320", "241", "188", "161", "137", "115",
199 "c5", "b7", "ab", "a1", "98", "8h", "89", "81", "7e", "77", "70", "6h", "6b", "65", "5q", "5l", "5g",
200 "5b", "56", "51", "4t", "4p", "4l", "4h"}}},
201 {UINT8_MAX, {{"skip0", "skip1", "11111111", "100110", "3333", "2010", "1103", "513", "377", "313", "255", "212",
202 "193", "168", "143", "120", "ff", "f0", "e3", "d8", "cf", "c3", "bd", "b2", "af", "a5", "9l", "9c",
203 "93", "8n", "8f", "87", "7v", "7o", "7h", "7a", "73"}}},
204 {1729U, {{"skip0", "skip1", "11011000001", "2101001", "123001", "23404", "12001", "5020", "3301", "2331", "1729",
205 "1332", "1001", "a30", "8b7", "7a4", "6c1", "5gc", "561", "4f0", "469", "3j7", "3cd", "364", "301",
206 "2j4", "2ed", "2a1", "25l", "21i", "1rj", "1oo", "1m1", "1jd", "1gt", "1ee", "1c1"}}},
207 {std::uint64_t{INT16_MAX}, {{"skip0", "skip1", "111111111111111", "1122221121", "13333333", "2022032", "411411",
208 "164350", "77777", "48847", "32767", "22689", "16b67", "11bb7", "bd27", "9a97", "7fff",
209 "6b68", "5b27", "4eeb", "41i7", "3b67", "31f9", "2flf", "28l7", "22ah", "1mc7", "1hpg",
210 "1dm7", "19rq", "16c7", "1330", "vvv", "u2v", "sbp", "qq7", "pa7"}}},
211 {57494U, {{"skip0", "skip1", "1110000010010110", "2220212102", "32002112", "3314434", "1122102", "326423", "160226",
212 "86772", "57494", "3a218", "29332", "20228", "16d4a", "1207e", "e096", "bbg0", "9f82", "8750", "73ee",
213 "647h", "58h8", "4gfh", "43je", "3goj", "3718", "2onb", "2h9a", "2aag", "23qe", "1spk", "1o4m", "1jq8",
214 "1fp0", "1bwo", "18d2"}}},
215 {UINT16_MAX, {{"skip0", "skip1", "1111111111111111", "10022220020", "33333333", "4044120", "1223223", "362031",
216 "177777", "108806", "65535", "45268", "31b13", "23aa2", "19c51", "14640", "ffff", "d5d0", "b44f",
217 "9aa4", "83gf", "71cf", "638j", "58k8", "4hif", "44la", "3iof", "38o6", "2rgf", "2jqo", "2cof",
218 "2661", "1vvv", "1r5u", "1mnh", "1ihf", "1ekf"}}},
219 {71125478U, {{"skip0", "skip1", "100001111010100100111100110", "11221211112210222", "10033110213212",
220 "121202003403", "11020244342", "1522361624", "417244746", "157745728", "71125478", "3716a696",
221 "1b9a06b2", "11973ba8", "9636514", "639e338", "43d49e6", "2g19gfb", "21b9d18", "19dec94", "124addi",
222 "h8f25b", "dhdfa6", "b13hg2", "8m91he", "7720j3", "5pgj58", "4pmelq", "43k17i", "3dg8ek", "2ro898",
223 "2f0et8", "23qif6", "1qw5lh", "1j7l7s", "1cdvli", "16cgrq"}}},
224 {std::uint64_t{INT32_MAX},
225 {{"skip0", "skip1", "1111111111111111111111111111111", "12112122212110202101", "1333333333333333",
226 "13344223434042", "553032005531", "104134211161", "17777777777", "5478773671", "2147483647", "a02220281",
227 "4bb2308a7", "282ba4aaa", "1652ca931", "c87e66b7", "7fffffff", "53g7f548", "3928g3h1", "27c57h32",
228 "1db1f927", "140h2d91", "ikf5bf1", "ebelf95", "b5gge57", "8jmdnkm", "6oj8ion", "5ehncka", "4clm98f",
229 "3hk7987", "2sb6cs7", "2d09uc1", "1vvvvvv", "1lsqtl1", "1d8xqrp", "15v22um", "zik0zj"}}},
230 {3522553278ULL,
231 {{"skip0", "skip1", "11010001111101011110010110111110", "100002111022020200020", "3101331132112332",
232 "24203233201103", "1341312313010", "153202131426", "32175362676", "10074266606", "3522553278", "1548431462",
233 "823842766", "441a34c6a", "255b8d486", "1593b4753", "d1f5e5be", "89ffb3b6", "5da3e606", "3hgbfb5i",
234 "2f0fj33i", "1k1ac536", "191b46e2", "10i6fmk8", "ia967l6", "eahia63", "baca9ga", "92d86i6", "78iq4i6",
235 "5qlc1dc", "4osos2i", "3u1862s", "38vbpdu", "2o0a7ro", "29hx9e6", "1w2dnod", "1m98ji6"}}},
236 {UINT32_MAX,
237 {{"skip0", "skip1", "11111111111111111111111111111111", "102002022201221111210", "3333333333333333",
238 "32244002423140", "1550104015503", "211301422353", "37777777777", "12068657453", "4294967295", "1904440553",
239 "9ba461593", "535a79888", "2ca5b7463", "1a20dcd80", "ffffffff", "a7ffda90", "704he7g3", "4f5aff65",
240 "3723ai4f", "281d55i3", "1fj8b183", "1606k7ib", "mb994af", "hek2mgk", "dnchbnl", "b28jpdl", "8pfgih3",
241 "76beigf", "5qmcpqf", "4q0jto3", "3vvvvvv", "3aokq93", "2qhxjlh", "2br45qa", "1z141z3"}}},
242 {545890816626160ULL,
243 {{"skip0", "skip1", "1111100000111110000011100001101100000110111110000", "2122120211122121121021010202111",
244 "1330013300130031200313300", "1033022333343024014120", "5213002440142255104", "222661211220253465",
245 "17407603415406760", "2576748547233674", "545890816626160", "148a34aa4706535", "51285369b87494",
246 "1a57a38b045a95", "98b3383b9766c", "4319d1601875a", "1f07c1c360df0", "ffd471f34f13", "88g09ff9dh84",
247 "4d0d5e232c53", "2d63h403i580", "1bf5h8185hdj", "kc3g550fkcg", "d41id5k9984", "8ef5n0him4g", "5i2dijfe1la",
248 "3me22fm5fhi", "2hfmhgg73kd", "1ngpfabr53c", "18i7220bh11", "rm0lcjngpa", "kk1elesni1", "fgfge3c3fg",
249 "bp4q5l6bjg", "8xna46jp0k", "6wejomvji5", "5di2s1qhv4"}}},
250 {std::uint64_t{INT64_MAX},
251 {{"skip0", "skip1", "111111111111111111111111111111111111111111111111111111111111111",
252 "2021110011022210012102010021220101220221", "13333333333333333333333333333333",
253 "1104332401304422434310311212", "1540241003031030222122211", "22341010611245052052300",
254 "777777777777777777777", "67404283172107811827", "9223372036854775807", "1728002635214590697",
255 "41a792678515120367", "10b269549075433c37", "4340724c6c71dc7a7", "160e2ad3246366807", "7fffffffffffffff",
256 "33d3d8307b214008", "16agh595df825fa7", "ba643dci0ffeehh", "5cbfjia3fh26ja7", "2heiciiie82dh97",
257 "1adaibb21dckfa7", "i6k448cf4192c2", "acd772jnc9l0l7", "64ie1focnn5g77", "3igoecjbmca687", "27c48l5b37oaop",
258 "1bk39f3ah3dmq7", "q1se8f0m04isb", "hajppbc1fc207", "bm03i95hia437", "7vvvvvvvvvvvv", "5hg4ck9jd4u37",
259 "3tdtk1v8j6tpp", "2pijmikexrxp7", "1y2p0ij32e8e7"}}},
260 {stress_chunks_positive,
261 {{"skip0", "skip1", "1010011010001000100100001011110000101100010101001001010111110100",
262 "2221221122020020011022001202200200202200", "22122020210023300230111021113310",
263 "1301130403021123030133211100", "2311004450342244200504500", "30325064311430214266301",
264 "1232104413605425112764", "87848206138052620680", "12000000345000678900", "2181782a1686924456a",
265 "54aa47a9058877b130", "150593a5b002c87b16", "571cad2b93c7760a8", "1c60d2676d4e53e00", "a68890bc2c5495f4",
266 "43499224707a4f4g", "1e052gdga1d26f40", "f06dh4g564c8a91", "769df0d9ace4h50", "3ee7bcj1ajghi4f",
267 "1k9agc4gfl0l43a", "10id7dakdlcjd22", "dge08fe0l5hl7c", "8184326d31ib60", "4ljbglf3cpim76",
268 "2pph66481kiiki", "1niph2ao132e58", "14qgbgk3c3iffg", "mhc35an1bhb00", "f78o8ur705ln5", "ad24gngm595fk",
269 "76e1n5i5v0ivl", "50wu8jsnks82g", "3ja41smfvqb1f", "2j64t3qgq0ut0"}}},
270 {14454900944617508688ULL,
271 {{"skip0", "skip1", "1100100010011010000111111101001011100011011000101000111101010000",
272 "10120022020112011211121221212101012220210", "30202122013331023203120220331100",
273 "1432224030234034034040234223", "3014532424232535441404120", "34610451042001242144165",
274 "1442320775134330507520", "116266464747855335823", "14454900944617508688", "266642a9a9471339935",
275 "662251403263939640", "1895280092bc310481", "68cb9c8292557406c", "23023deab20002893", "c89a1fd2e3628f50",
276 "50e7147a7db8ef84", "22a34a05086f78ec", "i1dgef04357g7i1", "8g90b882jcj8be8", "49c1kk35i0k24ic",
277 "272a16i54ebkacg", "15fdih7l3m7k8md", "gbj7303eg9nge0", "9hckfdkj3kkdmd", "5lc7hifdkl4nne",
278 "3f86e4mgpna5ol", "266pj428na273c", "1bomgjbnlg4m3f", "r5tf1f7f009ji", "iarsig29iqhhm", "ch6gvqbhm53qg",
279 "8lwtvcdj6rlqr", "61w23lajggp44", "49p1f3dsqqcdx", "31tkqqkxypopc"}}},
280 {UINT64_MAX,
281 {{"skip0", "skip1", "1111111111111111111111111111111111111111111111111111111111111111",
282 "11112220022122120101211020120210210211220", "33333333333333333333333333333333",
283 "2214220303114400424121122430", "3520522010102100444244423", "45012021522523134134601",
284 "1777777777777777777777", "145808576354216723756", "18446744073709551615", "335500516a429071284",
285 "839365134a2a240713", "219505a9511a867b72", "8681049adb03db171", "2c1d56b648c6cd110", "ffffffffffffffff",
286 "67979g60f5428010", "2d3fgb0b9cg4bd2f", "141c8786h1ccaagg", "b53bjh07be4dj0f", "5e8g4ggg7g56dif",
287 "2l4lf104353j8kf", "1ddh88h2782i515", "l12ee5fn0ji1if", "c9c336o0mlb7ef", "7b7n2pcniokcgf",
288 "4eo8hfam6fllmo", "2nc6j26l66rhof", "1n3rsh11f098rn", "14l9lkmo30o40f", "nd075ib45k86f", "fvvvvvvvvvvvv",
289 "b1w8p7j5q9r6f", "7orp63sh4dphh", "5g24a25twkwff", "3w5e11264sgsf"}}},
292 // https://www.wolframalpha.com : Table[BaseForm[k, n], {k, {MEOW, MEOW, MEOW}}, {n, 2, 36}]
293 constexpr std::int64_t stress_chunks_negative = -9000876000000054321LL;
294 constexpr pair<std::int64_t, array<const char*, 37>> output_negative[] = {
295 {-85, {{"skip0", "skip1", "-1010101", "-10011", "-1111", "-320", "-221", "-151", "-125", "-104", "-85", "-78",
296 "-71", "-67", "-61", "-5a", "-55", "-50", "-4d", "-49", "-45", "-41", "-3j", "-3g", "-3d", "-3a", "-37",
297 "-34", "-31", "-2r", "-2p", "-2n", "-2l", "-2j", "-2h", "-2f", "-2d"}}},
298 {INT8_MIN, {{"skip0", "skip1", "-10000000", "-11202", "-2000", "-1003", "-332", "-242", "-200", "-152", "-128",
299 "-107", "-a8", "-9b", "-92", "-88", "-80", "-79", "-72", "-6e", "-68", "-62", "-5i", "-5d", "-58",
300 "-53", "-4o", "-4k", "-4g", "-4c", "-48", "-44", "-40", "-3t", "-3q", "-3n", "-3k"}}},
301 {-1591, {{"skip0", "skip1", "-11000110111", "-2011221", "-120313", "-22331", "-11211", "-4432", "-3067", "-2157",
302 "-1591", "-1217", "-b07", "-955", "-819", "-711", "-637", "-58a", "-4g7", "-47e", "-3jb", "-3cg",
303 "-367", "-304", "-2i7", "-2dg", "-295", "-24p", "-20n", "-1pp", "-1n1", "-1ka", "-1hn", "-1f7", "-1cr",
304 "-1ag", "-187"}}},
305 {INT16_MIN, {{"skip0", "skip1", "-1000000000000000", "-1122221122", "-20000000", "-2022033", "-411412", "-164351",
306 "-100000", "-48848", "-32768", "-2268a", "-16b68", "-11bb8", "-bd28", "-9a98", "-8000", "-6b69",
307 "-5b28", "-4eec", "-41i8", "-3b68", "-31fa", "-2flg", "-28l8", "-22ai", "-1mc8", "-1hph", "-1dm8",
308 "-19rr", "-16c8", "-1331", "-1000", "-u2w", "-sbq", "-qq8", "-pa8"}}},
309 {-66748412,
310 {{"skip0", "skip1", "-11111110100111111111111100", "-11122121011121102", "-3332213333330", "-114041422122",
311 "-10342352232", "-1440231533", "-376477774", "-148534542", "-66748412", "-34750085", "-1a42b678",
312 "-10aa0803", "-8c1731a", "-5cd7492", "-3fa7ffc", "-2d03163", "-1h5f3b2", "-17i39c6", "-10h3b0c", "-g749jh",
313 "-ckkdkg", "-a8c0ak", "-894afk", "-6klmbc", "-5g1i6g", "-4hg4gb", "-3ogi7o", "-37anqb", "-2mc4r2",
314 "-2a8h7i", "-1vkvvs", "-1n9ca5", "-1fw8sk", "-19gshh", "-13qnek"}}},
315 {INT32_MIN, {{"skip0", "skip1", "-10000000000000000000000000000000", "-12112122212110202102", "-2000000000000000",
316 "-13344223434043", "-553032005532", "-104134211162", "-20000000000", "-5478773672", "-2147483648",
317 "-a02220282", "-4bb2308a8", "-282ba4aab", "-1652ca932", "-c87e66b8", "-80000000", "-53g7f549",
318 "-3928g3h2", "-27c57h33", "-1db1f928", "-140h2d92", "-ikf5bf2", "-ebelf96", "-b5gge58", "-8jmdnkn",
319 "-6oj8ioo", "-5ehnckb", "-4clm98g", "-3hk7988", "-2sb6cs8", "-2d09uc2", "-2000000", "-1lsqtl2",
320 "-1d8xqrq", "-15v22un", "-zik0zk"}}},
321 {-297139747082649553LL,
322 {{"skip0", "skip1", "-10000011111101001110000011010010001100000101011111111010001",
323 "-1222110012002112101210012211022102101", "-100133221300122101200223333101", "-4443033200104011124241203",
324 "-21313431255203203120401", "-350320603201030412545", "-20375160322140537721", "-1873162471705738371",
325 "-297139747082649553", "-65150976074a24025", "-173522497b5373101", "-5a60a99bc3b71654", "-1ca51a06cc38ba25",
326 "-a2a25babe62241d", "-41fa7069182bfd1", "-1d00134fba1769g", "-e4f799fc5f7e81", "-714ebbh8388188",
327 "-3cahb17836b3hd", "-1j8659jf5hbg3j", "-112bbb2jege5c5", "-dcjfmk2kjb4cc", "-836bm4klbgl61",
328 "-4ofia1416ee73", "-32ommgjef1l2h", "-1qc52eal5m8ba", "-17n53r05a4r15", "-oa88m2qiqjik", "-gn67qoat5r8d",
329 "-blgd6n5s90al", "-87t70q8o5fuh", "-5t09hwaqu9qg", "-47vssihaoa4x", "-32p24fbjye7x", "-299r8zck3841"}}},
330 {stress_chunks_negative,
331 {{"skip0", "skip1", "-111110011101001100010010000100010000111010101111001010000110001",
332 "-2012222010200021010000112111002001111200", "-13303221202100202013111321100301",
333 "-1101001100304341000003214241", "-1522150121302454031001413", "-22054250360123016161454",
334 "-763514220420725712061", "-65863607100474061450", "-9000876000000054321", "-1689813530958833498",
335 "-408258185a67069269", "-106b01597a47ba2948", "-41c02922bc776d49b", "-1584cd10979dc84b6",
336 "-7ce9890887579431", "-327cf6cbc67023c3", "-1604b5f6a0de8129", "-b50d3ef02f124a4", "-59h9bfif0006fg1",
337 "-2g5d8ekh05d2dfi", "-19i418c38g1chfj", "-hjgf7d0k0gla9a", "-a6b21ncehfa3f9", "-61060fnl003bml",
338 "-3g88bakondgf8l", "-25q3i730ed21di", "-1al84glo518iip", "-pcli8ig7pjhbo", "-gs31q8id2jnkl",
339 "-bd7kaglgdrbgk", "-7pqc9123lf51h", "-5d2sd1r5ms7su", "-3q833s8kdrun3", "-2n7vmqigfueqb",
340 "-1wdu892toj0a9"}}},
341 {INT64_MIN, {{"skip0", "skip1", "-1000000000000000000000000000000000000000000000000000000000000000",
342 "-2021110011022210012102010021220101220222", "-20000000000000000000000000000000",
343 "-1104332401304422434310311213", "-1540241003031030222122212", "-22341010611245052052301",
344 "-1000000000000000000000", "-67404283172107811828", "-9223372036854775808", "-1728002635214590698",
345 "-41a792678515120368", "-10b269549075433c38", "-4340724c6c71dc7a8", "-160e2ad3246366808",
346 "-8000000000000000", "-33d3d8307b214009", "-16agh595df825fa8", "-ba643dci0ffeehi",
347 "-5cbfjia3fh26ja8", "-2heiciiie82dh98", "-1adaibb21dckfa8", "-i6k448cf4192c3", "-acd772jnc9l0l8",
348 "-64ie1focnn5g78", "-3igoecjbmca688", "-27c48l5b37oaoq", "-1bk39f3ah3dmq8", "-q1se8f0m04isc",
349 "-hajppbc1fc208", "-bm03i95hia438", "-8000000000000", "-5hg4ck9jd4u38", "-3tdtk1v8j6tpq",
350 "-2pijmikexrxp8", "-1y2p0ij32e8e8"}}},
353 template <typename T>
354 void test_integer_to_chars() {
355 for (int base = 2; base <= 36; ++base) {
356 test_integer_to_chars(static_cast<T>(0), base, "0");
357 test_integer_to_chars(static_cast<T>(1), base, "1");
359 // tests [3, 71]
360 test_integer_to_chars(static_cast<T>(base * 2 - 1), base, output_max_digit[base]);
362 for (const auto& p : output_positive) {
363 if (p.first <= static_cast<std::uint64_t>(numeric_limits<T>::max())) {
364 test_integer_to_chars(static_cast<T>(p.first), base, p.second[static_cast<std::size_t>(base)]);
368 if constexpr (is_signed_v<T>) {
369 test_integer_to_chars(static_cast<T>(-1), base, "-1");
371 for (const auto& p : output_negative) {
372 if (p.first >= static_cast<std::int64_t>(numeric_limits<T>::min())) {
373 test_integer_to_chars(static_cast<T>(p.first), base, p.second[static_cast<std::size_t>(base)]);
379 test_integer_to_chars(static_cast<T>(42), nullopt, "42");
382 enum class TestFromCharsMode { Normal, SignalingNaN };
384 template <typename T, typename BaseOrFmt>
385 void test_from_chars(const string_view input, const BaseOrFmt base_or_fmt, const std::size_t correct_idx,
386 const errc correct_ec, const optional<T> opt_correct = nullopt,
387 const TestFromCharsMode mode = TestFromCharsMode::Normal) {
389 if constexpr (is_integral_v<T>) {
390 assert(mode == TestFromCharsMode::Normal);
393 constexpr T unmodified = 111;
395 T dest = unmodified;
397 const from_chars_result result = from_chars(input.data(), input.data() + input.size(), dest, base_or_fmt);
399 assert(result.ptr == input.data() + correct_idx);
400 assert(result.ec == correct_ec);
402 if (correct_ec == errc{} || (is_floating_point_v<T> && correct_ec == errc::result_out_of_range)) {
403 if constexpr (is_floating_point_v<T>) {
404 if (mode == TestFromCharsMode::Normal) {
405 using Uint = conditional_t<is_same_v<T, float>, std::uint32_t, std::uint64_t>;
406 assert(opt_correct.has_value());
407 assert(_Bit_cast<Uint>(dest) == _Bit_cast<Uint>(opt_correct.value()));
408 } else {
409 assert(mode == TestFromCharsMode::SignalingNaN);
410 assert(!opt_correct.has_value());
411 assert(isnan(dest));
413 } else {
414 assert(opt_correct.has_value());
415 assert(dest == opt_correct.value());
417 } else {
418 assert(!opt_correct.has_value());
419 assert(dest == unmodified);
423 constexpr errc inv_arg = errc::invalid_argument;
424 constexpr errc out_ran = errc::result_out_of_range;
426 template <typename T>
427 void test_integer_from_chars() {
428 for (int base = 2; base <= 36; ++base) {
429 test_from_chars<T>("", base, 0, inv_arg); // no characters
430 test_from_chars<T>("@1", base, 0, inv_arg); // '@' is bogus
431 test_from_chars<T>(".1", base, 0, inv_arg); // '.' is bogus, for integers
432 test_from_chars<T>("+1", base, 0, inv_arg); // '+' is bogus, N4713 23.20.3 [charconv.from.chars]/3
433 // "a minus sign is the only sign that may appear"
434 test_from_chars<T>(" 1", base, 0, inv_arg); // ' ' is bogus, no whitespace in subject sequence
436 if constexpr (is_unsigned_v<T>) { // N4713 23.20.3 [charconv.from.chars]/3
437 test_from_chars<T>("-1", base, 0, inv_arg); // "and only if value has a signed type"
440 // N4713 23.20.3 [charconv.from.chars]/1 "[ Note: If the pattern allows for an optional sign,
441 // but the string has no digit characters following the sign, no characters match the pattern. -end note ]"
442 test_from_chars<T>("-", base, 0, inv_arg); // '-' followed by no characters
443 test_from_chars<T>("-@1", base, 0, inv_arg); // '-' followed by bogus '@'
444 test_from_chars<T>("-.1", base, 0, inv_arg); // '-' followed by bogus '.'
445 test_from_chars<T>("-+1", base, 0, inv_arg); // '-' followed by bogus '+'
446 test_from_chars<T>("- 1", base, 0, inv_arg); // '-' followed by bogus ' '
447 test_from_chars<T>("--1", base, 0, inv_arg); // '-' can't be repeated
449 vector<char> bogus_digits;
451 if (base < 10) {
452 bogus_digits = {static_cast<char>('0' + base), 'A', 'a'};
453 } else {
454 // '[' and '{' are bogus for base 36
455 bogus_digits = {static_cast<char>('A' + (base - 10)), static_cast<char>('a' + (base - 10))};
458 for (const auto& bogus : bogus_digits) {
459 test_from_chars<T>(bogus + "1"s, base, 0, inv_arg); // bogus digit (for this base)
460 test_from_chars<T>("-"s + bogus + "1"s, base, 0, inv_arg); // '-' followed by bogus digit
463 // Test leading zeroes.
464 test_from_chars<T>(string(100, '0'), base, 100, errc{}, static_cast<T>(0));
465 test_from_chars<T>(string(100, '0') + "11"s, base, 102, errc{}, static_cast<T>(base + 1));
467 // Test negative zero and negative leading zeroes.
468 if constexpr (is_signed_v<T>) {
469 test_from_chars<T>("-0", base, 2, errc{}, static_cast<T>(0));
470 test_from_chars<T>("-"s + string(100, '0'), base, 101, errc{}, static_cast<T>(0));
471 test_from_chars<T>("-"s + string(100, '0') + "11"s, base, 103, errc{}, static_cast<T>(-base - 1));
474 // N4713 23.20.3 [charconv.from.chars]/1 "The member ptr of the return value points to the
475 // first character not matching the pattern, or has the value last if all characters match."
476 test_from_chars<T>("11", base, 2, errc{}, static_cast<T>(base + 1));
477 test_from_chars<T>("11@@@", base, 2, errc{}, static_cast<T>(base + 1));
479 // When overflowing, we need to keep consuming valid digits, in order to return ptr correctly.
480 test_from_chars<T>(string(100, '1'), base, 100, out_ran);
481 test_from_chars<T>(string(100, '1') + "@@@"s, base, 100, out_ran);
483 if constexpr (is_signed_v<T>) {
484 test_from_chars<T>("-"s + string(100, '1'), base, 101, out_ran);
485 test_from_chars<T>("-"s + string(100, '1') + "@@@"s, base, 101, out_ran);
489 // N4713 23.20.3 [charconv.from.chars]/3 "The pattern is the expected form of the subject sequence
490 // in the "C" locale for the given nonzero base, as described for strtol"
491 // C11 7.22.1.4/3 "The letters from a (or A) through z (or Z) are ascribed the values 10 through 35"
492 for (int i = 0; i < 26; ++i) {
493 test_from_chars<T>(string(1, static_cast<char>('A' + i)), 36, 1, errc{}, static_cast<T>(10 + i));
494 test_from_chars<T>(string(1, static_cast<char>('a' + i)), 36, 1, errc{}, static_cast<T>(10 + i));
497 // N4713 23.20.3 [charconv.from.chars]/3 "no "0x" or "0X" prefix shall appear if the value of base is 16"
498 test_from_chars<T>("0x1729", 16, 1, errc{}, static_cast<T>(0)); // reads '0', stops at 'x'
499 test_from_chars<T>("0X1729", 16, 1, errc{}, static_cast<T>(0)); // reads '0', stops at 'X'
501 if constexpr (is_signed_v<T>) {
502 test_from_chars<T>("-0x1729", 16, 2, errc{}, static_cast<T>(0)); // reads "-0", stops at 'x'
503 test_from_chars<T>("-0X1729", 16, 2, errc{}, static_cast<T>(0)); // reads "-0", stops at 'X'
507 template <typename T>
508 void test_integer() {
509 test_integer_to_chars<T>();
510 test_integer_from_chars<T>();
513 void all_integer_tests() {
514 test_integer<char>();
515 test_integer<signed char>();
516 test_integer<unsigned char>();
517 test_integer<short>();
518 test_integer<unsigned short>();
519 test_integer<int>();
520 test_integer<unsigned int>();
521 test_integer<long>();
522 test_integer<unsigned long>();
523 test_integer<long long>();
524 test_integer<unsigned long long>();
526 // Test overflow scenarios.
527 test_from_chars<unsigned int>("4294967289", 10, 10, errc{}, 4294967289U); // not risky
528 test_from_chars<unsigned int>("4294967294", 10, 10, errc{}, 4294967294U); // risky with good digit
529 test_from_chars<unsigned int>("4294967295", 10, 10, errc{}, 4294967295U); // risky with max digit
530 test_from_chars<unsigned int>("4294967296", 10, 10, out_ran); // risky with bad digit
531 test_from_chars<unsigned int>("4294967300", 10, 10, out_ran); // beyond risky
533 test_from_chars<int>("2147483639", 10, 10, errc{}, 2147483639); // not risky
534 test_from_chars<int>("2147483646", 10, 10, errc{}, 2147483646); // risky with good digit
535 test_from_chars<int>("2147483647", 10, 10, errc{}, 2147483647); // risky with max digit
536 test_from_chars<int>("2147483648", 10, 10, out_ran); // risky with bad digit
537 test_from_chars<int>("2147483650", 10, 10, out_ran); // beyond risky
539 test_from_chars<int>("-2147483639", 10, 11, errc{}, -2147483639); // not risky
540 test_from_chars<int>("-2147483647", 10, 11, errc{}, -2147483647); // risky with good digit
541 test_from_chars<int>("-2147483648", 10, 11, errc{}, -2147483647 - 1); // risky with max digit
542 test_from_chars<int>("-2147483649", 10, 11, out_ran); // risky with bad digit
543 test_from_chars<int>("-2147483650", 10, 11, out_ran); // beyond risky
546 void assert_message_bits(const bool b, const char* const msg, const std::uint32_t bits) {
547 if (!b) {
548 fprintf(stderr, "%s failed for 0x%08zX\n", msg, static_cast<std::size_t>(bits));
549 fprintf(stderr, "This is a randomized test.\n");
550 fprintf(stderr, "DO NOT IGNORE/RERUN THIS FAILURE.\n");
551 fprintf(stderr, "You must report it to the STL maintainers.\n");
552 abort();
556 void assert_message_bits(const bool b, const char* const msg, const std::uint64_t bits) {
557 if (!b) {
558 // libc++ uses long for 64-bit values.
559 fprintf(stderr, "%s failed for 0x%016llX\n", msg, static_cast<unsigned long long>(bits));
560 fprintf(stderr, "This is a randomized test.\n");
561 fprintf(stderr, "DO NOT IGNORE/RERUN THIS FAILURE.\n");
562 fprintf(stderr, "You must report it to the STL maintainers.\n");
563 abort();
567 constexpr std::uint32_t FractionBits = 10; // Tunable for test coverage vs. performance.
568 static_assert(FractionBits >= 1, "Must test at least 1 fraction bit.");
569 static_assert(FractionBits <= 23, "There are only 23 fraction bits in a float.");
571 constexpr std::uint32_t Fractions = 1U << FractionBits;
572 constexpr std::uint32_t Mask32 = ~((1U << FractionBits) - 1U);
573 constexpr std::uint64_t Mask64 = ~((1ULL << FractionBits) - 1ULL);
575 constexpr std::uint32_t PrefixesToTest = 100; // Tunable for test coverage vs. performance.
576 static_assert(PrefixesToTest >= 1, "Must test at least 1 prefix.");
578 constexpr std::uint32_t PrefixLimit = 2 // sign bit
579 * 255 // non-INF/NAN exponents for float
580 * (1U << (23 - FractionBits)); // fraction bits in prefix
581 static_assert(PrefixesToTest <= PrefixLimit, "Too many prefixes.");
583 template <bool IsDouble>
584 void test_floating_prefix(const conditional_t<IsDouble, std::uint64_t, std::uint32_t> prefix) {
586 using UIntType = conditional_t<IsDouble, std::uint64_t, std::uint32_t>;
587 using FloatingType = conditional_t<IsDouble, double, float>;
589 // "-1.2345678901234567e-100" or "-1.23456789e-10"
590 constexpr std::size_t buffer_size = IsDouble ? 24 : 15;
591 char buffer[buffer_size];
592 // TODO Enable once std::from_chars has floating point support.
593 #if 0
594 FloatingType val;
595 #endif
597 // Exact sizes are difficult to prove for fixed notation.
598 // This must be at least (IsDouble ? 327 : 48), and I suspect that that's exact.
599 // Here's a loose upper bound:
600 // 1 character for a negative sign
601 // + 325 (for double; 46 for float) characters in the "0.000~~~000" prefix of the min subnormal
602 // + 17 (for double; 9 for float) characters for round-trip digits
603 constexpr std::size_t fixed_buffer_size = IsDouble ? 1 + 325 + 17 : 1 + 46 + 9;
604 char fixed_buffer[fixed_buffer_size];
606 // worst case: negative sign + max normal + null terminator
607 constexpr std::size_t stdio_buffer_size = 1 + (IsDouble ? 309 : 39) + 1;
608 char stdio_buffer[stdio_buffer_size];
610 for (std::uint32_t frac = 0; frac < Fractions; ++frac) {
611 const UIntType bits = prefix + frac;
612 const FloatingType input = _Bit_cast<FloatingType>(bits);
615 const auto to_result = to_chars(buffer, end(buffer), input, chars_format::scientific);
616 assert_message_bits(to_result.ec == errc{}, "to_result.ec", bits);
617 // TODO Enable once std::from_chars has floating point support.
618 #if 0
619 const char* const last = to_result.ptr;
621 const auto from_result = from_chars(buffer, last, val);
623 assert_message_bits(from_result.ptr == last, "from_result.ptr", bits);
624 assert_message_bits(from_result.ec == errc{}, "from_result.ec", bits);
625 assert_message_bits(_Bit_cast<UIntType>(val) == bits, "round-trip", bits);
626 #endif
630 // Also verify that to_chars() and sprintf_s() emit the same output for integers in fixed notation.
631 const auto fixed_result = to_chars(fixed_buffer, end(fixed_buffer), input, chars_format::fixed);
632 assert_message_bits(fixed_result.ec == errc{}, "fixed_result.ec", bits);
633 const string_view fixed_sv(fixed_buffer, static_cast<std::size_t>(fixed_result.ptr - fixed_buffer));
635 if (find(fixed_sv.begin(), fixed_sv.end(), '.') == fixed_sv.end()) {
636 const int stdio_ret = sprintf_s(stdio_buffer, size(stdio_buffer), "%.0f", input);
637 assert_message_bits(stdio_ret != -1, "stdio_ret", bits);
638 const string_view stdio_sv(stdio_buffer);
639 assert_message_bits(fixed_sv == stdio_sv, "fixed_sv", bits);
645 template <bool IsDouble>
646 void test_floating_hex_prefix(const conditional_t<IsDouble, std::uint64_t, std::uint32_t> prefix) {
648 using UIntType = conditional_t<IsDouble, std::uint64_t, std::uint32_t>;
649 using FloatingType = conditional_t<IsDouble, double, float>;
651 // The precision is the number of hexits after the decimal point.
652 // These hexits correspond to the explicitly stored fraction bits.
653 // double explicitly stores 52 fraction bits. 52 / 4 == 13, so we need 13 hexits.
654 // float explicitly stores 23 fraction bits. 23 / 4 == 5.75, so we need 6 hexits.
656 // "-1.fffffffffffffp+1023" or "-1.fffffep+127"
657 constexpr std::size_t buffer_size = IsDouble ? 22 : 14;
658 char buffer[buffer_size];
659 // TODO Enable once std::from_chars has floating point support.
660 #if 0
661 FloatingType val;
662 #endif
664 for (std::uint32_t frac = 0; frac < Fractions; ++frac) {
665 const UIntType bits = prefix + frac;
666 const FloatingType input = _Bit_cast<FloatingType>(bits);
668 const auto to_result = to_chars(buffer, end(buffer), input, chars_format::hex);
669 assert_message_bits(to_result.ec == errc{}, "(hex) to_result.ec", bits);
670 // TODO Enable once std::from_chars has floating point support.
671 #if 0
672 const char* const last = to_result.ptr;
674 const auto from_result = from_chars(buffer, last, val, chars_format::hex);
676 assert_message_bits(from_result.ptr == last, "(hex) from_result.ptr", bits);
677 assert_message_bits(from_result.ec == errc{}, "(hex) from_result.ec", bits);
678 assert_message_bits(_Bit_cast<UIntType>(val) == bits, "(hex) round-trip", bits);
679 #endif
683 template <bool IsDouble>
684 void test_floating_precision_prefix(const conditional_t<IsDouble, std::uint64_t, std::uint32_t> prefix) {
686 using UIntType = conditional_t<IsDouble, std::uint64_t, std::uint32_t>;
687 using FloatingType = conditional_t<IsDouble, double, float>;
689 // Precision for min subnormal in fixed notation. (More than enough for scientific notation.)
690 constexpr int precision = IsDouble ? 1074 : 149;
692 // Number of digits for max normal in fixed notation.
693 constexpr int max_integer_length = IsDouble ? 309 : 39;
695 // Size for fixed notation. (More than enough for scientific notation.)
696 constexpr std::size_t charconv_buffer_size = 1 // negative sign
697 + max_integer_length // integer digits
698 + 1 // decimal point
699 + precision; // fractional digits
700 char charconv_buffer[charconv_buffer_size];
702 constexpr std::size_t stdio_buffer_size = charconv_buffer_size + 1; // null terminator
703 char stdio_buffer[stdio_buffer_size];
705 // 1 character for a negative sign
706 // + worst cases: 0x1.fffffffffffffp-1022 and 0x1.fffffep-126f
707 constexpr std::size_t general_buffer_size = 1 + (IsDouble ? 773 : 117);
708 char general_buffer[general_buffer_size];
709 char general_stdio_buffer[general_buffer_size + 1]; // + null terminator
711 for (std::uint32_t frac = 0; frac < Fractions; ++frac) {
712 const UIntType bits = prefix + frac;
713 const FloatingType input = _Bit_cast<FloatingType>(bits);
715 auto result = to_chars(charconv_buffer, end(charconv_buffer), input, chars_format::fixed, precision);
716 assert_message_bits(result.ec == errc{}, "to_chars fixed precision", bits);
717 string_view charconv_sv(charconv_buffer, static_cast<std::size_t>(result.ptr - charconv_buffer));
719 int stdio_ret = sprintf_s(stdio_buffer, size(stdio_buffer), "%.*f", precision, input);
720 assert_message_bits(stdio_ret != -1, "sprintf_s fixed precision", bits);
721 string_view stdio_sv(stdio_buffer);
723 assert_message_bits(charconv_sv == stdio_sv, "fixed precision output", bits);
726 result = to_chars(charconv_buffer, end(charconv_buffer), input, chars_format::scientific, precision);
727 assert_message_bits(result.ec == errc{}, "to_chars scientific precision", bits);
728 charconv_sv = string_view(charconv_buffer, static_cast<std::size_t>(result.ptr - charconv_buffer));
730 stdio_ret = sprintf_s(stdio_buffer, size(stdio_buffer), "%.*e", precision, input);
731 assert_message_bits(stdio_ret != -1, "sprintf_s scientific precision", bits);
732 stdio_sv = stdio_buffer;
734 assert_message_bits(charconv_sv == stdio_sv, "scientific precision output", bits);
737 result = to_chars(general_buffer, end(general_buffer), input, chars_format::general, 5000);
738 assert_message_bits(result.ec == errc{}, "to_chars general precision", bits);
739 charconv_sv = string_view(general_buffer, static_cast<std::size_t>(result.ptr - general_buffer));
741 stdio_ret = sprintf_s(general_stdio_buffer, size(general_stdio_buffer), "%.5000g", input);
742 assert_message_bits(stdio_ret != -1, "sprintf_s general precision", bits);
743 stdio_sv = general_stdio_buffer;
745 assert_message_bits(charconv_sv == stdio_sv, "general precision output", bits);
749 void test_floating_prefixes(mt19937_64& mt64) {
751 set<std::uint64_t> prefixes64;
753 while (prefixes64.size() < PrefixesToTest) {
754 const std::uint64_t val = mt64();
756 if ((val & 0x7FF0000000000000ULL) != 0x7FF0000000000000ULL) { // skip INF/NAN
757 prefixes64.insert(val & Mask64);
761 for (const auto& prefix : prefixes64) {
762 test_floating_prefix<true>(prefix);
763 test_floating_precision_prefix<true>(prefix);
766 test_floating_hex_prefix<true>(*prefixes64.begin()); // save time by testing fewer hexfloats
770 set<std::uint32_t> prefixes32;
772 while (prefixes32.size() < PrefixesToTest) {
773 const std::uint32_t val = static_cast<std::uint32_t>(mt64());
775 if ((val & 0x7F800000U) != 0x7F800000U) { // skip INF/NAN
776 prefixes32.insert(val & Mask32);
780 for (const auto& prefix : prefixes32) {
781 test_floating_prefix<false>(prefix);
782 test_floating_precision_prefix<false>(prefix);
785 test_floating_hex_prefix<false>(*prefixes32.begin()); // save time by testing fewer hexfloats
789 // TODO Enable once std::from_chars has floating point support.
790 #if 0
791 template <typename T>
792 void test_floating_from_chars(const chars_format fmt) {
793 test_from_chars<T>("", fmt, 0, inv_arg); // no characters
794 test_from_chars<T>("@1", fmt, 0, inv_arg); // '@' is bogus
795 test_from_chars<T>("z1", fmt, 0, inv_arg); // 'z' is bogus
796 test_from_chars<T>(".", fmt, 0, inv_arg); // '.' without digits is bogus
797 test_from_chars<T>("+1", fmt, 0, inv_arg); // '+' is bogus
798 test_from_chars<T>(" 1", fmt, 0, inv_arg); // ' ' is bogus
799 test_from_chars<T>("p5", fmt, 0, inv_arg); // binary-exponent-part without digits is bogus
800 test_from_chars<T>("in", fmt, 0, inv_arg); // incomplete inf is bogus
801 test_from_chars<T>("na", fmt, 0, inv_arg); // incomplete nan is bogus
803 test_from_chars<T>("-", fmt, 0, inv_arg); // '-' followed by no characters
804 test_from_chars<T>("-@1", fmt, 0, inv_arg); // '-' followed by bogus '@'
805 test_from_chars<T>("-z1", fmt, 0, inv_arg); // '-' followed by bogus 'z'
806 test_from_chars<T>("-.", fmt, 0, inv_arg); // '-' followed by bogus '.'
807 test_from_chars<T>("-+1", fmt, 0, inv_arg); // '-' followed by bogus '+'
808 test_from_chars<T>("- 1", fmt, 0, inv_arg); // '-' followed by bogus ' '
809 test_from_chars<T>("-p5", fmt, 0, inv_arg); // '-' followed by bogus binary-exponent-part
810 test_from_chars<T>("-in", fmt, 0, inv_arg); // '-' followed by bogus incomplete inf
811 test_from_chars<T>("-na", fmt, 0, inv_arg); // '-' followed by bogus incomplete nan
812 test_from_chars<T>("--1", fmt, 0, inv_arg); // '-' can't be repeated
814 if (fmt != chars_format::hex) { // "e5" are valid hexits
815 test_from_chars<T>("e5", fmt, 0, inv_arg); // exponent-part without digits is bogus
816 test_from_chars<T>("-e5", fmt, 0, inv_arg); // '-' followed by bogus exponent-part
819 constexpr T inf = numeric_limits<T>::infinity();
820 constexpr T qnan = numeric_limits<T>::quiet_NaN();
822 test_from_chars<T>("InF", fmt, 3, errc{}, inf);
823 test_from_chars<T>("infinite", fmt, 3, errc{}, inf);
824 test_from_chars<T>("iNfInItY", fmt, 8, errc{}, inf);
825 test_from_chars<T>("InfinityMeow", fmt, 8, errc{}, inf);
827 test_from_chars<T>("-InF", fmt, 4, errc{}, -inf);
828 test_from_chars<T>("-infinite", fmt, 4, errc{}, -inf);
829 test_from_chars<T>("-iNfInItY", fmt, 9, errc{}, -inf);
830 test_from_chars<T>("-InfinityMeow", fmt, 9, errc{}, -inf);
832 test_from_chars<T>("NaN", fmt, 3, errc{}, qnan);
833 test_from_chars<T>("nanotech", fmt, 3, errc{}, qnan);
834 test_from_chars<T>("nan(", fmt, 3, errc{}, qnan);
835 test_from_chars<T>("nan(@)", fmt, 3, errc{}, qnan);
836 test_from_chars<T>("nan(()", fmt, 3, errc{}, qnan);
837 test_from_chars<T>("nan(abc", fmt, 3, errc{}, qnan);
838 test_from_chars<T>("nan()", fmt, 5, errc{}, qnan);
839 test_from_chars<T>("nan(abc)def", fmt, 8, errc{}, qnan);
840 test_from_chars<T>("nan(_09AZaz)", fmt, 12, errc{}, qnan);
841 test_from_chars<T>("nan(int)", fmt, 8, errc{}, qnan);
842 test_from_chars<T>("nan(snap)", fmt, 9, errc{}, qnan);
844 test_from_chars<T>("-NaN", fmt, 4, errc{}, -qnan);
845 test_from_chars<T>("-nanotech", fmt, 4, errc{}, -qnan);
846 test_from_chars<T>("-nan(", fmt, 4, errc{}, -qnan);
847 test_from_chars<T>("-nan(@)", fmt, 4, errc{}, -qnan);
848 test_from_chars<T>("-nan(()", fmt, 4, errc{}, -qnan);
849 test_from_chars<T>("-nan(abc", fmt, 4, errc{}, -qnan);
850 test_from_chars<T>("-nan()", fmt, 6, errc{}, -qnan);
851 test_from_chars<T>("-nan(abc)def", fmt, 9, errc{}, -qnan);
852 test_from_chars<T>("-nan(_09AZaz)", fmt, 13, errc{}, -qnan);
853 test_from_chars<T>("-nan(int)", fmt, 9, errc{}, -qnan);
854 test_from_chars<T>("-nan(snap)", fmt, 10, errc{}, -qnan);
856 // The UCRT considers indeterminate NaN to be negative quiet NaN with no payload bits set.
857 // It parses "nan(ind)" and "-nan(ind)" identically.
858 test_from_chars<T>("nan(InD)", fmt, 8, errc{}, -qnan);
859 test_from_chars<T>("-nan(InD)", fmt, 9, errc{}, -qnan);
861 test_from_chars<T>("nan(SnAn)", fmt, 9, errc{}, nullopt, TestFromCharsMode::SignalingNaN);
862 test_from_chars<T>("-nan(SnAn)", fmt, 10, errc{}, nullopt, TestFromCharsMode::SignalingNaN);
864 switch (fmt) {
865 case chars_format::general:
866 test_from_chars<T>("1729", fmt, 4, errc{}, T{1729});
867 test_from_chars<T>("1729e3", fmt, 6, errc{}, T{1729000});
868 test_from_chars<T>("10", fmt, 2, errc{}, T{10});
869 test_from_chars<T>("11.", fmt, 3, errc{}, T{11});
870 test_from_chars<T>("12.13", fmt, 5, errc{}, static_cast<T>(12.13)); // avoid truncation warning
871 test_from_chars<T>(".14", fmt, 3, errc{}, static_cast<T>(.14)); // avoid truncation warning
872 test_from_chars<T>("20e5", fmt, 4, errc{}, T{2000000});
873 test_from_chars<T>("21.e5", fmt, 5, errc{}, T{2100000});
874 test_from_chars<T>("22.23e5", fmt, 7, errc{}, T{2223000});
875 test_from_chars<T>(".24e5", fmt, 5, errc{}, T{24000});
876 test_from_chars<T>("33e+5", fmt, 5, errc{}, T{3300000});
877 test_from_chars<T>("33e-5", fmt, 5, errc{}, static_cast<T>(.00033)); // avoid truncation warning
878 test_from_chars<T>("4E7", fmt, 3, errc{}, T{40000000});
879 test_from_chars<T>("-00123abc", fmt, 6, errc{}, T{-123});
880 test_from_chars<T>(".0045000", fmt, 8, errc{}, static_cast<T>(.0045)); // avoid truncation warning
881 test_from_chars<T>("000", fmt, 3, errc{}, T{0});
882 test_from_chars<T>("0e9999", fmt, 6, errc{}, T{0});
883 test_from_chars<T>("0e-9999", fmt, 7, errc{}, T{0});
884 test_from_chars<T>("-000", fmt, 4, errc{}, T{-0.0});
885 test_from_chars<T>("-0e9999", fmt, 7, errc{}, T{-0.0});
886 test_from_chars<T>("-0e-9999", fmt, 8, errc{}, T{-0.0});
887 test_from_chars<T>("1e9999", fmt, 6, errc::result_out_of_range, inf);
888 test_from_chars<T>("-1e9999", fmt, 7, errc::result_out_of_range, -inf);
889 test_from_chars<T>("1e-9999", fmt, 7, errc::result_out_of_range, T{0});
890 test_from_chars<T>("-1e-9999", fmt, 8, errc::result_out_of_range, T{-0.0});
891 test_from_chars<T>("1" + string(6000, '0'), fmt, 6001, errc::result_out_of_range, inf);
892 test_from_chars<T>("-1" + string(6000, '0'), fmt, 6002, errc::result_out_of_range, -inf);
893 test_from_chars<T>("." + string(6000, '0') + "1", fmt, 6002, errc::result_out_of_range, T{0});
894 test_from_chars<T>("-." + string(6000, '0') + "1", fmt, 6003, errc::result_out_of_range, T{-0.0});
895 test_from_chars<T>("1" + string(500, '0'), fmt, 501, errc::result_out_of_range, inf);
896 test_from_chars<T>("-1" + string(500, '0'), fmt, 502, errc::result_out_of_range, -inf);
897 test_from_chars<T>("." + string(500, '0') + "1", fmt, 502, errc::result_out_of_range, T{0});
898 test_from_chars<T>("-." + string(500, '0') + "1", fmt, 503, errc::result_out_of_range, T{-0.0});
899 break;
900 case chars_format::scientific:
901 test_from_chars<T>("1729", fmt, 0, inv_arg);
902 test_from_chars<T>("1729e3", fmt, 6, errc{}, T{1729000});
903 break;
904 case chars_format::fixed:
905 test_from_chars<T>("1729", fmt, 4, errc{}, T{1729});
906 test_from_chars<T>("1729e3", fmt, 4, errc{}, T{1729});
907 break;
908 case chars_format::hex:
909 test_from_chars<T>("0x123", fmt, 1, errc{}, T{0});
910 test_from_chars<T>("a0", fmt, 2, errc{}, T{160});
911 test_from_chars<T>("a1.", fmt, 3, errc{}, T{161});
912 test_from_chars<T>("a2.a3", fmt, 5, errc{}, T{162.63671875});
913 test_from_chars<T>(".a4", fmt, 3, errc{}, T{0.640625});
914 test_from_chars<T>("a0p5", fmt, 4, errc{}, T{5120});
915 test_from_chars<T>("a1.p5", fmt, 5, errc{}, T{5152});
916 test_from_chars<T>("a2.a3p5", fmt, 7, errc{}, T{5204.375});
917 test_from_chars<T>(".a4p5", fmt, 5, errc{}, T{20.5});
918 test_from_chars<T>("a0p+5", fmt, 5, errc{}, T{5120});
919 test_from_chars<T>("a0p-5", fmt, 5, errc{}, T{5});
920 test_from_chars<T>("ABCDEFP3", fmt, 8, errc{}, T{90075000});
921 test_from_chars<T>("-00cdrom", fmt, 5, errc{}, T{-205});
922 test_from_chars<T>(".00ef000", fmt, 8, errc{}, T{0.0036468505859375});
923 test_from_chars<T>("000", fmt, 3, errc{}, T{0});
924 test_from_chars<T>("0p9999", fmt, 6, errc{}, T{0});
925 test_from_chars<T>("0p-9999", fmt, 7, errc{}, T{0});
926 test_from_chars<T>("-000", fmt, 4, errc{}, T{-0.0});
927 test_from_chars<T>("-0p9999", fmt, 7, errc{}, T{-0.0});
928 test_from_chars<T>("-0p-9999", fmt, 8, errc{}, T{-0.0});
929 test_from_chars<T>("1p9999", fmt, 6, errc::result_out_of_range, inf);
930 test_from_chars<T>("-1p9999", fmt, 7, errc::result_out_of_range, -inf);
931 test_from_chars<T>("1p-9999", fmt, 7, errc::result_out_of_range, T{0});
932 test_from_chars<T>("-1p-9999", fmt, 8, errc::result_out_of_range, T{-0.0});
933 test_from_chars<T>("1" + string(2000, '0'), fmt, 2001, errc::result_out_of_range, inf);
934 test_from_chars<T>("-1" + string(2000, '0'), fmt, 2002, errc::result_out_of_range, -inf);
935 test_from_chars<T>("." + string(2000, '0') + "1", fmt, 2002, errc::result_out_of_range, T{0});
936 test_from_chars<T>("-." + string(2000, '0') + "1", fmt, 2003, errc::result_out_of_range, T{-0.0});
937 test_from_chars<T>("1" + string(300, '0'), fmt, 301, errc::result_out_of_range, inf);
938 test_from_chars<T>("-1" + string(300, '0'), fmt, 302, errc::result_out_of_range, -inf);
939 test_from_chars<T>("." + string(300, '0') + "1", fmt, 302, errc::result_out_of_range, T{0});
940 test_from_chars<T>("-." + string(300, '0') + "1", fmt, 303, errc::result_out_of_range, T{-0.0});
941 break;
944 #endif
946 template <typename T>
947 void test_floating_to_chars(
948 const T value, const optional<chars_format> opt_fmt, const optional<int> opt_precision, const string_view correct) {
950 test_common_to_chars(value, opt_fmt, opt_precision, correct);
953 void all_floating_tests(mt19937_64& mt64) {
954 test_floating_prefixes(mt64);
956 // TODO Enable once std::from_chars has floating point support.
957 #if 0
958 for (const auto& fmt : {chars_format::general, chars_format::scientific, chars_format::fixed, chars_format::hex}) {
959 test_floating_from_chars<float>(fmt);
960 test_floating_from_chars<double>(fmt);
963 // Test rounding.
965 // See float_from_chars_test_cases.hpp in this directory.
966 for (const auto& t : float_from_chars_test_cases) {
967 test_from_chars<float>(t.input, t.fmt, t.correct_idx, t.correct_ec, t.correct_value);
970 // See double_from_chars_test_cases.hpp in this directory.
971 for (const auto& t : double_from_chars_test_cases) {
972 test_from_chars<double>(t.input, t.fmt, t.correct_idx, t.correct_ec, t.correct_value);
976 // See LWG-2403. This number (exactly 0x1.fffffd00000004 in infinite precision) behaves differently
977 // when parsed as double and converted to float, versus being parsed as float directly.
978 const char* const lwg_2403 = "1.999999821186065729339276231257827021181583404541015625";
979 constexpr float correct_float = 0x1.fffffep0f;
980 constexpr double correct_double = 0x1.fffffdp0;
981 constexpr float twice_rounded_float = 0x1.fffffcp0f;
983 test_from_chars<float>(lwg_2403, chars_format::general, 56, errc{}, correct_float);
984 test_from_chars<double>(lwg_2403, chars_format::general, 56, errc{}, correct_double);
985 static_assert(static_cast<float>(correct_double) == twice_rounded_float);
988 // See floating_point_test_cases.hpp.
989 for (const auto& p : floating_point_test_cases_float) {
990 test_from_chars<float>(p.first, chars_format::general, strlen(p.first), errc{}, _Bit_cast<float>(p.second));
993 for (const auto& p : floating_point_test_cases_double) {
994 test_from_chars<double>(p.first, chars_format::general, strlen(p.first), errc{}, _Bit_cast<double>(p.second));
996 #endif
997 // See float_to_chars_test_cases.hpp in this directory.
998 for (const auto& t : float_to_chars_test_cases) {
999 if (t.fmt == chars_format{}) {
1000 test_floating_to_chars(t.value, nullopt, nullopt, t.correct);
1001 } else {
1002 test_floating_to_chars(t.value, t.fmt, nullopt, t.correct);
1006 // See double_to_chars_test_cases.hpp in this directory.
1007 for (const auto& t : double_to_chars_test_cases) {
1008 if (t.fmt == chars_format{}) {
1009 test_floating_to_chars(t.value, nullopt, nullopt, t.correct);
1010 } else {
1011 test_floating_to_chars(t.value, t.fmt, nullopt, t.correct);
1015 // See corresponding headers in this directory.
1016 for (const auto& t : float_hex_precision_to_chars_test_cases) {
1017 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1019 for (const auto& t : float_fixed_precision_to_chars_test_cases) {
1020 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1022 for (const auto& t : float_scientific_precision_to_chars_test_cases) {
1023 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1025 for (const auto& t : float_general_precision_to_chars_test_cases) {
1026 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1028 for (const auto& t : double_hex_precision_to_chars_test_cases) {
1029 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1031 for (const auto& t : double_fixed_precision_to_chars_test_cases_1) {
1032 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1034 for (const auto& t : double_fixed_precision_to_chars_test_cases_2) {
1035 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1037 for (const auto& t : double_fixed_precision_to_chars_test_cases_3) {
1038 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1040 for (const auto& t : double_fixed_precision_to_chars_test_cases_4) {
1041 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1043 for (const auto& t : double_scientific_precision_to_chars_test_cases_1) {
1044 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1046 for (const auto& t : double_scientific_precision_to_chars_test_cases_2) {
1047 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1049 for (const auto& t : double_scientific_precision_to_chars_test_cases_3) {
1050 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1052 for (const auto& t : double_scientific_precision_to_chars_test_cases_4) {
1053 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1055 for (const auto& t : double_general_precision_to_chars_test_cases) {
1056 test_floating_to_chars(t.value, t.fmt, t.precision, t.correct);
1060 int main(int argc, char** argv) {
1061 const auto start = chrono::steady_clock::now();
1063 mt19937_64 mt64;
1065 initialize_randomness(mt64, argc, argv);
1067 all_integer_tests();
1069 all_floating_tests(mt64);
1071 const auto finish = chrono::steady_clock::now();
1072 const long long ms = chrono::duration_cast<chrono::milliseconds>(finish - start).count();
1074 puts("PASS");
1075 printf("Randomized test cases: %zu\n", static_cast<std::size_t>(PrefixesToTest * Fractions));
1076 printf("Total time: %lld ms\n", ms);
1078 if (ms < 3'000) {
1079 puts("That was fast. Consider tuning PrefixesToTest and FractionBits to test more cases.");
1080 } else if (ms > 30'000) {
1081 puts("That was slow. Consider tuning PrefixesToTest and FractionBits to test fewer cases.");