brintos

brintos / llvm-project-archived public Read only

0
0
Text · 49.1 KiB · a02c7ac Raw
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