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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14 10 11 // <charconv> 12 13 // constexpr from_chars_result from_chars(const char* first, const char* last, 14 // Integral& value, int base = 10) 15 16 #include <charconv> 17 #include <system_error> 18 19 #include "test_macros.h" 20 #include "charconv_test_helpers.h" 21 22 template <typename T> 23 struct test_basics 24 { 25 TEST_CONSTEXPR_CXX23 void operator()() 26 { 27 std::from_chars_result r; 28 T x; 29 30 { 31 char s[] = "001x"; 32 33 // the expected form of the subject sequence is a sequence of 34 // letters and digits representing an integer with the radix 35 // specified by base (C11 7.22.1.4/3) 36 r = std::from_chars(s, s + sizeof(s), x); 37 assert(r.ec == std::errc{}); 38 assert(r.ptr == s + 3); 39 assert(x == 1); 40 } 41 42 { 43 // The string has more characters than valid in an 128-bit value. 44 char s[] = "0X7BAtSGHDkEIXZgQRfYChLpOzRnM "; 45 46 // The letters from a (or A) through z (or Z) are ascribed the 47 // values 10 through 35; (C11 7.22.1.4/3) 48 r = std::from_chars(s, s + sizeof(s), x, 36); 49 assert(r.ec == std::errc::result_out_of_range); 50 // The member ptr of the return value points to the first character 51 // not matching the pattern 52 assert(r.ptr == s + sizeof(s) - 2); 53 assert(x == 1); 54 55 // no "0x" or "0X" prefix shall appear if the value of base is 16 56 r = std::from_chars(s, s + sizeof(s), x, 16); 57 assert(r.ec == std::errc{}); 58 assert(r.ptr == s + 1); 59 assert(x == 0); 60 61 // only letters and digits whose ascribed values are less than that 62 // of base are permitted. (C11 7.22.1.4/3) 63 r = std::from_chars(s + 2, s + sizeof(s), x, 12); 64 // If the parsed value is not in the range representable by the type 65 // of value, 66 if (!fits_in<T>(1150)) 67 { 68 // value is unmodified and 69 assert(x == 0); 70 // the member ec of the return value is equal to 71 // errc::result_out_of_range 72 assert(r.ec == std::errc::result_out_of_range); 73 } 74 else 75 { 76 // Otherwise, value is set to the parsed value, 77 assert(x == 1150); 78 // and the member ec is value-initialized. 79 assert(r.ec == std::errc{}); 80 } 81 assert(r.ptr == s + 5); 82 } 83 } 84 }; 85 86 template <typename T> 87 struct test_signed 88 { 89 TEST_CONSTEXPR_CXX23 void operator()() 90 { 91 std::from_chars_result r; 92 T x = 42; 93 94 { 95 // If the pattern allows for an optional sign, 96 // but the string has no digit characters following the sign, 97 char s[] = "- 9+12"; 98 r = std::from_chars(s, s + sizeof(s), x); 99 // value is unmodified, 100 assert(x == 42); 101 // no characters match the pattern. 102 assert(r.ptr == s); 103 assert(r.ec == std::errc::invalid_argument); 104 } 105 106 { 107 char s[] = "9+12"; 108 r = std::from_chars(s, s + sizeof(s), x); 109 assert(r.ec == std::errc{}); 110 // The member ptr of the return value points to the first character 111 // not matching the pattern, 112 assert(r.ptr == s + 1); 113 assert(x == 9); 114 } 115 116 { 117 char s[] = "12"; 118 r = std::from_chars(s, s + 2, x); 119 assert(r.ec == std::errc{}); 120 // or has the value last if all characters match. 121 assert(r.ptr == s + 2); 122 assert(x == 12); 123 } 124 125 { 126 // '-' is the only sign that may appear 127 char s[] = "+30"; 128 // If no characters match the pattern, 129 r = std::from_chars(s, s + sizeof(s), x); 130 // value is unmodified, 131 assert(x == 12); 132 // the member ptr of the return value is first and 133 assert(r.ptr == s); 134 // the member ec is equal to errc::invalid_argument. 135 assert(r.ec == std::errc::invalid_argument); 136 } 137 } 138 }; 139 140 TEST_CONSTEXPR_CXX23 bool test() 141 { 142 run<test_basics>(integrals); 143 run<test_signed>(all_signed); 144 145 return true; 146 } 147 148 int main(int, char**) { 149 test(); 150 #if TEST_STD_VER > 20 151 static_assert(test()); 152 #endif 153 154 return 0; 155 } 156