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