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