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