Simplify atoi*/strto* for signed integers.
Make the cost of strto<signed> closer to the cost of strto<unsigned>
by removing an `if` from the inner loop. Previously a signed conversion
cost 10ns more than an unsigned one.
After:
BM_inttypes_strtoimax 81 ns 81 ns 8603362
BM_inttypes_strtoumax 78 ns 78 ns 8967174
BM_stdlib_strtol 81 ns 81 ns 8685537
BM_stdlib_strtoll 81 ns 81 ns 8685481
BM_stdlib_strtoul 78 ns 78 ns 8962569
BM_stdlib_strtoull 78 ns 78 ns 8972023
Bug: N/A
Test: ran tests, benchmarks
Change-Id: I72dd5499427b6a940bd94c4d6f727f7efe134d7e
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 93877f3..caa7a85 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -679,22 +679,51 @@
if (std::numeric_limits<T>::is_signed) {
// Minimum (such as -128).
std::string min{std::to_string(std::numeric_limits<T>::min())};
+ end_p = nullptr;
+ errno = 0;
ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
+ ASSERT_EQ(0, errno);
+ ASSERT_EQ('\0', *end_p);
// Too negative (such as -129).
min.back() = (min.back() + 1);
+ end_p = nullptr;
errno = 0;
ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
ASSERT_EQ(ERANGE, errno);
+ ASSERT_EQ('\0', *end_p);
}
// Maximum (such as 127).
std::string max{std::to_string(std::numeric_limits<T>::max())};
+ end_p = nullptr;
+ errno = 0;
ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
+ ASSERT_EQ(0, errno);
+ ASSERT_EQ('\0', *end_p);
// Too positive (such as 128).
max.back() = (max.back() + 1);
+ end_p = nullptr;
errno = 0;
ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
ASSERT_EQ(ERANGE, errno);
+ ASSERT_EQ('\0', *end_p);
+
+ // In case of overflow, strto* leaves us pointing past the end of the number,
+ // not at the digit that overflowed.
+ end_p = nullptr;
+ errno = 0;
+ ASSERT_EQ(std::numeric_limits<T>::max(),
+ fn("99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
+ ASSERT_EQ(ERANGE, errno);
+ ASSERT_STREQ("abc", end_p);
+ if (std::numeric_limits<T>::is_signed) {
+ end_p = nullptr;
+ errno = 0;
+ ASSERT_EQ(std::numeric_limits<T>::min(),
+ fn("-99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
+ ASSERT_EQ(ERANGE, errno);
+ ASSERT_STREQ("abc", end_p);
+ }
}
TEST(stdlib, strtol_smoke) {