[libc++] Refactor the <charconv> tests - #227611
Open
philnik777 wants to merge 1 commit into
Open
philnik777 wants to merge 1 commit into
philnik777 wants to merge 1 commit into
Conversation
|
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesPatch is 119.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/227611.diff 7 Files Affected:
diff --git a/libcxx/test/std/utilities/charconv/charconv.from.chars/floating_point.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.from.chars/floating_point.pass.cpp
index a02c7ac466f04..fa223785d758d 100644
--- a/libcxx/test/std/utilities/charconv/charconv.from.chars/floating_point.pass.cpp
+++ b/libcxx/test/std/utilities/charconv/charconv.from.chars/floating_point.pass.cpp
@@ -17,6 +17,7 @@
// double& value, chars_format fmt = chars_format::general)
#include <array>
+#include <cassert>
#include <charconv>
#include <cmath>
#include <cstring>
@@ -24,8 +25,8 @@
#include <stdexcept>
#include <system_error>
-#include "charconv_test_helpers.h"
#include "test_macros.h"
+#include "type_algorithms.h"
template <class F>
void test_infinity(std::chars_format fmt) {
@@ -326,1193 +327,1183 @@ void test_fmt_independent(std::chars_format fmt) {
}
template <class F>
-struct test_basics {
- void operator()() {
- for (auto fmt : {std::chars_format::scientific,
- std::chars_format::fixed,
- /*std::chars_format::hex,*/ std::chars_format::general})
- test_fmt_independent<F>(fmt);
- }
-};
+void test_basics() {
+ for (auto fmt : {std::chars_format::scientific,
+ std::chars_format::fixed,
+ /*std::chars_format::hex,*/ std::chars_format::general})
+ test_fmt_independent<F>(fmt);
+}
template <class F>
-struct test_fixed {
- void operator()() {
- std::from_chars_result r;
- F x = 0.25;
+void test_fixed() {
+ std::from_chars_result r;
+ F x = 0.25;
- // *** Failures
+ // *** Failures
- { // Starts with invalid character
- std::array s = {' ', '1'};
- for (auto c : "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {
- s[0] = c;
- r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::fixed);
+ { // Starts with invalid character
+ std::array s = {' ', '1'};
+ for (auto c : "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {
+ s[0] = c;
+ r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::fixed);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s.data());
- assert(x == F(0.25));
- }
+ assert(r.ec == std::errc::invalid_argument);
+ assert(r.ptr == s.data());
+ assert(x == F(0.25));
}
+ }
- // *** Success
+ // *** Success
- { // number followed by non-numeric values
- const char* s = "001x";
+ { // number followed by non-numeric values
+ const char* s = "001x";
- // the expected form of the subject sequence is a nonempty sequence of
- // decimal digits optionally containing a decimal-point character, then
- // an optional exponent part as defined in 6.4.4.3, excluding any digit
- // separators (6.4.4.2); (C23 7.24.1.5)
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.0));
- }
- { // no leading digit
- const char* s = ".5";
+ // the expected form of the subject sequence is a nonempty sequence of
+ // decimal digits optionally containing a decimal-point character, then
+ // an optional exponent part as defined in 6.4.4.3, excluding any digit
+ // separators (6.4.4.2); (C23 7.24.1.5)
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.0));
+ }
+ { // no leading digit
+ const char* s = ".5";
+
+ // the expected form of the subject sequence is a nonempty sequence of
+ // decimal digits optionally containing a decimal-point character, then
+ // an optional exponent part as defined in 6.4.4.3, excluding any digit
+ // separators (6.4.4.2); (C23 7.24.1.5)
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 2);
+ assert(x == F(0.5));
+ }
+ { // negative sign and no leading digit
+ const char* s = "-.5";
+
+ // the expected form of the subject sequence is a nonempty sequence of
+ // decimal digits optionally containing a decimal-point character, then
+ // an optional exponent part as defined in 6.4.4.3, excluding any digit
+ // separators (6.4.4.2); (C23 7.24.1.5)
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(-0.5));
+ }
- // the expected form of the subject sequence is a nonempty sequence of
- // decimal digits optionally containing a decimal-point character, then
- // an optional exponent part as defined in 6.4.4.3, excluding any digit
- // separators (6.4.4.2); (C23 7.24.1.5)
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 2);
- assert(x == F(0.5));
- }
- { // negative sign and no leading digit
- const char* s = "-.5";
+ { // double decimal point
+ const char* s = "1.25.78";
- // the expected form of the subject sequence is a nonempty sequence of
- // decimal digits optionally containing a decimal-point character, then
- // an optional exponent part as defined in 6.4.4.3, excluding any digit
- // separators (6.4.4.2); (C23 7.24.1.5)
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(-0.5));
- }
+ // This number is halfway between two float values.
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 4);
+ assert(x == F(1.25));
+ }
+ { // exponent no sign
+ const char* s = "1.5e10";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
+ }
+ { // exponent capitalized no sign
+ const char* s = "1.5E10";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
+ }
+ { // exponent + sign
+ const char* s = "1.5e+10";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
+ }
+ { // exponent - sign
+ const char* s = "1.5e-10";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
+ }
+ { // Exponent no number
+ const char* s = "1.5e";
- { // double decimal point
- const char* s = "1.25.78";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
+ }
+ { // Exponent sign no number
+ {
+ const char* s = "1.5e+";
- // This number is halfway between two float values.
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
- assert(r.ptr == s + 4);
- assert(x == F(1.25));
+ assert(r.ptr == s + 3);
+ assert(x == F(1.5));
}
- { // exponent no sign
- const char* s = "1.5e10";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ {
+ const char* s = "1.5e-";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 3);
assert(x == F(1.5));
}
- { // exponent capitalized no sign
- const char* s = "1.5E10";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ }
+ { // Exponent with whitespace
+ {
+ const char* s = "1.5e +1";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 3);
assert(x == F(1.5));
}
- { // exponent + sign
- const char* s = "1.5e+10";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ {
+ const char* s = "1.5e+ 1";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 3);
assert(x == F(1.5));
}
- { // exponent - sign
- const char* s = "1.5e-10";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ {
+ const char* s = "1.5e -1";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 3);
assert(x == F(1.5));
}
- { // Exponent no number
- const char* s = "1.5e";
+ {
+ const char* s = "1.5e- 1";
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 3);
assert(x == F(1.5));
}
- { // Exponent sign no number
- {
- const char* s = "1.5e+";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- {
- const char* s = "1.5e-";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- }
- { // Exponent with whitespace
- {
- const char* s = "1.5e +1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- {
- const char* s = "1.5e+ 1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- {
- const char* s = "1.5e -1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- {
- const char* s = "1.5e- 1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == F(1.5));
- }
- }
- { // double exponent
- const char* s = "1.25e0e12";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ }
+ { // double exponent
+ const char* s = "1.25e0e12";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 4);
+ assert(x == F(1.25));
+ }
+ { // Exponent double sign
+ {
+ const char* s = "1.25e++12";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 4);
assert(x == F(1.25));
}
- { // Exponent double sign
- {
- const char* s = "1.25e++12";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 4);
- assert(x == F(1.25));
- }
- {
- const char* s = "1.25e+-12";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 4);
- assert(x == F(1.25));
- }
- {
- const char* s = "1.25e-+12";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 4);
- assert(x == F(1.25));
- }
- {
- const char* s = "1.25e--12";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 4);
- assert(x == F(1.25));
- }
- }
- { // exponent hex prefix
- const char* s = "1.25e0x12";
+ {
+ const char* s = "1.25e+-12";
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + 4);
assert(x == F(1.25));
}
- { // This number is halfway between two float values.
- const char* s = "20040229";
+ {
+ const char* s = "1.25e-+12";
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
- assert(r.ptr == s + 8);
- assert(x == F(20040229));
+ assert(r.ptr == s + 4);
+ assert(x == F(1.25));
}
- { // Shifting mantissa exponent and no exponent
- const char* s = "123.456";
+ {
+ const char* s = "1.25e--12";
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
- assert(r.ptr == s + 7);
- assert(x == F(1.23456e2));
+ assert(r.ptr == s + 4);
+ assert(x == F(1.25));
}
- { // Shifting mantissa exponent and an exponent
- const char* s = "123.456e3";
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ }
+ { // exponent hex prefix
+ const char* s = "1.25e0x12";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 4);
+ assert(x == F(1.25));
+ }
+ { // This number is halfway between two float values.
+ const char* s = "20040229";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 8);
+ assert(x == F(20040229));
+ }
+ { // Shifting mantissa exponent and no exponent
+ const char* s = "123.456";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 7);
+ assert(x == F(1.23456e2));
+ }
+ { // Shifting mantissa exponent and an exponent
+ const char* s = "123.456e3";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 7);
+ assert(x == F(123.456));
+ }
+ { // Mantissa overflow
+ {
+ const char* s = "0.111111111111111111111111111111111111111111";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
- assert(r.ptr == s + 7);
- assert(x == F(123.456));
- }
- { // Mantissa overflow
- {
- const char* s = "0.111111111111111111111111111111111111111111";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + std::strlen(s));
- assert(x == F(0.111111111111111111111111111111111111111111));
- }
- {
- const char* s = "111111111111.111111111111111111111111111111111111111111";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + std::strlen(s));
- assert(x == F(111111111111.111111111111111111111111111111111111111111));
- }
- }
- { // Negative value
- const char* s = "-0.25";
+ assert(r.ptr == s + std::strlen(s));
+ assert(x == F(0.111111111111111111111111111111111111111111));
+ }
+ {
+ const char* s = "111111111111.111111111111111111111111111111111111111111";
r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
assert(r.ec == std::errc{});
assert(r.ptr == s + std::strlen(s));
- assert(x == F(-0.25));
+ assert(x == F(111111111111.111111111111111111111111111111111111111111));
}
}
-};
+ { // Negative value
+ const char* s = "-0.25";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::fixed);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + std::strlen(s));
+ assert(x == F(-0.25));
+ }
+}
template <class F>
-struct test_scientific {
- void operator()() {
- std::from_chars_result r;
- F x = 0.25;
+void test_scientific() {
+ std::from_chars_result r;
+ F x = 0.25;
- // *** Failures
+ // *** Failures
- { // Starts with invalid character
- std::array s = {' ', '1', 'e', '0'};
- for (auto c : "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {
- s[0] = c;
- r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::scientific);
+ { // Starts with invalid character
+ std::array s = {' ', '1', 'e', '0'};
+ for (auto c : "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "`~!@#$%^&*()_=[]{}\\|;:'\",/<>? \t\v\r\n") {
+ s[0] = c;
+ r = std::from_chars(s.data(), s.data() + s.size(), x, std::chars_format::scientific);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s.data());
- assert(x == F(0.25));
- }
+ assert(r.ec == std::errc::invalid_argument);
+ assert(r.ptr == s.data());
+ assert(x == F(0.25));
}
- { // No exponent
- const char* s = "1.23";
- r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);
+ }
+ { // No exponent
+ const char* s = "1.23";
+ r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);
+ assert(r.ec == std::errc::invalid_argument);
+ assert(r.ptr == s);
+ assert(x == F(0.25));
+ }
+ { // Exponent no number
+ const char* s = "1.23e";
+ r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);
+
+ assert(r.ec == std::errc::invalid_argument);
+ assert(r.ptr == s);
+ assert(x == F(0.25));
+ }
+ { // Exponent sign no number
+ {
+ const char* s = "1.5e+";
+
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
assert(r.ec == std::errc::invalid_argument);
assert(r.ptr == s);
assert(x == F(0.25));
}
- { // Exponent no number
- const char* s = "1.23e";
- r = std::from_chars(s, s + strlen(s), x, std::chars_format::scientific);
+ {
+ const char* s = "1.5e-";
+ r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
assert(r.ec == std::errc::invalid_argument);
assert(r.ptr == s);
assert(x == F(0.25));
}
- { // Exponent sign no number
- {
- const char* s = "1.5e+";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s);
- assert(x == F(0.25));
- }
- {
- const char* s = "1.5e-";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s);
- assert(x == F(0.25));
- }
- }
- { // Exponent with whitespace
- {
- const char* s = "1.5e +1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s);
- assert(x == F(0.25));
- }
- {
- const char* s = "1.5e+ 1";
-
- r = std::from_chars(s, s + std::strlen(s), x, std::chars_format::scientific);
- assert(r.ec == std::errc::invalid_argument);
- assert(r.ptr == s);
- assert(x == F(0.25));
- ...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp,h -- libcxx/test/std/utilities/charconv/charconv.from.chars/floating_point.pass.cpp libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp libcxx/test/support/charconv_test_helpers.h --diff_from_common_commit
View the diff from clang-format here.diff --git a/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
index 1e0aaebb1..0a32dd079 100644
--- a/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -37,120 +37,115 @@ static_assert(!has_from_chars<char*, char*, bool&, int>);
struct test_basics
{
- template <typename T>
- TEST_CONSTEXPR_CXX23 void operator()()
+ template <typename T>
+ TEST_CONSTEXPR_CXX23 void operator()() {
+ 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 = std::from_chars(s, s + sizeof(s), x);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == 1);
+ }
+
{
- 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 = std::from_chars(s, s + sizeof(s), x);
- assert(r.ec == std::errc{});
- assert(r.ptr == s + 3);
- assert(x == 1);
- }
-
- {
- // The string has more characters than valid in an 128-bit value.
- char s[] = "0X7BAtSGHDkEIXZgQRfYChLpOzRnM ";
-
- // The letters from a (or A) through z (or Z) are ascribed the
- // values 10 through 35; (C11 7.22.1.4/3)
- r = std::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 = std::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 = std::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<T>(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);
- }
+ // The string has more characters than valid in an 128-bit value.
+ char s[] = "0X7BAtSGHDkEIXZgQRfYChLpOzRnM ";
+
+ // The letters from a (or A) through z (or Z) are ascribed the
+ // values 10 through 35; (C11 7.22.1.4/3)
+ r = std::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 = std::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 = std::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<T>(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);
}
+ }
};
struct test_signed
{
- template <typename T>
- TEST_CONSTEXPR_CXX23 void operator()()
+ template <typename T>
+ TEST_CONSTEXPR_CXX23 void operator()() {
+ std::from_chars_result r;
+ T x = 42;
+
+ {
+ // If the pattern allows for an optional sign,
+ // but the string has no digit characters following the sign,
+ char s[] = "- 9+12";
+ r = std::from_chars(s, s + sizeof(s), x);
+ // value is unmodified,
+ assert(x == 42);
+ // no characters match the pattern.
+ assert(r.ptr == s);
+ assert(r.ec == std::errc::invalid_argument);
+ }
+
+ {
+ char s[] = "9+12";
+ r = std::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 = std::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);
+ }
+
{
- std::from_chars_result r;
- T x = 42;
-
- {
- // If the pattern allows for an optional sign,
- // but the string has no digit characters following the sign,
- char s[] = "- 9+12";
- r = std::from_chars(s, s + sizeof(s), x);
- // value is unmodified,
- assert(x == 42);
- // no characters match the pattern.
- assert(r.ptr == s);
- assert(r.ec == std::errc::invalid_argument);
- }
-
- {
- char s[] = "9+12";
- r = std::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 = std::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 = std::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);
- }
+ // '-' is the only sign that may appear
+ char s[] = "+30";
+ // If no characters match the pattern,
+ r = std::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);
}
+ }
};
TEST_CONSTEXPR_CXX23 bool test()
diff --git a/libcxx/test/support/charconv_test_helpers.h b/libcxx/test/support/charconv_test_helpers.h
index 51c579e79..91313e66f 100644
--- a/libcxx/test/support/charconv_test_helpers.h
+++ b/libcxx/test/support/charconv_test_helpers.h
@@ -20,45 +20,33 @@
#endif
template <typename To, typename From>
-constexpr auto
-is_non_narrowing(From a) -> decltype(To{a}, std::true_type())
-{
- return {};
+constexpr auto is_non_narrowing(From a) -> decltype(To{a}, std::true_type()) {
+ return {};
}
template <typename To>
-constexpr auto
-is_non_narrowing(...) -> std::false_type
-{
- return {};
+constexpr auto is_non_narrowing(...) -> std::false_type {
+ return {};
}
template <typename X, typename T>
-constexpr bool
-_fits_in(T, std::true_type /* non-narrowing*/, ...)
-{
- return true;
+constexpr bool _fits_in(T, std::true_type /* non-narrowing*/, ...) {
+ return true;
}
template <typename X, typename T, typename xl = std::numeric_limits<X>>
-constexpr bool
-_fits_in(T v, std::false_type, std::true_type /* T signed*/, std::true_type /* X signed */)
-{
- return xl::lowest() <= v && v <= (xl::max)();
+constexpr bool _fits_in(T v, std::false_type, std::true_type /* T signed*/, std::true_type /* X signed */) {
+ return xl::lowest() <= v && v <= (xl::max)();
}
template <typename X, typename T, typename xl = std::numeric_limits<X>>
-constexpr bool
-_fits_in(T v, std::false_type, std::true_type /* T signed */, std::false_type /* X unsigned*/)
-{
- return 0 <= v && typename std::make_unsigned<T>::type(v) <= (xl::max)();
+constexpr bool _fits_in(T v, std::false_type, std::true_type /* T signed */, std::false_type /* X unsigned*/) {
+ return 0 <= v && typename std::make_unsigned<T>::type(v) <= (xl::max)();
}
template <typename X, typename T, typename xl = std::numeric_limits<X>>
-constexpr bool
-_fits_in(T v, std::false_type, std::false_type /* T unsigned */, ...)
-{
- return v <= typename std::make_unsigned<X>::type((xl::max)());
+constexpr bool _fits_in(T v, std::false_type, std::false_type /* T unsigned */, ...) {
+ return v <= typename std::make_unsigned<X>::type((xl::max)());
}
template <typename X, typename T>
|
philnik777
force-pushed
the
refactor_charconv_tests
branch
from
September 30, 2026 12:31
f1139ec to
bccfd44
Compare
Member
|
I think we should rebase this on top of #225801 once it lands. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This does a few things:
charconv_test_helpers.hthat is only used in a single test is moved into the test.verify.cpptests are instead SFINAE testedUsing the type algorithms is an important fix here, since the custom implementation resulted in only ever constant evaluating some functions.