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