Home | History | Annotate | Download | only in charconv.from.chars
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03, c++11
     11 
     12 // XFAIL: with_system_cxx_lib=macosx10.14
     13 // XFAIL: with_system_cxx_lib=macosx10.13
     14 // XFAIL: with_system_cxx_lib=macosx10.12
     15 // XFAIL: with_system_cxx_lib=macosx10.11
     16 // XFAIL: with_system_cxx_lib=macosx10.10
     17 // XFAIL: with_system_cxx_lib=macosx10.9
     18 // XFAIL: with_system_cxx_lib=macosx10.8
     19 // XFAIL: with_system_cxx_lib=macosx10.7
     20 
     21 // <charconv>
     22 
     23 // from_chars_result from_chars(const char* first, const char* last,
     24 //                              Integral& value, int base = 10)
     25 
     26 #include "charconv_test_helpers.h"
     27 
     28 template <typename T>
     29 struct test_basics : roundtrip_test_base<T>
     30 {
     31     using roundtrip_test_base<T>::test;
     32 
     33     void operator()()
     34     {
     35         test(0);
     36         test(42);
     37         test(32768);
     38         test(0, 10);
     39         test(42, 10);
     40         test(32768, 10);
     41         test(0xf, 16);
     42         test(0xdeadbeaf, 16);
     43         test(0755, 8);
     44 
     45         for (int b = 2; b < 37; ++b)
     46         {
     47             using xl = std::numeric_limits<T>;
     48 
     49             test(1, b);
     50             test(-1, b);
     51             test(xl::lowest(), b);
     52             test((xl::max)(), b);
     53             test((xl::max)() / 2, b);
     54         }
     55 
     56         using std::from_chars;
     57         std::from_chars_result r;
     58         T x;
     59 
     60         {
     61             char s[] = "001x";
     62 
     63             // the expected form of the subject sequence is a sequence of
     64             // letters and digits representing an integer with the radix
     65             // specified by base (C11 7.22.1.4/3)
     66             r = from_chars(s, s + sizeof(s), x);
     67             assert(r.ec == std::errc{});
     68             assert(r.ptr == s + 3);
     69             assert(x == 1);
     70         }
     71 
     72         {
     73             char s[] = "0X7BAtSGHDkEIXZg ";
     74 
     75             // The letters from a (or A) through z (or Z) are ascribed the
     76             // values 10 through 35; (C11 7.22.1.4/3)
     77             r = from_chars(s, s + sizeof(s), x, 36);
     78             assert(r.ec == std::errc::result_out_of_range);
     79             // The member ptr of the return value points to the first character
     80             // not matching the pattern
     81             assert(r.ptr == s + sizeof(s) - 2);
     82             assert(x == 1);
     83 
     84             // no "0x" or "0X" prefix shall appear if the value of base is 16
     85             r = from_chars(s, s + sizeof(s), x, 16);
     86             assert(r.ec == std::errc{});
     87             assert(r.ptr == s + 1);
     88             assert(x == 0);
     89 
     90             // only letters and digits whose ascribed values are less than that
     91             // of base are permitted. (C11 7.22.1.4/3)
     92             r = from_chars(s + 2, s + sizeof(s), x, 12);
     93             // If the parsed value is not in the range representable by the type
     94             // of value,
     95             if (!fits_in<T>(1150))
     96             {
     97                 // value is unmodified and
     98                 assert(x == 0);
     99                 // the member ec of the return value is equal to
    100                 // errc::result_out_of_range
    101                 assert(r.ec == std::errc::result_out_of_range);
    102             }
    103             else
    104             {
    105                 // Otherwise, value is set to the parsed value,
    106                 assert(x == 1150);
    107                 // and the member ec is value-initialized.
    108                 assert(r.ec == std::errc{});
    109             }
    110             assert(r.ptr == s + 5);
    111         }
    112     }
    113 };
    114 
    115 template <typename T>
    116 struct test_signed : roundtrip_test_base<T>
    117 {
    118     using roundtrip_test_base<T>::test;
    119 
    120     void operator()()
    121     {
    122         test(-1);
    123         test(-12);
    124         test(-1, 10);
    125         test(-12, 10);
    126         test(-21734634, 10);
    127         test(-2647, 2);
    128         test(-0xcc1, 16);
    129 
    130         for (int b = 2; b < 37; ++b)
    131         {
    132             using xl = std::numeric_limits<T>;
    133 
    134             test(0, b);
    135             test(xl::lowest(), b);
    136             test((xl::max)(), b);
    137         }
    138 
    139         using std::from_chars;
    140         std::from_chars_result r;
    141         T x;
    142 
    143         {
    144             // If the pattern allows for an optional sign,
    145             // but the string has no digit characters following the sign,
    146             char s[] = "- 9+12";
    147             r = from_chars(s, s + sizeof(s), x);
    148             // no characters match the pattern.
    149             assert(r.ptr == s);
    150             assert(r.ec == std::errc::invalid_argument);
    151         }
    152 
    153         {
    154             char s[] = "9+12";
    155             r = from_chars(s, s + sizeof(s), x);
    156             assert(r.ec == std::errc{});
    157             // The member ptr of the return value points to the first character
    158             // not matching the pattern,
    159             assert(r.ptr == s + 1);
    160             assert(x == 9);
    161         }
    162 
    163         {
    164             char s[] = "12";
    165             r = from_chars(s, s + 2, x);
    166             assert(r.ec == std::errc{});
    167             // or has the value last if all characters match.
    168             assert(r.ptr == s + 2);
    169             assert(x == 12);
    170         }
    171 
    172         {
    173             // '-' is the only sign that may appear
    174             char s[] = "+30";
    175             // If no characters match the pattern,
    176             r = from_chars(s, s + sizeof(s), x);
    177             // value is unmodified,
    178             assert(x == 12);
    179             // the member ptr of the return value is first and
    180             assert(r.ptr == s);
    181             // the member ec is equal to errc::invalid_argument.
    182             assert(r.ec == std::errc::invalid_argument);
    183         }
    184     }
    185 };
    186 
    187 int main()
    188 {
    189     run<test_basics>(integrals);
    190     run<test_signed>(all_signed);
    191 }
    192