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