1561 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// XFAIL: availability-fp_from_chars-missing12 13// from_chars_result from_chars(const char* first, const char* last,14// float& value, chars_format fmt = chars_format::general)15//16// from_chars_result from_chars(const char* first, const char* last,17// double& value, chars_format fmt = chars_format::general)18 19#include <array>20#include <charconv>21#include <cmath>22#include <cstring>23#include <limits>24#include <stdexcept>25#include <system_error>26 27#include "charconv_test_helpers.h"28#include "test_macros.h"29 30template <class F>31void test_infinity(std::chars_format fmt) {32 const char* s = "-InFiNiTyXXX";33 { // I34 F value = 0.25;35 std::from_chars_result result = std::from_chars(s + 1, s + 2, value, fmt);36 37 assert(result.ec == std::errc::invalid_argument);38 assert(result.ptr == s + 1);39 assert(value == F(0.25));40 }41 { // In42 F value = 0.25;43 std::from_chars_result result = std::from_chars(s + 1, s + 3, value, fmt);44 45 assert(result.ec == std::errc::invalid_argument);46 assert(result.ptr == s + 1);47 assert(value == F(0.25));48 }49 { // InF50 F value = 0.25;51 std::from_chars_result result = std::from_chars(s + 1, s + 4, value, fmt);52 53 assert(result.ec == std::errc{});54 assert(result.ptr == s + 4);55 assert(value == std::numeric_limits<F>::infinity());56 }57 { // -InF58 F value = 0.25;59 std::from_chars_result result = std::from_chars(s, s + 4, value, fmt);60 61 assert(result.ec == std::errc{});62 assert(result.ptr == s + 4);63 assert(value == -std::numeric_limits<F>::infinity());64 }65 { // InFi66 F value = 0.25;67 std::from_chars_result result = std::from_chars(s + 1, s + 5, value, fmt);68 69 assert(result.ec == std::errc{});70 assert(result.ptr == s + 4);71 assert(value == std::numeric_limits<F>::infinity());72 }73 { // -InFiN74 F value = 0.25;75 std::from_chars_result result = std::from_chars(s, s + 6, value, fmt);76 77 assert(result.ec == std::errc{});78 assert(result.ptr == s + 4);79 assert(value == -std::numeric_limits<F>::infinity());80 }81 { // InFiNi82 F value = 0.25;83 std::from_chars_result result = std::from_chars(s + 1, s + 7, value, fmt);84 85 assert(result.ec == std::errc{});86 assert(result.ptr == s + 4);87 assert(value == std::numeric_limits<F>::infinity());88 }89 { // -InFiNiT90 F value = 0.25;91 std::from_chars_result result = std::from_chars(s, s + 8, value, fmt);92 93 assert(result.ec == std::errc{});94 assert(result.ptr == s + 4);95 assert(value == -std::numeric_limits<F>::infinity());96 }97 { // InFiNiTy98 F value = 0.25;99 std::from_chars_result result = std::from_chars(s + 1, s + 9, value, fmt);100 101 assert(result.ec == std::errc{});102 assert(result.ptr == s + 9);103 assert(value == std::numeric_limits<F>::infinity());104 }105 { // -InFiNiTy106 F value = 0.25;107 std::from_chars_result result = std::from_chars(s, s + 9, value, fmt);108 109 assert(result.ec == std::errc{});110 assert(result.ptr == s + 9);111 assert(value == -std::numeric_limits<F>::infinity());112 }113 { // InFiNiTyXXX114 F value = 0.25;115 std::from_chars_result result = std::from_chars(s + 1, s + 12, value, fmt);116 117 assert(result.ec == std::errc{});118 assert(result.ptr == s + 9);119 assert(value == std::numeric_limits<F>::infinity());120 }121 { // -InFiNiTyXXX122 F value = 0.25;123 std::from_chars_result result = std::from_chars(s, s + 12, value, fmt);124 125 assert(result.ec == std::errc{});126 assert(result.ptr == s + 9);127 assert(value == -std::numeric_limits<F>::infinity());128 }129}130 131template <class F>132void test_nan(std::chars_format fmt) {133 {134 const char* s = "-NaN(1_A)XXX";135 { // N136 F value = 0.25;137 std::from_chars_result result = std::from_chars(s + 1, s + 2, value, fmt);138 139 assert(result.ec == std::errc::invalid_argument);140 assert(result.ptr == s + 1);141 assert(value == F(0.25));142 }143 { // Na144 F value = 0.25;145 std::from_chars_result result = std::from_chars(s + 1, s + 3, value, fmt);146 147 assert(result.ec == std::errc::invalid_argument);148 assert(result.ptr == s + 1);149 assert(value == F(0.25));150 }151 { // NaN152 F value = 0.25;153 std::from_chars_result result = std::from_chars(s + 1, s + 4, value, fmt);154 155 assert(result.ec == std::errc{});156 assert(result.ptr == s + 4);157 assert(std::isnan(value));158 assert(!std::signbit(value));159 }160 { // -NaN161 F value = 0.25;162 std::from_chars_result result = std::from_chars(s + 0, s + 4, value, fmt);163 164 assert(result.ec == std::errc{});165 assert(result.ptr == s + 4);166 assert(std::isnan(value));167 assert(std::signbit(value));168 }169 { // NaN(170 F value = 0.25;171 std::from_chars_result result = std::from_chars(s + 1, s + 5, value, fmt);172 173 assert(result.ec == std::errc{});174 assert(result.ptr == s + 4);175 assert(std::isnan(value));176 assert(!std::signbit(value));177 }178 { // -NaN(1179 F value = 0.25;180 std::from_chars_result result = std::from_chars(s, s + 6, value, fmt);181 182 assert(result.ec == std::errc{});183 assert(result.ptr == s + 4);184 assert(std::isnan(value));185 assert(std::signbit(value));186 }187 { // NaN(1_188 F value = 0.25;189 std::from_chars_result result = std::from_chars(s + 1, s + 7, value, fmt);190 191 assert(result.ec == std::errc{});192 assert(result.ptr == s + 4);193 assert(std::isnan(value));194 assert(!std::signbit(value));195 }196 { // -NaN(1_A197 F value = 0.25;198 std::from_chars_result result = std::from_chars(s, s + 8, value, fmt);199 200 assert(result.ec == std::errc{});201 assert(result.ptr == s + 4);202 assert(std::isnan(value));203 assert(std::signbit(value));204 }205 { // NaN(1_A)206 F value = 0.25;207 std::from_chars_result result = std::from_chars(s + 1, s + 9, value, fmt);208 209 assert(result.ec == std::errc{});210 assert(result.ptr == s + 9);211 assert(std::isnan(value));212 assert(!std::signbit(value));213 }214 { // -NaN(1_A)215 F value = 0.25;216 std::from_chars_result result = std::from_chars(s, s + 9, value, fmt);217 218 assert(result.ec == std::errc{});219 assert(result.ptr == s + 9);220 assert(std::isnan(value));221 assert(std::signbit(value));222 }223 { // NaN(1_A)XXX224 F value = 0.25;225 std::from_chars_result result = std::from_chars(s + 1, s + 12, value, fmt);226 227 assert(result.ec == std::errc{});228 assert(result.ptr == s + 9);229 assert(std::isnan(value));230 assert(!std::signbit(value));231 }232 { // -NaN(1_A)XXX233 F value = 0.25;234 std::from_chars_result result = std::from_chars(s, s + 12, value, fmt);235 236 assert(result.ec == std::errc{});237 assert(result.ptr == s + 9);238 assert(std::isnan(value));239 assert(std::signbit(value));240 }241 }242 {243 const char* s = "NaN()";244 F value = 0.25;245 std::from_chars_result result = std::from_chars(s, s + std::strlen(s), value, fmt);246 247 assert(result.ec == std::errc{});248 assert(result.ptr == s + 5);249 assert(std::isnan(value));250 assert(!std::signbit(value));251 }252 { // validates a n-char-sequences with an invalid value253 std::array s = {'N', 'a', 'N', '(', ' ', ')'};254 s[4] = 'a';255 {256 F value = 0.25;257 std::from_chars_result result = std::from_chars(s.data(), s.data() + s.size(), value, fmt);258 259 assert(result.ec == std::errc{});260 assert(result.ptr == s.data() + s.size());261 assert(std::isnan(value));262 assert(!std::signbit(value));263 }264 for (auto c : "!@#$%^&*(-=+[]{}|\\;:'\",./<>?~` \t\v\r\n") {265 F value = 0.25;266 s[4] = c;267 std::from_chars_result result = std::from_chars(s.data(), s.data() + s.size(), value, fmt);268 269 assert(result.ec == std::errc{});270 assert(result.ptr == s.data() + 3);271 assert(std::isnan(value));272 assert(!std::signbit(value));273 }274 }275}276 277template <class F>278void test_fmt_independent(std::chars_format fmt) {279 test_infinity<F>(fmt);280 test_nan<F>(fmt);281 282 { // first == last283 F value = 0.25;284 std::from_chars_result result = std::from_chars(nullptr, nullptr, value, fmt);285 286 assert(result.ec == std::errc::invalid_argument);287 assert(result.ptr == nullptr);288 assert(value == F(0.25));289 }290 { // only a sign291 F value = 0.25;292 const char* s = "-";293 std::from_chars_result result = std::from_chars(s, s + std::strlen(s), value, fmt);294 295 assert(result.ec == std::errc::invalid_argument);296 assert(result.ptr == s);297 assert(value == F(0.25));298 }299 { // only decimal separator300 F value = 0.25;301 const char* s = ".";302 std::from_chars_result result = std::from_chars(s, s + std::strlen(s), value, fmt);303 304 assert(result.ec == std::errc::invalid_argument);305 assert(result.ptr == s);306 assert(value == F(0.25));307 }308 { // sign and decimal separator309 F value = 0.25;310 const char* s = "-.";311 std::from_chars_result result = std::from_chars(s, s + std::strlen(s), value, fmt);312 313 assert(result.ec == std::errc::invalid_argument);314 assert(result.ptr == s);315 assert(value == F(0.25));316 }317 { // + sign is not allowed318 F value = 0.25;319 const char* s = "+0.25";320 std::from_chars_result result = std::from_chars(s, s + std::strlen(s), value, fmt);321 322 assert(result.ec == std::errc::invalid_argument);323 assert(result.ptr == s);324 assert(value == F(0.25));325 }326}327 328template <class F>329struct test_basics {330 void operator()() {331 for (auto fmt : {std::chars_format::scientific,332 std::chars_format::fixed,333 /*std::chars_format::hex,*/ std::chars_format::general})334 test_fmt_independent<F>(fmt);335 }336};337 338template <class F>339struct test_fixed {340 void operator()() {341 std::from_chars_result r;342 F x = 0.25;343 344 // *** Failures345 346 { // Starts with invalid character347 std::array s = {' ', '1'};348 for (auto c : "abcdefghijklmnopqrstuvwxyz"349 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"350 "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {351 s[0] = c;352 r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::fixed);353 354 assert(r.ec == std::errc::invalid_argument);355 assert(r.ptr == s.data());356 assert(x == F(0.25));357 }358 }359 360 // *** Success361 362 { // number followed by non-numeric values363 const char* s = "001x";364 365 // the expected form of the subject sequence is a nonempty sequence of366 // decimal digits optionally containing a decimal-point character, then367 // an optional exponent part as defined in 6.4.4.3, excluding any digit368 // separators (6.4.4.2); (C23 7.24.1.5)369 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);370 assert(r.ec == std::errc{});371 assert(r.ptr == s + 3);372 assert(x == F(1.0));373 }374 { // no leading digit375 const char* s = ".5";376 377 // the expected form of the subject sequence is a nonempty sequence of378 // decimal digits optionally containing a decimal-point character, then379 // an optional exponent part as defined in 6.4.4.3, excluding any digit380 // separators (6.4.4.2); (C23 7.24.1.5)381 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);382 assert(r.ec == std::errc{});383 assert(r.ptr == s + 2);384 assert(x == F(0.5));385 }386 { // negative sign and no leading digit387 const char* s = "-.5";388 389 // the expected form of the subject sequence is a nonempty sequence of390 // decimal digits optionally containing a decimal-point character, then391 // an optional exponent part as defined in 6.4.4.3, excluding any digit392 // separators (6.4.4.2); (C23 7.24.1.5)393 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);394 assert(r.ec == std::errc{});395 assert(r.ptr == s + 3);396 assert(x == F(-0.5));397 }398 399 { // double decimal point400 const char* s = "1.25.78";401 402 // This number is halfway between two float values.403 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);404 assert(r.ec == std::errc{});405 assert(r.ptr == s + 4);406 assert(x == F(1.25));407 }408 { // exponent no sign409 const char* s = "1.5e10";410 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);411 412 assert(r.ec == std::errc{});413 assert(r.ptr == s + 3);414 assert(x == F(1.5));415 }416 { // exponent capitalized no sign417 const char* s = "1.5E10";418 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);419 420 assert(r.ec == std::errc{});421 assert(r.ptr == s + 3);422 assert(x == F(1.5));423 }424 { // exponent + sign425 const char* s = "1.5e+10";426 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);427 428 assert(r.ec == std::errc{});429 assert(r.ptr == s + 3);430 assert(x == F(1.5));431 }432 { // exponent - sign433 const char* s = "1.5e-10";434 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);435 436 assert(r.ec == std::errc{});437 assert(r.ptr == s + 3);438 assert(x == F(1.5));439 }440 { // Exponent no number441 const char* s = "1.5e";442 443 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);444 assert(r.ec == std::errc{});445 assert(r.ptr == s + 3);446 assert(x == F(1.5));447 }448 { // Exponent sign no number449 {450 const char* s = "1.5e+";451 452 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);453 assert(r.ec == std::errc{});454 assert(r.ptr == s + 3);455 assert(x == F(1.5));456 }457 {458 const char* s = "1.5e-";459 460 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);461 assert(r.ec == std::errc{});462 assert(r.ptr == s + 3);463 assert(x == F(1.5));464 }465 }466 { // Exponent with whitespace467 {468 const char* s = "1.5e +1";469 470 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);471 assert(r.ec == std::errc{});472 assert(r.ptr == s + 3);473 assert(x == F(1.5));474 }475 {476 const char* s = "1.5e+ 1";477 478 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);479 assert(r.ec == std::errc{});480 assert(r.ptr == s + 3);481 assert(x == F(1.5));482 }483 {484 const char* s = "1.5e -1";485 486 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);487 assert(r.ec == std::errc{});488 assert(r.ptr == s + 3);489 assert(x == F(1.5));490 }491 {492 const char* s = "1.5e- 1";493 494 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);495 assert(r.ec == std::errc{});496 assert(r.ptr == s + 3);497 assert(x == F(1.5));498 }499 }500 { // double exponent501 const char* s = "1.25e0e12";502 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);503 504 assert(r.ec == std::errc{});505 assert(r.ptr == s + 4);506 assert(x == F(1.25));507 }508 { // Exponent double sign509 {510 const char* s = "1.25e++12";511 512 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);513 assert(r.ec == std::errc{});514 assert(r.ptr == s + 4);515 assert(x == F(1.25));516 }517 {518 const char* s = "1.25e+-12";519 520 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);521 assert(r.ec == std::errc{});522 assert(r.ptr == s + 4);523 assert(x == F(1.25));524 }525 {526 const char* s = "1.25e-+12";527 528 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);529 assert(r.ec == std::errc{});530 assert(r.ptr == s + 4);531 assert(x == F(1.25));532 }533 {534 const char* s = "1.25e--12";535 536 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);537 assert(r.ec == std::errc{});538 assert(r.ptr == s + 4);539 assert(x == F(1.25));540 }541 }542 { // exponent hex prefix543 const char* s = "1.25e0x12";544 545 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);546 assert(r.ec == std::errc{});547 assert(r.ptr == s + 4);548 assert(x == F(1.25));549 }550 { // This number is halfway between two float values.551 const char* s = "20040229";552 553 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);554 assert(r.ec == std::errc{});555 assert(r.ptr == s + 8);556 assert(x == F(20040229));557 }558 { // Shifting mantissa exponent and no exponent559 const char* s = "123.456";560 561 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);562 assert(r.ec == std::errc{});563 assert(r.ptr == s + 7);564 assert(x == F(1.23456e2));565 }566 { // Shifting mantissa exponent and an exponent567 const char* s = "123.456e3";568 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);569 570 assert(r.ec == std::errc{});571 assert(r.ptr == s + 7);572 assert(x == F(123.456));573 }574 { // Mantissa overflow575 {576 const char* s = "0.111111111111111111111111111111111111111111";577 578 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);579 assert(r.ec == std::errc{});580 assert(r.ptr == s + std::strlen(s));581 assert(x == F(0.111111111111111111111111111111111111111111));582 }583 {584 const char* s = "111111111111.111111111111111111111111111111111111111111";585 586 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);587 assert(r.ec == std::errc{});588 assert(r.ptr == s + std::strlen(s));589 assert(x == F(111111111111.111111111111111111111111111111111111111111));590 }591 }592 { // Negative value593 const char* s = "-0.25";594 595 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);596 assert(r.ec == std::errc{});597 assert(r.ptr == s + std::strlen(s));598 assert(x == F(-0.25));599 }600 }601};602 603template <class F>604struct test_scientific {605 void operator()() {606 std::from_chars_result r;607 F x = 0.25;608 609 // *** Failures610 611 { // Starts with invalid character612 std::array s = {' ', '1', 'e', '0'};613 for (auto c : "abcdefghijklmnopqrstuvwxyz"614 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"615 "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {616 s[0] = c;617 r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::scientific);618 619 assert(r.ec == std::errc::invalid_argument);620 assert(r.ptr == s.data());621 assert(x == F(0.25));622 }623 }624 { // No exponent625 const char* s = "1.23";626 r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);627 628 assert(r.ec == std::errc::invalid_argument);629 assert(r.ptr == s);630 assert(x == F(0.25));631 }632 { // Exponent no number633 const char* s = "1.23e";634 r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);635 636 assert(r.ec == std::errc::invalid_argument);637 assert(r.ptr == s);638 assert(x == F(0.25));639 }640 { // Exponent sign no number641 {642 const char* s = "1.5e+";643 644 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);645 assert(r.ec == std::errc::invalid_argument);646 assert(r.ptr == s);647 assert(x == F(0.25));648 }649 {650 const char* s = "1.5e-";651 652 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);653 assert(r.ec == std::errc::invalid_argument);654 assert(r.ptr == s);655 assert(x == F(0.25));656 }657 }658 { // Exponent with whitespace659 {660 const char* s = "1.5e +1";661 662 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);663 assert(r.ec == std::errc::invalid_argument);664 assert(r.ptr == s);665 assert(x == F(0.25));666 }667 {668 const char* s = "1.5e+ 1";669 670 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);671 assert(r.ec == std::errc::invalid_argument);672 assert(r.ptr == s);673 assert(x == F(0.25));674 }675 {676 const char* s = "1.5e -1";677 678 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);679 assert(r.ec == std::errc::invalid_argument);680 assert(r.ptr == s);681 assert(x == F(0.25));682 }683 {684 const char* s = "1.5e- 1";685 686 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);687 assert(r.ec == std::errc::invalid_argument);688 assert(r.ptr == s);689 assert(x == F(0.25));690 }691 }692 { // exponent double sign693 {694 const char* s = "1.25e++12";695 696 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);697 assert(r.ec == std::errc::invalid_argument);698 assert(r.ptr == s);699 assert(x == F(0.25));700 }701 {702 const char* s = "1.25e+-12";703 704 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);705 assert(r.ec == std::errc::invalid_argument);706 assert(r.ptr == s);707 assert(x == F(0.25));708 }709 {710 const char* s = "1.25e-+12";711 712 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);713 assert(r.ec == std::errc::invalid_argument);714 assert(r.ptr == s);715 assert(x == F(0.25));716 }717 {718 const char* s = "1.25e--12";719 720 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);721 assert(r.ec == std::errc::invalid_argument);722 assert(r.ptr == s);723 assert(x == F(0.25));724 }725 }726 727 // *** Success728 729 { // number followed by non-numeric values730 const char* s = "001e0x";731 732 // the expected form of the subject sequence is a nonempty sequence of733 // decimal digits optionally containing a decimal-point character, then734 // an optional exponent part as defined in 6.4.4.3, excluding any digit735 // separators (6.4.4.2); (C23 7.24.1.5)736 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);737 assert(r.ec == std::errc{});738 assert(r.ptr == s + 5);739 assert(x == F(1.0));740 }741 742 { // double decimal point743 const char* s = "1.25e0.78";744 745 // This number is halfway between two float values.746 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);747 assert(r.ec == std::errc{});748 assert(r.ptr == s + 6);749 assert(x == F(1.25));750 }751 752 { // exponent no sign753 const char* s = "1.5e10";754 755 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);756 assert(r.ec == std::errc{});757 assert(r.ptr == s + 6);758 assert(x == F(1.5e10));759 }760 { // exponent capitalized no sign761 const char* s = "1.5E10";762 763 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);764 assert(r.ec == std::errc{});765 assert(r.ptr == s + 6);766 assert(x == F(1.5e10));767 }768 { // exponent + sign769 const char* s = "1.5e+10";770 771 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);772 assert(r.ec == std::errc{});773 assert(r.ptr == s + 7);774 assert(x == F(1.5e10));775 }776 { // exponent - sign777 const char* s = "1.5e-10";778 779 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);780 assert(r.ec == std::errc{});781 assert(r.ptr == s + 7);782 assert(x == F(1.5e-10));783 }784 { // exponent hex prefix -> e0785 const char* s = "1.25e0x12";786 787 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);788 assert(r.ec == std::errc{});789 assert(r.ptr == s + 6);790 assert(x == F(1.25));791 }792 { // double exponent793 const char* s = "1.25e0e12";794 795 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);796 assert(r.ec == std::errc{});797 assert(r.ptr == s + 6);798 assert(x == F(1.25));799 }800 { // This number is halfway between two float values.801 const char* s = "20040229e0";802 803 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);804 assert(r.ec == std::errc{});805 assert(r.ptr == s + 10);806 assert(x == F(20040229));807 }808 { // Shifting mantissa exponent and an exponent809 const char* s = "123.456e3";810 811 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);812 assert(r.ec == std::errc{});813 assert(r.ptr == s + 9);814 assert(x == F(1.23456e5));815 }816 { // Mantissa overflow817 {818 const char* s = "0.111111111111111111111111111111111111111111e0";819 820 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);821 assert(r.ec == std::errc{});822 assert(r.ptr == s + std::strlen(s));823 assert(x == F(0.111111111111111111111111111111111111111111));824 }825 {826 const char* s = "111111111111.111111111111111111111111111111111111111111e0";827 828 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);829 assert(r.ec == std::errc{});830 assert(r.ptr == s + std::strlen(s));831 assert(x == F(111111111111.111111111111111111111111111111111111111111));832 }833 }834 { // Negative value835 const char* s = "-0.25e0";836 837 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);838 assert(r.ec == std::errc{});839 assert(r.ptr == s + std::strlen(s));840 assert(x == F(-0.25));841 }842 { // value is too big -> +inf843 const char* s = "1e9999999999999999999999999999999999999999";844 845 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);846 assert(r.ec == std::errc::result_out_of_range);847 assert(r.ptr == s + strlen(s));848 assert(x == std::numeric_limits<F>::infinity());849 }850 { // negative value is too big -> -inf851 const char* s = "-1e9999999999999999999999999999999999999999";852 853 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);854 assert(r.ec == std::errc::result_out_of_range);855 assert(r.ptr == s + strlen(s));856 assert(x == -std::numeric_limits<F>::infinity());857 }858 { // value is too small -> 0859 const char* s = "1e-9999999999999999999999999999999999999999";860 861 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);862 assert(r.ec == std::errc::result_out_of_range);863 assert(r.ptr == s + strlen(s));864 assert(x == F(0.0));865 }866 { // negative value is too small -> -0867 const char* s = "-1e-9999999999999999999999999999999999999999";868 869 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);870 assert(r.ec == std::errc::result_out_of_range);871 assert(r.ptr == s + strlen(s));872 assert(x == F(-0.0));873 }874 }875};876 877template <class F>878struct test_general {879 void operator()() {880 std::from_chars_result r;881 F x = 0.25;882 883 // *** Failures884 885 { // Starts with invalid character886 std::array s = {' ', '1'};887 for (auto c : "abcdefghijklmnopqrstuvwxyz"888 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"889 "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {890 s[0] = c;891 r = std::from_chars(s.data(), s.data() + s.size(), x);892 893 assert(r.ec == std::errc::invalid_argument);894 assert(r.ptr == s.data());895 assert(x == F(0.25));896 }897 }898 899 // *** Success900 901 { // number followed by non-numeric values902 const char* s = "001x";903 904 // the expected form of the subject sequence is a nonempty sequence of905 // decimal digits optionally containing a decimal-point character, then906 // an optional exponent part as defined in 6.4.4.3, excluding any digit907 // separators (6.4.4.2); (C23 7.24.1.5)908 r = std::from_chars(s, s + std::strlen(s), x);909 assert(r.ec == std::errc{});910 assert(r.ptr == s + 3);911 assert(x == F(1.0));912 }913 { // no leading digit914 const char* s = ".5e0";915 916 // the expected form of the subject sequence is a nonempty sequence of917 // decimal digits optionally containing a decimal-point character, then918 // an optional exponent part as defined in 6.4.4.3, excluding any digit919 // separators (6.4.4.2); (C23 7.24.1.5)920 r = std::from_chars(s, s + std::strlen(s), x);921 assert(r.ec == std::errc{});922 assert(r.ptr == s + 4);923 assert(x == F(0.5));924 }925 { // negative sign and no leading digit926 const char* s = "-.5e0";927 928 // the expected form of the subject sequence is a nonempty sequence of929 // decimal digits optionally containing a decimal-point character, then930 // an optional exponent part as defined in 6.4.4.3, excluding any digit931 // separators (6.4.4.2); (C23 7.24.1.5)932 r = std::from_chars(s, s + std::strlen(s), x);933 assert(r.ec == std::errc{});934 assert(r.ptr == s + 5);935 assert(x == F(-0.5));936 }937 { // no leading digit938 const char* s = ".5";939 940 // the expected form of the subject sequence is a nonempty sequence of941 // decimal digits optionally containing a decimal-point character, then942 // an optional exponent part as defined in 6.4.4.3, excluding any digit943 // separators (6.4.4.2); (C23 7.24.1.5)944 r = std::from_chars(s, s + std::strlen(s), x);945 assert(r.ec == std::errc{});946 assert(r.ptr == s + 2);947 assert(x == F(0.5));948 }949 { // negative sign and no leading digit950 const char* s = "-.5";951 952 // the expected form of the subject sequence is a nonempty sequence of953 // decimal digits optionally containing a decimal-point character, then954 // an optional exponent part as defined in 6.4.4.3, excluding any digit955 // separators (6.4.4.2); (C23 7.24.1.5)956 r = std::from_chars(s, s + std::strlen(s), x);957 assert(r.ec == std::errc{});958 assert(r.ptr == s + 3);959 assert(x == F(-0.5));960 }961 { // double decimal point962 const char* s = "1.25.78";963 964 // This number is halfway between two float values.965 r = std::from_chars(s, s + std::strlen(s), x);966 assert(r.ec == std::errc{});967 assert(r.ptr == s + 4);968 assert(x == F(1.25));969 }970 { // exponent no sign971 const char* s = "1.5e10";972 973 r = std::from_chars(s, s + std::strlen(s), x);974 assert(r.ec == std::errc{});975 assert(r.ptr == s + 6);976 assert(x == F(1.5e10));977 }978 { // exponent capitalized no sign979 const char* s = "1.5E10";980 981 r = std::from_chars(s, s + std::strlen(s), x);982 assert(r.ec == std::errc{});983 assert(r.ptr == s + 6);984 assert(x == F(1.5e10));985 }986 { // exponent + sign987 const char* s = "1.5e+10";988 989 r = std::from_chars(s, s + std::strlen(s), x);990 assert(r.ec == std::errc{});991 assert(r.ptr == s + 7);992 assert(x == F(1.5e10));993 }994 { // exponent - sign995 const char* s = "1.5e-10";996 997 r = std::from_chars(s, s + std::strlen(s), x);998 assert(r.ec == std::errc{});999 assert(r.ptr == s + 7);1000 assert(x == F(1.5e-10));1001 }1002 { // Exponent no number1003 const char* s = "1.5e";1004 1005 r = std::from_chars(s, s + std::strlen(s), x);1006 assert(r.ec == std::errc{});1007 assert(r.ptr == s + 3);1008 assert(x == F(1.5));1009 }1010 { // Exponent sign no number1011 {1012 const char* s = "1.5e+";1013 1014 r = std::from_chars(s, s + std::strlen(s), x);1015 assert(r.ec == std::errc{});1016 assert(r.ptr == s + 3);1017 assert(x == F(1.5));1018 }1019 {1020 const char* s = "1.5e-";1021 1022 r = std::from_chars(s, s + std::strlen(s), x);1023 assert(r.ec == std::errc{});1024 assert(r.ptr == s + 3);1025 assert(x == F(1.5));1026 }1027 }1028 { // Exponent with whitespace1029 {1030 const char* s = "1.5e +1";1031 1032 r = std::from_chars(s, s + std::strlen(s), x);1033 assert(r.ec == std::errc{});1034 assert(r.ptr == s + 3);1035 assert(x == F(1.5));1036 }1037 {1038 const char* s = "1.5e+ 1";1039 1040 r = std::from_chars(s, s + std::strlen(s), x);1041 assert(r.ec == std::errc{});1042 assert(r.ptr == s + 3);1043 assert(x == F(1.5));1044 }1045 {1046 const char* s = "1.5e -1";1047 1048 r = std::from_chars(s, s + std::strlen(s), x);1049 assert(r.ec == std::errc{});1050 assert(r.ptr == s + 3);1051 assert(x == F(1.5));1052 }1053 {1054 const char* s = "1.5e- 1";1055 1056 r = std::from_chars(s, s + std::strlen(s), x);1057 assert(r.ec == std::errc{});1058 assert(r.ptr == s + 3);1059 assert(x == F(1.5));1060 }1061 }1062 { // exponent double sign1063 {1064 const char* s = "1.25e++12";1065 1066 r = std::from_chars(s, s + std::strlen(s), x);1067 assert(r.ec == std::errc{});1068 assert(r.ptr == s + 4);1069 assert(x == F(1.25));1070 }1071 {1072 const char* s = "1.25e+-12";1073 1074 r = std::from_chars(s, s + std::strlen(s), x);1075 assert(r.ec == std::errc{});1076 assert(r.ptr == s + 4);1077 assert(x == F(1.25));1078 }1079 {1080 const char* s = "1.25e-+12";1081 1082 r = std::from_chars(s, s + std::strlen(s), x);1083 assert(r.ec == std::errc{});1084 assert(r.ptr == s + 4);1085 assert(x == F(1.25));1086 }1087 {1088 const char* s = "1.25e--12";1089 1090 r = std::from_chars(s, s + std::strlen(s), x);1091 assert(r.ec == std::errc{});1092 assert(r.ptr == s + 4);1093 assert(x == F(1.25));1094 }1095 }1096 { // exponent hex prefix -> e01097 const char* s = "1.25e0x12";1098 1099 r = std::from_chars(s, s + std::strlen(s), x);1100 assert(r.ec == std::errc{});1101 assert(r.ptr == s + 6);1102 assert(x == F(1.25));1103 }1104 { // double exponent1105 const char* s = "1.25e0e12";1106 1107 r = std::from_chars(s, s + std::strlen(s), x);1108 assert(r.ec == std::errc{});1109 assert(r.ptr == s + 6);1110 assert(x == F(1.25));1111 }1112 { // This number is halfway between two float values.1113 const char* s = "20040229";1114 1115 r = std::from_chars(s, s + std::strlen(s), x);1116 assert(r.ec == std::errc{});1117 assert(r.ptr == s + 8);1118 assert(x == F(20040229));1119 }1120 { // Shifting mantissa exponent and no exponent1121 const char* s = "123.456";1122 1123 r = std::from_chars(s, s + std::strlen(s), x);1124 assert(r.ec == std::errc{});1125 assert(r.ptr == s + 7);1126 assert(x == F(1.23456e2));1127 }1128 { // Shifting mantissa exponent and an exponent1129 const char* s = "123.456e3";1130 1131 r = std::from_chars(s, s + std::strlen(s), x);1132 assert(r.ec == std::errc{});1133 assert(r.ptr == s + 9);1134 assert(x == F(1.23456e5));1135 }1136 { // Mantissa overflow1137 {1138 const char* s = "0.111111111111111111111111111111111111111111";1139 1140 r = std::from_chars(s, s + std::strlen(s), x);1141 assert(r.ec == std::errc{});1142 assert(r.ptr == s + std::strlen(s));1143 assert(x == F(0.111111111111111111111111111111111111111111));1144 }1145 {1146 const char* s = "111111111111.111111111111111111111111111111111111111111";1147 1148 r = std::from_chars(s, s + std::strlen(s), x);1149 assert(r.ec == std::errc{});1150 assert(r.ptr == s + std::strlen(s));1151 assert(x == F(111111111111.111111111111111111111111111111111111111111));1152 }1153 }1154 { // Negative value1155 const char* s = "-0.25";1156 1157 r = std::from_chars(s, s + std::strlen(s), x);1158 assert(r.ec == std::errc{});1159 assert(r.ptr == s + std::strlen(s));1160 assert(x == F(-0.25));1161 }1162 { // value is too big -> +inf1163 const char* s = "1e9999999999999999999999999999999999999999";1164 1165 r = std::from_chars(s, s + std::strlen(s), x);1166 assert(r.ec == std::errc::result_out_of_range);1167 assert(r.ptr == s + strlen(s));1168 assert(x == std::numeric_limits<F>::infinity());1169 }1170 { // negative value is too big -> -inf1171 const char* s = "-1e9999999999999999999999999999999999999999";1172 1173 r = std::from_chars(s, s + std::strlen(s), x);1174 assert(r.ec == std::errc::result_out_of_range);1175 assert(r.ptr == s + strlen(s));1176 assert(x == -std::numeric_limits<F>::infinity());1177 }1178 { // value is too small -> 01179 const char* s = "1e-9999999999999999999999999999999999999999";1180 1181 r = std::from_chars(s, s + std::strlen(s), x);1182 assert(r.ec == std::errc::result_out_of_range);1183 assert(r.ptr == s + strlen(s));1184 assert(x == F(0.0));1185 }1186 { // negative value is too small -> -01187 const char* s = "-1e-9999999999999999999999999999999999999999";1188 1189 r = std::from_chars(s, s + std::strlen(s), x);1190 assert(r.ec == std::errc::result_out_of_range);1191 assert(r.ptr == s + strlen(s));1192 assert(x == F(-0.0));1193 }1194 }1195};1196 1197template <class F>1198struct test_hex {1199 void operator()() {1200 std::from_chars_result r;1201 F x = 0.25;1202 1203 // *** Failures1204 1205 { // Starts with invalid character1206 std::array s = {' ', '1', 'e', '0'};1207 for (auto c : "ghijklmnopqrstuvwxyz"1208 "GHIJKLMNOPQRSTUVWXYZ"1209 "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {1210 s[0] = c;1211 r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::hex);1212 1213 assert(r.ec == std::errc::invalid_argument);1214 assert(r.ptr == s.data());1215 assert(x == F(0.25));1216 }1217 }1218 1219 // *** Success1220 1221 { // number followed by non-numeric values1222 const char* s = "001x";1223 1224 // the expected form of the subject sequence is a nonempty sequence of1225 // decimal digits optionally containing a decimal-point character, then1226 // an optional exponent part as defined in 6.4.4.3, excluding any digit1227 // separators (6.4.4.2); (C23 7.24.1.5)1228 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1229 assert(r.ec == std::errc{});1230 assert(r.ptr == s + 3);1231 assert(x == F(1.0));1232 }1233 { // no leading digit1234 const char* s = ".5p0";1235 1236 // the expected form of the subject sequence is a nonempty sequence of1237 // decimal digits optionally containing a decimal-point character, then1238 // an optional exponent part as defined in 6.4.4.3, excluding any digit1239 // separators (6.4.4.2); (C23 7.24.1.5)1240 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1241 assert(r.ec == std::errc{});1242 assert(r.ptr == s + 4);1243 assert(x == F(0x0.5p0));1244 }1245 { // negative sign and no leading digit1246 const char* s = "-.5p0";1247 1248 // the expected form of the subject sequence is a nonempty sequence of1249 // decimal digits optionally containing a decimal-point character, then1250 // an optional exponent part as defined in 6.4.4.3, excluding any digit1251 // separators (6.4.4.2); (C23 7.24.1.5)1252 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1253 assert(r.ec == std::errc{});1254 assert(r.ptr == s + 5);1255 assert(x == F(-0x0.5p0));1256 }1257 { // no leading digit1258 const char* s = ".5";1259 1260 // the expected form of the subject sequence is a nonempty sequence of1261 // decimal digits optionally containing a decimal-point character, then1262 // an optional exponent part as defined in 6.4.4.3, excluding any digit1263 // separators (6.4.4.2); (C23 7.24.1.5)1264 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1265 assert(r.ec == std::errc{});1266 assert(r.ptr == s + 2);1267 assert(x == F(0x0.5p0));1268 }1269 { // negative sign and no leading digit1270 const char* s = "-.5";1271 1272 // the expected form of the subject sequence is a nonempty sequence of1273 // decimal digits optionally containing a decimal-point character, then1274 // an optional exponent part as defined in 6.4.4.3, excluding any digit1275 // separators (6.4.4.2); (C23 7.24.1.5)1276 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1277 assert(r.ec == std::errc{});1278 assert(r.ptr == s + 3);1279 assert(x == F(-0x0.5p0));1280 }1281 { // double decimal point1282 const char* s = "1.25.78";1283 1284 // This number is halfway between two float values.1285 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1286 assert(r.ec == std::errc{});1287 assert(r.ptr == s + 4);1288 assert(x == F(0x1.25p0));1289 }1290 { // exponent no sign1291 const char* s = "1.5p10";1292 1293 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1294 assert(r.ec == std::errc{});1295 assert(r.ptr == s + 6);1296 assert(x == F(0x1.5p10));1297 }1298 { // exponent capitalized no sign1299 const char* s = "1.5P10";1300 1301 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1302 assert(r.ec == std::errc{});1303 assert(r.ptr == s + 6);1304 assert(x == F(0x1.5p10));1305 }1306 { // exponent + sign1307 const char* s = "1.5p+10";1308 1309 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1310 assert(r.ec == std::errc{});1311 assert(r.ptr == s + 7);1312 assert(x == F(0x1.5p10));1313 }1314 { // exponent - sign1315 const char* s = "1.5p-10";1316 1317 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1318 assert(r.ec == std::errc{});1319 assert(r.ptr == s + 7);1320 assert(x == F(0x1.5p-10));1321 }1322 { // Exponent no number1323 const char* s = "1.5p";1324 1325 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1326 assert(r.ec == std::errc{});1327 assert(r.ptr == s + 3);1328 assert(x == F(0x1.5p0));1329 }1330 { // Exponent sign no number1331 {1332 const char* s = "1.5p+";1333 1334 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1335 assert(r.ec == std::errc{});1336 assert(r.ptr == s + 3);1337 assert(x == F(0x1.5p0));1338 }1339 {1340 const char* s = "1.5p-";1341 1342 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1343 assert(r.ec == std::errc{});1344 assert(r.ptr == s + 3);1345 assert(x == F(0x1.5p0));1346 }1347 }1348 { // Exponent with whitespace1349 {1350 const char* s = "1.5p +1";1351 1352 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1353 assert(r.ec == std::errc{});1354 assert(r.ptr == s + 3);1355 assert(x == F(0x1.5p0));1356 }1357 {1358 const char* s = "1.5p+ 1";1359 1360 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1361 assert(r.ec == std::errc{});1362 assert(r.ptr == s + 3);1363 assert(x == F(0x1.5p0));1364 }1365 {1366 const char* s = "1.5p -1";1367 1368 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1369 assert(r.ec == std::errc{});1370 assert(r.ptr == s + 3);1371 assert(x == F(0x1.5p0));1372 }1373 {1374 const char* s = "1.5p- 1";1375 1376 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1377 assert(r.ec == std::errc{});1378 assert(r.ptr == s + 3);1379 assert(x == F(0x1.5p0));1380 }1381 }1382 { // Exponent double sign1383 {1384 const char* s = "1.25p++12";1385 1386 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1387 assert(r.ec == std::errc{});1388 assert(r.ptr == s + 4);1389 assert(x == F(0x1.25p0));1390 }1391 {1392 const char* s = "1.25p+-12";1393 1394 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1395 assert(r.ec == std::errc{});1396 assert(r.ptr == s + 4);1397 assert(x == F(0x1.25p0));1398 }1399 {1400 const char* s = "1.25p-+12";1401 1402 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1403 assert(r.ec == std::errc{});1404 assert(r.ptr == s + 4);1405 assert(x == F(0x1.25p0));1406 }1407 {1408 const char* s = "1.25p--12";1409 1410 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1411 assert(r.ec == std::errc{});1412 assert(r.ptr == s + 4);1413 assert(x == F(0x1.25p0));1414 }1415 }1416 { // exponent hex prefix -> p01417 const char* s = "1.25p0x12";1418 1419 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1420 assert(r.ec == std::errc{});1421 assert(r.ptr == s + 6);1422 assert(x == F(0x1.25p0));1423 }1424 { // double exponent1425 const char* s = "1.25p0p12";1426 1427 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1428 assert(r.ec == std::errc{});1429 assert(r.ptr == s + 6);1430 assert(x == F(0x1.25p0));1431 }1432 { // This number is halfway between two float values.1433 const char* s = "131CA25";1434 1435 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1436 assert(r.ec == std::errc{});1437 assert(r.ptr == s + 7);1438 assert(x == F(0x131CA25p0));1439 }1440 { // Shifting mantissa exponent and no exponent1441 const char* s = "123.456";1442 1443 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1444 assert(r.ec == std::errc{});1445 assert(r.ptr == s + 7);1446 assert(x == F(0x123.456p0));1447 }1448 { // Shifting mantissa exponent and an exponent1449 const char* s = "123.456p3";1450 1451 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1452 assert(r.ec == std::errc{});1453 assert(r.ptr == s + 9);1454 assert(x == F(0x123.456p3));1455 }1456 { // Mantissa overflow1457 {1458 const char* s = "0.111111111111111111111111111111111111111111";1459 1460 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1461 assert(r.ec == std::errc{});1462 assert(r.ptr == s + std::strlen(s));1463 assert(x == F(0x0.111111111111111111111111111111111111111111p0));1464 }1465 {1466 const char* s = "111111111111.111111111111111111111111111111111111111111";1467 1468 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1469 assert(r.ec == std::errc{});1470 assert(r.ptr == s + std::strlen(s));1471 assert(x == F(0x111111111111.111111111111111111111111111111111111111111p0));1472 }1473 }1474 { // Negative value1475 const char* s = "-0.25";1476 1477 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1478 assert(r.ec == std::errc{});1479 assert(r.ptr == s + std::strlen(s));1480 assert(x == F(-0x0.25p0));1481 }1482 { // value is too big -> +inf1483 const char* s = "1p9999999999999999999999999999999999999999";1484 1485 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1486 assert(r.ec == std::errc::result_out_of_range);1487 assert(r.ptr == s + strlen(s));1488 assert(x == std::numeric_limits<F>::infinity());1489 }1490 { // negative value is too big -> -inf1491 const char* s = "-1p9999999999999999999999999999999999999999";1492 1493 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1494 assert(r.ec == std::errc::result_out_of_range);1495 assert(r.ptr == s + strlen(s));1496 assert(x == -std::numeric_limits<F>::infinity());1497 }1498 { // value is too small -> 01499 const char* s = "1p-9999999999999999999999999999999999999999";1500 1501 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1502 assert(r.ec == std::errc::result_out_of_range);1503 assert(r.ptr == s + strlen(s));1504 assert(x == F(0.0));1505 }1506 { // negative value is too small -> -01507 const char* s = "-1p-9999999999999999999999999999999999999999";1508 1509 r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::hex);1510 assert(r.ec == std::errc::result_out_of_range);1511 assert(r.ptr == s + strlen(s));1512 assert(x == F(-0.0));1513 }1514 }1515};1516 1517// The test1518// test/std/utilities/charconv/charconv.msvc/test.cpp1519// uses random values. This tests contains errors found by this test.1520void test_random_errors() {1521 {1522 const char* s = "4.219902180869891e-2788";1523 const char* last = s + std::strlen(s) - 1;1524 1525 // last + 1 contains a digit. When that value is parsed the exponent is1526 // e-2788 which returns std::errc::result_out_of_range and the value 0.1527 // the proper exponent is e-278, which can be represented by a double.1528 1529 double value = 0.25;1530 std::from_chars_result result = std::from_chars(s, last, value);1531 1532 assert(result.ec == std::errc{});1533 assert(result.ptr == last);1534 assert(value == 4.219902180869891e-278);1535 }1536 {1537 const char* s = "7.411412e-39U";1538 const char* last = s + std::strlen(s) - 1;1539 1540 float value = 0.25;1541 std::from_chars_result result = std::from_chars(s, last, value);1542 1543 assert(result.ec == std::errc{});1544 assert(result.ptr == last);1545 assert(value == 7.411412e-39F);1546 }1547}1548 1549int main(int, char**) {1550 run<test_basics>(all_floats);1551 run<test_scientific>(all_floats);1552 run<test_fixed>(all_floats);1553 run<test_general>(all_floats);1554 1555 run<test_hex>(all_floats);1556 1557 test_random_errors();1558 1559 return 0;1560}1561