1d2748964SZhihao Yuan //===----------------------------------------------------------------------===// 2d2748964SZhihao Yuan // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d2748964SZhihao Yuan // 7d2748964SZhihao Yuan //===----------------------------------------------------------------------===// 8d2748964SZhihao Yuan 9e17ec8e9SMark de Wever // UNSUPPORTED: c++03, c++11, c++14 100b8efae6SVolodymyr Sapsai 11d2748964SZhihao Yuan // <charconv> 12d2748964SZhihao Yuan 13a1e13a80SMark de Wever // constexpr from_chars_result from_chars(const char* first, const char* last, 14d2748964SZhihao Yuan // Integral& value, int base = 10) 15d2748964SZhihao Yuan 168b60ba73SLouis Dionne #include <charconv> 17*5e19fd17SLouis Dionne #include <system_error> 18*5e19fd17SLouis Dionne 197fc6a556SMarshall Clow #include "test_macros.h" 20d2748964SZhihao Yuan #include "charconv_test_helpers.h" 21d2748964SZhihao Yuan 22d2748964SZhihao Yuan template <typename T> 238b60ba73SLouis Dionne struct test_basics 24d2748964SZhihao Yuan { 25a1e13a80SMark de Wever TEST_CONSTEXPR_CXX23 void operator()() 26d2748964SZhihao Yuan { 27d2748964SZhihao Yuan std::from_chars_result r; 28d2748964SZhihao Yuan T x; 29d2748964SZhihao Yuan 30d2748964SZhihao Yuan { 31d2748964SZhihao Yuan char s[] = "001x"; 32d2748964SZhihao Yuan 33d2748964SZhihao Yuan // the expected form of the subject sequence is a sequence of 34d2748964SZhihao Yuan // letters and digits representing an integer with the radix 35d2748964SZhihao Yuan // specified by base (C11 7.22.1.4/3) 368b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x); 37d2748964SZhihao Yuan assert(r.ec == std::errc{}); 38d2748964SZhihao Yuan assert(r.ptr == s + 3); 39d2748964SZhihao Yuan assert(x == 1); 40d2748964SZhihao Yuan } 41d2748964SZhihao Yuan 42d2748964SZhihao Yuan { 433f786833SMark de Wever // The string has more characters than valid in an 128-bit value. 443f786833SMark de Wever char s[] = "0X7BAtSGHDkEIXZgQRfYChLpOzRnM "; 45d2748964SZhihao Yuan 46d2748964SZhihao Yuan // The letters from a (or A) through z (or Z) are ascribed the 47d2748964SZhihao Yuan // values 10 through 35; (C11 7.22.1.4/3) 488b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x, 36); 49d2748964SZhihao Yuan assert(r.ec == std::errc::result_out_of_range); 50d2748964SZhihao Yuan // The member ptr of the return value points to the first character 51d2748964SZhihao Yuan // not matching the pattern 52d2748964SZhihao Yuan assert(r.ptr == s + sizeof(s) - 2); 53d2748964SZhihao Yuan assert(x == 1); 54d2748964SZhihao Yuan 55d2748964SZhihao Yuan // no "0x" or "0X" prefix shall appear if the value of base is 16 568b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x, 16); 57d2748964SZhihao Yuan assert(r.ec == std::errc{}); 58d2748964SZhihao Yuan assert(r.ptr == s + 1); 59d2748964SZhihao Yuan assert(x == 0); 60d2748964SZhihao Yuan 61d2748964SZhihao Yuan // only letters and digits whose ascribed values are less than that 62d2748964SZhihao Yuan // of base are permitted. (C11 7.22.1.4/3) 638b60ba73SLouis Dionne r = std::from_chars(s + 2, s + sizeof(s), x, 12); 64d2748964SZhihao Yuan // If the parsed value is not in the range representable by the type 65d2748964SZhihao Yuan // of value, 66d2748964SZhihao Yuan if (!fits_in<T>(1150)) 67d2748964SZhihao Yuan { 68d2748964SZhihao Yuan // value is unmodified and 69d2748964SZhihao Yuan assert(x == 0); 70d2748964SZhihao Yuan // the member ec of the return value is equal to 71d2748964SZhihao Yuan // errc::result_out_of_range 72d2748964SZhihao Yuan assert(r.ec == std::errc::result_out_of_range); 73d2748964SZhihao Yuan } 74d2748964SZhihao Yuan else 75d2748964SZhihao Yuan { 76d2748964SZhihao Yuan // Otherwise, value is set to the parsed value, 77d2748964SZhihao Yuan assert(x == 1150); 78d2748964SZhihao Yuan // and the member ec is value-initialized. 79d2748964SZhihao Yuan assert(r.ec == std::errc{}); 80d2748964SZhihao Yuan } 81d2748964SZhihao Yuan assert(r.ptr == s + 5); 82d2748964SZhihao Yuan } 83d2748964SZhihao Yuan } 84d2748964SZhihao Yuan }; 85d2748964SZhihao Yuan 86d2748964SZhihao Yuan template <typename T> 878b60ba73SLouis Dionne struct test_signed 88d2748964SZhihao Yuan { 89a1e13a80SMark de Wever TEST_CONSTEXPR_CXX23 void operator()() 90d2748964SZhihao Yuan { 91d2748964SZhihao Yuan std::from_chars_result r; 923f786833SMark de Wever T x = 42; 93d2748964SZhihao Yuan 94d2748964SZhihao Yuan { 95d2748964SZhihao Yuan // If the pattern allows for an optional sign, 96d2748964SZhihao Yuan // but the string has no digit characters following the sign, 97d2748964SZhihao Yuan char s[] = "- 9+12"; 988b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x); 993f786833SMark de Wever // value is unmodified, 1003f786833SMark de Wever assert(x == 42); 101d2748964SZhihao Yuan // no characters match the pattern. 102d2748964SZhihao Yuan assert(r.ptr == s); 103d2748964SZhihao Yuan assert(r.ec == std::errc::invalid_argument); 104d2748964SZhihao Yuan } 105d2748964SZhihao Yuan 106d2748964SZhihao Yuan { 107d2748964SZhihao Yuan char s[] = "9+12"; 1088b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x); 109d2748964SZhihao Yuan assert(r.ec == std::errc{}); 110d2748964SZhihao Yuan // The member ptr of the return value points to the first character 111d2748964SZhihao Yuan // not matching the pattern, 112d2748964SZhihao Yuan assert(r.ptr == s + 1); 113d2748964SZhihao Yuan assert(x == 9); 114d2748964SZhihao Yuan } 115d2748964SZhihao Yuan 116d2748964SZhihao Yuan { 117d2748964SZhihao Yuan char s[] = "12"; 1188b60ba73SLouis Dionne r = std::from_chars(s, s + 2, x); 119d2748964SZhihao Yuan assert(r.ec == std::errc{}); 120d2748964SZhihao Yuan // or has the value last if all characters match. 121d2748964SZhihao Yuan assert(r.ptr == s + 2); 122d2748964SZhihao Yuan assert(x == 12); 123d2748964SZhihao Yuan } 124d2748964SZhihao Yuan 125d2748964SZhihao Yuan { 126d2748964SZhihao Yuan // '-' is the only sign that may appear 127d2748964SZhihao Yuan char s[] = "+30"; 128d2748964SZhihao Yuan // If no characters match the pattern, 1298b60ba73SLouis Dionne r = std::from_chars(s, s + sizeof(s), x); 130d2748964SZhihao Yuan // value is unmodified, 131d2748964SZhihao Yuan assert(x == 12); 132d2748964SZhihao Yuan // the member ptr of the return value is first and 133d2748964SZhihao Yuan assert(r.ptr == s); 134d2748964SZhihao Yuan // the member ec is equal to errc::invalid_argument. 135d2748964SZhihao Yuan assert(r.ec == std::errc::invalid_argument); 136d2748964SZhihao Yuan } 137d2748964SZhihao Yuan } 138d2748964SZhihao Yuan }; 139d2748964SZhihao Yuan 140a1e13a80SMark de Wever TEST_CONSTEXPR_CXX23 bool test() 141d2748964SZhihao Yuan { 142d2748964SZhihao Yuan run<test_basics>(integrals); 143d2748964SZhihao Yuan run<test_signed>(all_signed); 1442df59c50SJF Bastien 145a1e13a80SMark de Wever return true; 146a1e13a80SMark de Wever } 147a1e13a80SMark de Wever 148a1e13a80SMark de Wever int main(int, char**) { 149a1e13a80SMark de Wever test(); 150a1e13a80SMark de Wever #if TEST_STD_VER > 20 151a1e13a80SMark de Wever static_assert(test()); 152a1e13a80SMark de Wever #endif 153a1e13a80SMark de Wever 1542df59c50SJF Bastien return 0; 155d2748964SZhihao Yuan } 156