diff options
author | Elliott Hughes <enh@google.com> | 2017-12-20 17:37:11 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2017-12-21 17:44:22 -0800 |
commit | cb239bda6569c48efd3925bb87682fc0efa077fd (patch) | |
tree | becb3004fc64eee97b8dd3af604787b8a8eaa161 /tests/stdlib_test.cpp | |
parent | 2c5f914584704878d6d1e0225304bd48844329e3 (diff) |
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
Diffstat (limited to 'tests/stdlib_test.cpp')
-rw-r--r-- | tests/stdlib_test.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp index 93877f335..caa7a851a 100644 --- a/tests/stdlib_test.cpp +++ b/tests/stdlib_test.cpp @@ -679,22 +679,51 @@ static void CheckStrToInt(T fn(const char* s, char** end, int base)) { 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) { |