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