xref: /llvm-project/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp (revision 5e19fd172063c8957a35c7fa3596620f79ebba97)
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