summaryrefslogtreecommitdiff
path: root/absl/strings/numbers_test.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-10-19 15:25:26 -0700
committerGravatar Gennadiy Rozental <rogeeff@google.com>2020-10-19 19:24:23 -0400
commit4b915e70929ca2d6152240facc83d3d38c5d5f28 (patch)
tree3663ad6f3ddb8f0a94045bac592901ee7298447e /absl/strings/numbers_test.cc
parent8f1c34a77a2ba04512b7f9cbc6013d405e6a0b31 (diff)
Export of internal Abseil changes
-- 77c85460dc3c46593b231c5161ac55273bb0c7ef by Abseil Team <absl-team@google.com>: Support int128 in SimpleAtoi. PiperOrigin-RevId: 337946262 -- 0be53049ccf8309650e4e22f23b290e5f75ee828 by Gennadiy Rozental <rogeeff@google.com>: Update build scripts to use --mount instead of --volume to mount the host data into a container. This is somewhat more verbose, but more readable and flexible. More importantly this is what docker documentation is recomending to use now. PiperOrigin-RevId: 337898761 -- 3bc877f1679fdf61ecbf4365287a0403cfc9b53e by Samuel Benzaquen <sbenza@google.com>: Add Cord constructor for constinit instances. PiperOrigin-RevId: 337871148 -- 8b87701892b9c325e78ad4e8e4f16b785a744622 by Chris Kennelly <ckennelly@google.com>: Use the address of kSeed, rather than its value. We initialize kSeed with &kSeed, so these are equivalent, but kSeed requires a load from memory while &kSeed can be formed as a RIP-relative lea. PiperOrigin-RevId: 337868415 GitOrigin-RevId: 77c85460dc3c46593b231c5161ac55273bb0c7ef Change-Id: I3d06c18a123f1be29dad5801e8625952dc41cd95
Diffstat (limited to 'absl/strings/numbers_test.cc')
-rw-r--r--absl/strings/numbers_test.cc76
1 files changed, 74 insertions, 2 deletions
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index c2f03b63..4ab67fb6 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -251,7 +251,7 @@ TEST(Numbers, TestFastPrints) {
template <typename int_type, typename in_val_type>
void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) {
std::string s;
- // uint128 can be streamed but not StrCat'd
+ // (u)int128 can be streamed but not StrCat'd.
absl::strings_internal::OStringStream(&s) << in_value;
int_type x = static_cast<int_type>(~exp_value);
EXPECT_TRUE(SimpleAtoi(s, &x))
@@ -264,7 +264,9 @@ void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) {
template <typename int_type, typename in_val_type>
void VerifySimpleAtoiBad(in_val_type in_value) {
- std::string s = absl::StrCat(in_value);
+ std::string s;
+ // (u)int128 can be streamed but not StrCat'd.
+ absl::strings_internal::OStringStream(&s) << in_value;
int_type x;
EXPECT_FALSE(SimpleAtoi(s, &x));
EXPECT_FALSE(SimpleAtoi(s.c_str(), &x));
@@ -347,6 +349,31 @@ TEST(NumbersTest, Atoi) {
std::numeric_limits<absl::uint128>::max(),
std::numeric_limits<absl::uint128>::max());
+ // SimpleAtoi(absl::string_view, absl::int128)
+ VerifySimpleAtoiGood<absl::int128>(0, 0);
+ VerifySimpleAtoiGood<absl::int128>(42, 42);
+ VerifySimpleAtoiGood<absl::int128>(-42, -42);
+
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int32_t>::min(),
+ std::numeric_limits<int32_t>::min());
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int32_t>::max(),
+ std::numeric_limits<int32_t>::max());
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<uint32_t>::max(),
+ std::numeric_limits<uint32_t>::max());
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int64_t>::min(),
+ std::numeric_limits<int64_t>::min());
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int64_t>::max(),
+ std::numeric_limits<int64_t>::max());
+ VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<uint64_t>::max(),
+ std::numeric_limits<uint64_t>::max());
+ VerifySimpleAtoiGood<absl::int128>(
+ std::numeric_limits<absl::int128>::min(),
+ std::numeric_limits<absl::int128>::min());
+ VerifySimpleAtoiGood<absl::int128>(
+ std::numeric_limits<absl::int128>::max(),
+ std::numeric_limits<absl::int128>::max());
+ VerifySimpleAtoiBad<absl::int128>(std::numeric_limits<absl::uint128>::max());
+
// Some other types
VerifySimpleAtoiGood<int>(-42, -42);
VerifySimpleAtoiGood<int32_t>(-42, -42);
@@ -725,6 +752,51 @@ TEST(stringtest, safe_strtou128_random) {
EXPECT_FALSE(parse_func(s, &parsed_value, base));
}
}
+TEST(stringtest, safe_strto128_random) {
+ // random number generators don't work for int128, and
+ // int128 can be streamed but not StrCat'd, so this code must be custom
+ // implemented for int128, but is generally the same as what's above.
+ // test_random_integer_parse_base<absl::int128>(
+ // &absl::numbers_internal::safe_strto128_base);
+ using RandomEngine = std::minstd_rand0;
+ using IntType = absl::int128;
+ constexpr auto parse_func = &absl::numbers_internal::safe_strto128_base;
+
+ std::random_device rd;
+ RandomEngine rng(rd());
+ std::uniform_int_distribution<int64_t> random_int64(
+ std::numeric_limits<int64_t>::min());
+ std::uniform_int_distribution<uint64_t> random_uint64(
+ std::numeric_limits<uint64_t>::min());
+ std::uniform_int_distribution<int> random_base(2, 35);
+
+ for (size_t i = 0; i < kNumRandomTests; ++i) {
+ int64_t high = random_int64(rng);
+ uint64_t low = random_uint64(rng);
+ IntType value = absl::MakeInt128(high, low);
+
+ int base = random_base(rng);
+ std::string str_value;
+ EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
+ IntType parsed_value;
+
+ // Test successful parse
+ EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
+ EXPECT_EQ(parsed_value, value);
+
+ // Test overflow
+ std::string s;
+ absl::strings_internal::OStringStream(&s)
+ << std::numeric_limits<IntType>::max() << value;
+ EXPECT_FALSE(parse_func(s, &parsed_value, base));
+
+ // Test underflow
+ s.clear();
+ absl::strings_internal::OStringStream(&s)
+ << std::numeric_limits<IntType>::min() << value;
+ EXPECT_FALSE(parse_func(s, &parsed_value, base));
+ }
+}
TEST(stringtest, safe_strtou32_base) {
for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {