//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11 // // from_chars_result from_chars(const char* first, const char* last, // Integral& value, int base = 10) #include "charconv_test_helpers.h" template struct test_basics : roundtrip_test_base { using roundtrip_test_base::test; void operator()() { test(0); test(42); test(32768); test(0, 10); test(42, 10); test(32768, 10); test(0xf, 16); test(0xdeadbeaf, 16); test(0755, 8); for (int b = 2; b < 37; ++b) { using xl = std::numeric_limits; test(1, b); test(-1, b); test(xl::lowest(), b); test((xl::max)(), b); test((xl::max)() / 2, b); } using std::from_chars; std::from_chars_result r; T x; { char s[] = "001x"; // the expected form of the subject sequence is a sequence of // letters and digits representing an integer with the radix // specified by base (C11 7.22.1.4/3) r = from_chars(s, s + sizeof(s), x); assert(r.ec == std::errc{}); assert(r.ptr == s + 3); assert(x == 1); } { char s[] = "0X7BAtSGHDkEIXZg "; // The letters from a (or A) through z (or Z) are ascribed the // values 10 through 35; (C11 7.22.1.4/3) r = from_chars(s, s + sizeof(s), x, 36); assert(r.ec == std::errc::result_out_of_range); // The member ptr of the return value points to the first character // not matching the pattern assert(r.ptr == s + sizeof(s) - 2); assert(x == 1); // no "0x" or "0X" prefix shall appear if the value of base is 16 r = from_chars(s, s + sizeof(s), x, 16); assert(r.ec == std::errc{}); assert(r.ptr == s + 1); assert(x == 0); // only letters and digits whose ascribed values are less than that // of base are permitted. (C11 7.22.1.4/3) r = from_chars(s + 2, s + sizeof(s), x, 12); // If the parsed value is not in the range representable by the type // of value, if (!fits_in(1150)) { // value is unmodified and assert(x == 0); // the member ec of the return value is equal to // errc::result_out_of_range assert(r.ec == std::errc::result_out_of_range); } else { // Otherwise, value is set to the parsed value, assert(x == 1150); // and the member ec is value-initialized. assert(r.ec == std::errc{}); } assert(r.ptr == s + 5); } } }; template struct test_signed : roundtrip_test_base { using roundtrip_test_base::test; void operator()() { test(-1); test(-12); test(-1, 10); test(-12, 10); test(-21734634, 10); test(-2647, 2); test(-0xcc1, 16); for (int b = 2; b < 37; ++b) { using xl = std::numeric_limits; test(0, b); test(xl::lowest(), b); test((xl::max)(), b); } using std::from_chars; std::from_chars_result r; T x; { // If the pattern allows for an optional sign, // but the string has no digit characters following the sign, char s[] = "- 9+12"; r = from_chars(s, s + sizeof(s), x); // no characters match the pattern. assert(r.ptr == s); assert(r.ec == std::errc::invalid_argument); } { char s[] = "9+12"; r = from_chars(s, s + sizeof(s), x); assert(r.ec == std::errc{}); // The member ptr of the return value points to the first character // not matching the pattern, assert(r.ptr == s + 1); assert(x == 9); } { char s[] = "12"; r = from_chars(s, s + 2, x); assert(r.ec == std::errc{}); // or has the value last if all characters match. assert(r.ptr == s + 2); assert(x == 12); } { // '-' is the only sign that may appear char s[] = "+30"; // If no characters match the pattern, r = from_chars(s, s + sizeof(s), x); // value is unmodified, assert(x == 12); // the member ptr of the return value is first and assert(r.ptr == s); // the member ec is equal to errc::invalid_argument. assert(r.ec == std::errc::invalid_argument); } } }; int main() { run(integrals); run(all_signed); }