00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "absl/strings/numbers.h"
00018
00019 #include <sys/types.h>
00020 #include <cfenv>
00021 #include <cinttypes>
00022 #include <climits>
00023 #include <cmath>
00024 #include <cstddef>
00025 #include <cstdint>
00026 #include <cstdio>
00027 #include <cstdlib>
00028 #include <cstring>
00029 #include <limits>
00030 #include <numeric>
00031 #include <random>
00032 #include <set>
00033 #include <string>
00034 #include <vector>
00035
00036 #include "gmock/gmock.h"
00037 #include "gtest/gtest.h"
00038 #include "absl/base/internal/raw_logging.h"
00039 #include "absl/strings/str_cat.h"
00040
00041 #include "absl/strings/internal/numbers_test_common.h"
00042 #include "absl/strings/internal/pow10_helper.h"
00043
00044 namespace {
00045
00046 using absl::numbers_internal::kSixDigitsToBufferSize;
00047 using absl::numbers_internal::safe_strto32_base;
00048 using absl::numbers_internal::safe_strto64_base;
00049 using absl::numbers_internal::safe_strtou32_base;
00050 using absl::numbers_internal::safe_strtou64_base;
00051 using absl::numbers_internal::SixDigitsToBuffer;
00052 using absl::strings_internal::Itoa;
00053 using absl::strings_internal::strtouint32_test_cases;
00054 using absl::strings_internal::strtouint64_test_cases;
00055 using absl::SimpleAtoi;
00056 using testing::Eq;
00057 using testing::MatchesRegex;
00058
00059
00060
00061
00062
00063
00064 const int kFloatNumCases = 5000000;
00065
00066
00067
00068
00069 std::string PerfectDtoa(double d) {
00070 if (d == 0) return "0";
00071 if (d < 0) return "-" + PerfectDtoa(-d);
00072
00073
00074
00075 int64_t mantissa, exp = 0;
00076 while (d >= 1ULL << 63) ++exp, d *= 0.5;
00077 while ((mantissa = d) != d) --exp, d *= 2.0;
00078
00079
00080
00081
00082 constexpr int maxlen = 1100;
00083 char buf[maxlen + 5];
00084 for (int64_t num = mantissa, pos = maxlen; --pos >= 0;) {
00085 buf[pos] = '0' + (num % 10);
00086 num /= 10;
00087 }
00088 char* begin = &buf[0];
00089 char* end = buf + maxlen;
00090 for (int i = 0; i != exp; i += (exp > 0) ? 1 : -1) {
00091 int carry = 0;
00092 for (char* p = end; --p != begin;) {
00093 int dig = *p - '0';
00094 dig = dig * (exp > 0 ? 2 : 5) + carry;
00095 carry = dig / 10;
00096 dig %= 10;
00097 *p = '0' + dig;
00098 }
00099 }
00100 if (exp < 0) {
00101
00102 memmove(end + 1 + exp, end + exp, 1 - exp);
00103 end[exp] = '.';
00104 ++end;
00105 }
00106 while (*begin == '0' && begin[1] != '.') ++begin;
00107 return {begin, end};
00108 }
00109
00110 TEST(ToString, PerfectDtoa) {
00111 EXPECT_THAT(PerfectDtoa(1), Eq("1"));
00112 EXPECT_THAT(PerfectDtoa(0.1),
00113 Eq("0.1000000000000000055511151231257827021181583404541015625"));
00114 EXPECT_THAT(PerfectDtoa(1e24), Eq("999999999999999983222784"));
00115 EXPECT_THAT(PerfectDtoa(5e-324), MatchesRegex("0.0000.*625"));
00116 for (int i = 0; i < 100; ++i) {
00117 for (double multiplier :
00118 {1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) {
00119 double d = multiplier * i;
00120 std::string s = PerfectDtoa(d);
00121 EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr));
00122 }
00123 }
00124 }
00125
00126 template <typename integer>
00127 struct MyInteger {
00128 integer i;
00129 explicit constexpr MyInteger(integer i) : i(i) {}
00130 constexpr operator integer() const { return i; }
00131
00132 constexpr MyInteger operator+(MyInteger other) const { return i + other.i; }
00133 constexpr MyInteger operator-(MyInteger other) const { return i - other.i; }
00134 constexpr MyInteger operator*(MyInteger other) const { return i * other.i; }
00135 constexpr MyInteger operator/(MyInteger other) const { return i / other.i; }
00136
00137 constexpr bool operator<(MyInteger other) const { return i < other.i; }
00138 constexpr bool operator<=(MyInteger other) const { return i <= other.i; }
00139 constexpr bool operator==(MyInteger other) const { return i == other.i; }
00140 constexpr bool operator>=(MyInteger other) const { return i >= other.i; }
00141 constexpr bool operator>(MyInteger other) const { return i > other.i; }
00142 constexpr bool operator!=(MyInteger other) const { return i != other.i; }
00143
00144 integer as_integer() const { return i; }
00145 };
00146
00147 typedef MyInteger<int64_t> MyInt64;
00148 typedef MyInteger<uint64_t> MyUInt64;
00149
00150 void CheckInt32(int32_t x) {
00151 char buffer[absl::numbers_internal::kFastToBufferSize];
00152 char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
00153 std::string expected = std::to_string(x);
00154 EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
00155
00156 char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
00157 EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
00158 }
00159
00160 void CheckInt64(int64_t x) {
00161 char buffer[absl::numbers_internal::kFastToBufferSize + 3];
00162 buffer[0] = '*';
00163 buffer[23] = '*';
00164 buffer[24] = '*';
00165 char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
00166 std::string expected = std::to_string(x);
00167 EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
00168 EXPECT_EQ(buffer[0], '*');
00169 EXPECT_EQ(buffer[23], '*');
00170 EXPECT_EQ(buffer[24], '*');
00171
00172 char* my_actual =
00173 absl::numbers_internal::FastIntToBuffer(MyInt64(x), &buffer[1]);
00174 EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
00175 }
00176
00177 void CheckUInt32(uint32_t x) {
00178 char buffer[absl::numbers_internal::kFastToBufferSize];
00179 char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
00180 std::string expected = std::to_string(x);
00181 EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
00182
00183 char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
00184 EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
00185 }
00186
00187 void CheckUInt64(uint64_t x) {
00188 char buffer[absl::numbers_internal::kFastToBufferSize + 1];
00189 char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
00190 std::string expected = std::to_string(x);
00191 EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
00192
00193 char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
00194 EXPECT_EQ(expected, std::string(&buffer[1], generic_actual))
00195 << " Input " << x;
00196
00197 char* my_actual =
00198 absl::numbers_internal::FastIntToBuffer(MyUInt64(x), &buffer[1]);
00199 EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
00200 }
00201
00202 void CheckHex64(uint64_t v) {
00203 char expected[16 + 1];
00204 std::string actual = absl::StrCat(absl::Hex(v, absl::kZeroPad16));
00205 snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast<uint64_t>(v));
00206 EXPECT_EQ(expected, actual) << " Input " << v;
00207 }
00208
00209 TEST(Numbers, TestFastPrints) {
00210 for (int i = -100; i <= 100; i++) {
00211 CheckInt32(i);
00212 CheckInt64(i);
00213 }
00214 for (int i = 0; i <= 100; i++) {
00215 CheckUInt32(i);
00216 CheckUInt64(i);
00217 }
00218
00219 CheckInt32(INT_MIN);
00220 CheckInt32(INT_MAX);
00221 CheckInt64(LONG_MIN);
00222 CheckInt64(uint64_t{1000000000});
00223 CheckInt64(uint64_t{9999999999});
00224 CheckInt64(uint64_t{100000000000000});
00225 CheckInt64(uint64_t{999999999999999});
00226 CheckInt64(uint64_t{1000000000000000000});
00227 CheckInt64(uint64_t{1199999999999999999});
00228 CheckInt64(int64_t{-700000000000000000});
00229 CheckInt64(LONG_MAX);
00230 CheckUInt32(std::numeric_limits<uint32_t>::max());
00231 CheckUInt64(uint64_t{1000000000});
00232 CheckUInt64(uint64_t{9999999999});
00233 CheckUInt64(uint64_t{100000000000000});
00234 CheckUInt64(uint64_t{999999999999999});
00235 CheckUInt64(uint64_t{1000000000000000000});
00236 CheckUInt64(uint64_t{1199999999999999999});
00237 CheckUInt64(std::numeric_limits<uint64_t>::max());
00238
00239 for (int i = 0; i < 10000; i++) {
00240 CheckHex64(i);
00241 }
00242 CheckHex64(uint64_t{0x123456789abcdef0});
00243 }
00244
00245 template <typename int_type, typename in_val_type>
00246 void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) {
00247 std::string s = absl::StrCat(in_value);
00248 int_type x = static_cast<int_type>(~exp_value);
00249 EXPECT_TRUE(SimpleAtoi(s, &x))
00250 << "in_value=" << in_value << " s=" << s << " x=" << x;
00251 EXPECT_EQ(exp_value, x);
00252 x = static_cast<int_type>(~exp_value);
00253 EXPECT_TRUE(SimpleAtoi(s.c_str(), &x));
00254 EXPECT_EQ(exp_value, x);
00255 }
00256
00257 template <typename int_type, typename in_val_type>
00258 void VerifySimpleAtoiBad(in_val_type in_value) {
00259 std::string s = absl::StrCat(in_value);
00260 int_type x;
00261 EXPECT_FALSE(SimpleAtoi(s, &x));
00262 EXPECT_FALSE(SimpleAtoi(s.c_str(), &x));
00263 }
00264
00265 TEST(NumbersTest, Atoi) {
00266
00267 VerifySimpleAtoiGood<int32_t>(0, 0);
00268 VerifySimpleAtoiGood<int32_t>(42, 42);
00269 VerifySimpleAtoiGood<int32_t>(-42, -42);
00270
00271 VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::min(),
00272 std::numeric_limits<int32_t>::min());
00273 VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::max(),
00274 std::numeric_limits<int32_t>::max());
00275
00276
00277 VerifySimpleAtoiGood<uint32_t>(0, 0);
00278 VerifySimpleAtoiGood<uint32_t>(42, 42);
00279 VerifySimpleAtoiBad<uint32_t>(-42);
00280
00281 VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int32_t>::min());
00282 VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<int32_t>::max(),
00283 std::numeric_limits<int32_t>::max());
00284 VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<uint32_t>::max(),
00285 std::numeric_limits<uint32_t>::max());
00286 VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::min());
00287 VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::max());
00288 VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<uint64_t>::max());
00289
00290
00291 VerifySimpleAtoiGood<int64_t>(0, 0);
00292 VerifySimpleAtoiGood<int64_t>(42, 42);
00293 VerifySimpleAtoiGood<int64_t>(-42, -42);
00294
00295 VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::min(),
00296 std::numeric_limits<int32_t>::min());
00297 VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::max(),
00298 std::numeric_limits<int32_t>::max());
00299 VerifySimpleAtoiGood<int64_t>(std::numeric_limits<uint32_t>::max(),
00300 std::numeric_limits<uint32_t>::max());
00301 VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::min(),
00302 std::numeric_limits<int64_t>::min());
00303 VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::max(),
00304 std::numeric_limits<int64_t>::max());
00305 VerifySimpleAtoiBad<int64_t>(std::numeric_limits<uint64_t>::max());
00306
00307
00308 VerifySimpleAtoiGood<uint64_t>(0, 0);
00309 VerifySimpleAtoiGood<uint64_t>(42, 42);
00310 VerifySimpleAtoiBad<uint64_t>(-42);
00311
00312 VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int32_t>::min());
00313 VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int32_t>::max(),
00314 std::numeric_limits<int32_t>::max());
00315 VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint32_t>::max(),
00316 std::numeric_limits<uint32_t>::max());
00317 VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int64_t>::min());
00318 VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int64_t>::max(),
00319 std::numeric_limits<int64_t>::max());
00320 VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint64_t>::max(),
00321 std::numeric_limits<uint64_t>::max());
00322
00323
00324 VerifySimpleAtoiGood<int>(-42, -42);
00325 VerifySimpleAtoiGood<int32_t>(-42, -42);
00326 VerifySimpleAtoiGood<uint32_t>(42, 42);
00327 VerifySimpleAtoiGood<unsigned int>(42, 42);
00328 VerifySimpleAtoiGood<int64_t>(-42, -42);
00329 VerifySimpleAtoiGood<long>(-42, -42);
00330 VerifySimpleAtoiGood<uint64_t>(42, 42);
00331 VerifySimpleAtoiGood<size_t>(42, 42);
00332 VerifySimpleAtoiGood<std::string::size_type>(42, 42);
00333 }
00334
00335 TEST(NumbersTest, Atoenum) {
00336 enum E01 {
00337 E01_zero = 0,
00338 E01_one = 1,
00339 };
00340
00341 VerifySimpleAtoiGood<E01>(E01_zero, E01_zero);
00342 VerifySimpleAtoiGood<E01>(E01_one, E01_one);
00343
00344 enum E_101 {
00345 E_101_minusone = -1,
00346 E_101_zero = 0,
00347 E_101_one = 1,
00348 };
00349
00350 VerifySimpleAtoiGood<E_101>(E_101_minusone, E_101_minusone);
00351 VerifySimpleAtoiGood<E_101>(E_101_zero, E_101_zero);
00352 VerifySimpleAtoiGood<E_101>(E_101_one, E_101_one);
00353
00354 enum E_bigint {
00355 E_bigint_zero = 0,
00356 E_bigint_one = 1,
00357 E_bigint_max31 = static_cast<int32_t>(0x7FFFFFFF),
00358 };
00359
00360 VerifySimpleAtoiGood<E_bigint>(E_bigint_zero, E_bigint_zero);
00361 VerifySimpleAtoiGood<E_bigint>(E_bigint_one, E_bigint_one);
00362 VerifySimpleAtoiGood<E_bigint>(E_bigint_max31, E_bigint_max31);
00363
00364 enum E_fullint {
00365 E_fullint_zero = 0,
00366 E_fullint_one = 1,
00367 E_fullint_max31 = static_cast<int32_t>(0x7FFFFFFF),
00368 E_fullint_min32 = INT32_MIN,
00369 };
00370
00371 VerifySimpleAtoiGood<E_fullint>(E_fullint_zero, E_fullint_zero);
00372 VerifySimpleAtoiGood<E_fullint>(E_fullint_one, E_fullint_one);
00373 VerifySimpleAtoiGood<E_fullint>(E_fullint_max31, E_fullint_max31);
00374 VerifySimpleAtoiGood<E_fullint>(E_fullint_min32, E_fullint_min32);
00375
00376 enum E_biguint {
00377 E_biguint_zero = 0,
00378 E_biguint_one = 1,
00379 E_biguint_max31 = static_cast<uint32_t>(0x7FFFFFFF),
00380 E_biguint_max32 = static_cast<uint32_t>(0xFFFFFFFF),
00381 };
00382
00383 VerifySimpleAtoiGood<E_biguint>(E_biguint_zero, E_biguint_zero);
00384 VerifySimpleAtoiGood<E_biguint>(E_biguint_one, E_biguint_one);
00385 VerifySimpleAtoiGood<E_biguint>(E_biguint_max31, E_biguint_max31);
00386 VerifySimpleAtoiGood<E_biguint>(E_biguint_max32, E_biguint_max32);
00387 }
00388
00389 TEST(stringtest, safe_strto32_base) {
00390 int32_t value;
00391 EXPECT_TRUE(safe_strto32_base("0x34234324", &value, 16));
00392 EXPECT_EQ(0x34234324, value);
00393
00394 EXPECT_TRUE(safe_strto32_base("0X34234324", &value, 16));
00395 EXPECT_EQ(0x34234324, value);
00396
00397 EXPECT_TRUE(safe_strto32_base("34234324", &value, 16));
00398 EXPECT_EQ(0x34234324, value);
00399
00400 EXPECT_TRUE(safe_strto32_base("0", &value, 16));
00401 EXPECT_EQ(0, value);
00402
00403 EXPECT_TRUE(safe_strto32_base(" \t\n -0x34234324", &value, 16));
00404 EXPECT_EQ(-0x34234324, value);
00405
00406 EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 16));
00407 EXPECT_EQ(-0x34234324, value);
00408
00409 EXPECT_TRUE(safe_strto32_base("7654321", &value, 8));
00410 EXPECT_EQ(07654321, value);
00411
00412 EXPECT_TRUE(safe_strto32_base("-01234", &value, 8));
00413 EXPECT_EQ(-01234, value);
00414
00415 EXPECT_FALSE(safe_strto32_base("1834", &value, 8));
00416
00417
00418 EXPECT_TRUE(safe_strto32_base("0", &value, 0));
00419 EXPECT_EQ(0, value);
00420
00421 EXPECT_TRUE(safe_strto32_base("077", &value, 0));
00422 EXPECT_EQ(077, value);
00423
00424
00425 EXPECT_FALSE(safe_strto32_base("088", &value, 0));
00426
00427
00428 EXPECT_FALSE(safe_strto32_base("0xG", &value, 0));
00429
00430
00431 EXPECT_TRUE(safe_strto32_base("34234324", &value, 10));
00432 EXPECT_EQ(34234324, value);
00433
00434 EXPECT_TRUE(safe_strto32_base("0", &value, 10));
00435 EXPECT_EQ(0, value);
00436
00437 EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 10));
00438 EXPECT_EQ(-34234324, value);
00439
00440 EXPECT_TRUE(safe_strto32_base("34234324 \n\t ", &value, 10));
00441 EXPECT_EQ(34234324, value);
00442
00443
00444 EXPECT_FALSE(safe_strto32_base("", &value, 10));
00445 EXPECT_FALSE(safe_strto32_base(" ", &value, 10));
00446 EXPECT_FALSE(safe_strto32_base("abc", &value, 10));
00447 EXPECT_FALSE(safe_strto32_base("34234324a", &value, 10));
00448 EXPECT_FALSE(safe_strto32_base("34234.3", &value, 10));
00449
00450
00451 EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
00452 EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
00453
00454
00455 EXPECT_TRUE(safe_strto32_base(std::string("0x1234"), &value, 16));
00456 EXPECT_EQ(0x1234, value);
00457
00458
00459 EXPECT_TRUE(safe_strto32_base("1234", &value, 10));
00460 EXPECT_EQ(1234, value);
00461 }
00462
00463 TEST(stringtest, safe_strto32_range) {
00464
00465 int32_t value;
00466 EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
00467 EXPECT_EQ(std::numeric_limits<int32_t>::max(), value);
00468
00469 EXPECT_TRUE(safe_strto32_base("-2147483648", &value, 10));
00470 EXPECT_EQ(std::numeric_limits<int32_t>::min(), value);
00471
00472 EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
00473 EXPECT_EQ(std::numeric_limits<int32_t>::min(), value);
00474 }
00475
00476 TEST(stringtest, safe_strto64_range) {
00477
00478 int64_t value;
00479 EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
00480 EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
00481
00482 EXPECT_TRUE(safe_strto64_base("-9223372036854775808", &value, 10));
00483 EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
00484
00485 EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
00486 EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
00487 }
00488
00489 TEST(stringtest, safe_strto32_leading_substring) {
00490
00491
00492
00493
00494 int32_t value;
00495 EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 10));
00496 EXPECT_EQ(4069, value);
00497
00498 EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 8));
00499 EXPECT_EQ(0406, value);
00500
00501 EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 10));
00502 EXPECT_EQ(4069, value);
00503
00504 EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 16));
00505 EXPECT_EQ(0x4069ba, value);
00506
00507 EXPECT_FALSE(safe_strto32_base("@@@", &value, 10));
00508 EXPECT_EQ(0, value);
00509 }
00510
00511 TEST(stringtest, safe_strto64_leading_substring) {
00512
00513
00514
00515
00516 int64_t value;
00517 EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 10));
00518 EXPECT_EQ(4069, value);
00519
00520 EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 8));
00521 EXPECT_EQ(0406, value);
00522
00523 EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 10));
00524 EXPECT_EQ(4069, value);
00525
00526 EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 16));
00527 EXPECT_EQ(0x4069ba, value);
00528
00529 EXPECT_FALSE(safe_strto64_base("@@@", &value, 10));
00530 EXPECT_EQ(0, value);
00531 }
00532
00533 TEST(stringtest, safe_strto64_base) {
00534 int64_t value;
00535 EXPECT_TRUE(safe_strto64_base("0x3423432448783446", &value, 16));
00536 EXPECT_EQ(int64_t{0x3423432448783446}, value);
00537
00538 EXPECT_TRUE(safe_strto64_base("3423432448783446", &value, 16));
00539 EXPECT_EQ(int64_t{0x3423432448783446}, value);
00540
00541 EXPECT_TRUE(safe_strto64_base("0", &value, 16));
00542 EXPECT_EQ(0, value);
00543
00544 EXPECT_TRUE(safe_strto64_base(" \t\n -0x3423432448783446", &value, 16));
00545 EXPECT_EQ(int64_t{-0x3423432448783446}, value);
00546
00547 EXPECT_TRUE(safe_strto64_base(" \t\n -3423432448783446", &value, 16));
00548 EXPECT_EQ(int64_t{-0x3423432448783446}, value);
00549
00550 EXPECT_TRUE(safe_strto64_base("123456701234567012", &value, 8));
00551 EXPECT_EQ(int64_t{0123456701234567012}, value);
00552
00553 EXPECT_TRUE(safe_strto64_base("-017777777777777", &value, 8));
00554 EXPECT_EQ(int64_t{-017777777777777}, value);
00555
00556 EXPECT_FALSE(safe_strto64_base("19777777777777", &value, 8));
00557
00558
00559 EXPECT_TRUE(safe_strto64_base("0", &value, 0));
00560 EXPECT_EQ(0, value);
00561
00562 EXPECT_TRUE(safe_strto64_base("077", &value, 0));
00563 EXPECT_EQ(077, value);
00564
00565
00566 EXPECT_FALSE(safe_strto64_base("088", &value, 0));
00567
00568
00569 EXPECT_FALSE(safe_strto64_base("0xG", &value, 0));
00570
00571
00572 EXPECT_TRUE(safe_strto64_base("34234324487834466", &value, 10));
00573 EXPECT_EQ(int64_t{34234324487834466}, value);
00574
00575 EXPECT_TRUE(safe_strto64_base("0", &value, 10));
00576 EXPECT_EQ(0, value);
00577
00578 EXPECT_TRUE(safe_strto64_base(" \t\n -34234324487834466", &value, 10));
00579 EXPECT_EQ(int64_t{-34234324487834466}, value);
00580
00581 EXPECT_TRUE(safe_strto64_base("34234324487834466 \n\t ", &value, 10));
00582 EXPECT_EQ(int64_t{34234324487834466}, value);
00583
00584
00585 EXPECT_FALSE(safe_strto64_base("", &value, 10));
00586 EXPECT_FALSE(safe_strto64_base(" ", &value, 10));
00587 EXPECT_FALSE(safe_strto64_base("abc", &value, 10));
00588 EXPECT_FALSE(safe_strto64_base("34234324487834466a", &value, 10));
00589 EXPECT_FALSE(safe_strto64_base("34234487834466.3", &value, 10));
00590
00591
00592 EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
00593 EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
00594
00595
00596 EXPECT_TRUE(safe_strto64_base(std::string("0x1234"), &value, 16));
00597 EXPECT_EQ(0x1234, value);
00598
00599
00600 EXPECT_TRUE(safe_strto64_base("1234", &value, 10));
00601 EXPECT_EQ(1234, value);
00602 }
00603
00604 const size_t kNumRandomTests = 10000;
00605
00606 template <typename IntType>
00607 void test_random_integer_parse_base(bool (*parse_func)(absl::string_view,
00608 IntType* value,
00609 int base)) {
00610 using RandomEngine = std::minstd_rand0;
00611 std::random_device rd;
00612 RandomEngine rng(rd());
00613 std::uniform_int_distribution<IntType> random_int(
00614 std::numeric_limits<IntType>::min());
00615 std::uniform_int_distribution<int> random_base(2, 35);
00616 for (size_t i = 0; i < kNumRandomTests; i++) {
00617 IntType value = random_int(rng);
00618 int base = random_base(rng);
00619 std::string str_value;
00620 EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
00621 IntType parsed_value;
00622
00623
00624 EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
00625 EXPECT_EQ(parsed_value, value);
00626
00627
00628 EXPECT_FALSE(
00629 parse_func(absl::StrCat(std::numeric_limits<IntType>::max(), value),
00630 &parsed_value, base));
00631
00632
00633 if (std::numeric_limits<IntType>::min() < 0) {
00634 EXPECT_FALSE(
00635 parse_func(absl::StrCat(std::numeric_limits<IntType>::min(), value),
00636 &parsed_value, base));
00637 } else {
00638 EXPECT_FALSE(parse_func(absl::StrCat("-", value), &parsed_value, base));
00639 }
00640 }
00641 }
00642
00643 TEST(stringtest, safe_strto32_random) {
00644 test_random_integer_parse_base<int32_t>(&safe_strto32_base);
00645 }
00646 TEST(stringtest, safe_strto64_random) {
00647 test_random_integer_parse_base<int64_t>(&safe_strto64_base);
00648 }
00649 TEST(stringtest, safe_strtou32_random) {
00650 test_random_integer_parse_base<uint32_t>(&safe_strtou32_base);
00651 }
00652 TEST(stringtest, safe_strtou64_random) {
00653 test_random_integer_parse_base<uint64_t>(&safe_strtou64_base);
00654 }
00655
00656 TEST(stringtest, safe_strtou32_base) {
00657 for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
00658 const auto& e = strtouint32_test_cases()[i];
00659 uint32_t value;
00660 EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
00661 << "str=\"" << e.str << "\" base=" << e.base;
00662 if (e.expect_ok) {
00663 EXPECT_EQ(e.expected, value) << "i=" << i << " str=\"" << e.str
00664 << "\" base=" << e.base;
00665 }
00666 }
00667 }
00668
00669 TEST(stringtest, safe_strtou32_base_length_delimited) {
00670 for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
00671 const auto& e = strtouint32_test_cases()[i];
00672 std::string tmp(e.str);
00673 tmp.append("12");
00674
00675 uint32_t value;
00676 EXPECT_EQ(e.expect_ok,
00677 safe_strtou32_base(absl::string_view(tmp.data(), strlen(e.str)),
00678 &value, e.base))
00679 << "str=\"" << e.str << "\" base=" << e.base;
00680 if (e.expect_ok) {
00681 EXPECT_EQ(e.expected, value) << "i=" << i << " str=" << e.str
00682 << " base=" << e.base;
00683 }
00684 }
00685 }
00686
00687 TEST(stringtest, safe_strtou64_base) {
00688 for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
00689 const auto& e = strtouint64_test_cases()[i];
00690 uint64_t value;
00691 EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
00692 << "str=\"" << e.str << "\" base=" << e.base;
00693 if (e.expect_ok) {
00694 EXPECT_EQ(e.expected, value) << "str=" << e.str << " base=" << e.base;
00695 }
00696 }
00697 }
00698
00699 TEST(stringtest, safe_strtou64_base_length_delimited) {
00700 for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
00701 const auto& e = strtouint64_test_cases()[i];
00702 std::string tmp(e.str);
00703 tmp.append("12");
00704
00705 uint64_t value;
00706 EXPECT_EQ(e.expect_ok,
00707 safe_strtou64_base(absl::string_view(tmp.data(), strlen(e.str)),
00708 &value, e.base))
00709 << "str=\"" << e.str << "\" base=" << e.base;
00710 if (e.expect_ok) {
00711 EXPECT_EQ(e.expected, value) << "str=\"" << e.str << "\" base=" << e.base;
00712 }
00713 }
00714 }
00715
00716
00717
00718 #if defined(_MSC_VER) || defined(__APPLE__) || defined(__EMSCRIPTEN__)
00719 #define ABSL_MISSING_FEENABLEEXCEPT 1
00720 #define ABSL_MISSING_FEDISABLEEXCEPT 1
00721 #endif
00722
00723 class SimpleDtoaTest : public testing::Test {
00724 protected:
00725 void SetUp() override {
00726
00727 feholdexcept(&fp_env_);
00728 #ifndef ABSL_MISSING_FEENABLEEXCEPT
00729
00730 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
00731 #endif
00732 }
00733
00734 void TearDown() override {
00735
00736
00737
00738 #ifndef ABSL_MISSING_FEDISABLEEXCEPT
00739 fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
00740 #endif
00741 fesetenv(&fp_env_);
00742 }
00743
00744 std::string ToNineDigits(double value) {
00745 char buffer[16];
00746 snprintf(buffer, sizeof(buffer), "%.9g", value);
00747 return buffer;
00748 }
00749
00750 fenv_t fp_env_;
00751 };
00752
00753
00754
00755
00756
00757
00758
00759 template <typename R>
00760 void ExhaustiveFloat(uint32_t cases, R&& runnable) {
00761 runnable(0.0f);
00762 runnable(-0.0f);
00763 if (cases >= 2e9) {
00764 for (float f = 0; f < std::numeric_limits<float>::max(); ) {
00765 f = nextafterf(f, std::numeric_limits<float>::max());
00766 runnable(-f);
00767 runnable(f);
00768 }
00769 return;
00770 }
00771 std::set<float> floats = {3.4028234e38f};
00772 for (float f : {1.0, 3.14159265, 2.718281828, 1 / 2.718281828}) {
00773 for (float testf = f; testf != 0; testf *= 0.1f) floats.insert(testf);
00774 for (float testf = f; testf != 0; testf *= 0.5f) floats.insert(testf);
00775 for (float testf = f; testf < 3e38f / 2; testf *= 2.0f)
00776 floats.insert(testf);
00777 for (float testf = f; testf < 3e38f / 10; testf *= 10) floats.insert(testf);
00778 }
00779
00780 float last = *floats.begin();
00781
00782 runnable(last);
00783 runnable(-last);
00784 int iters_per_float = cases / floats.size();
00785 if (iters_per_float == 0) iters_per_float = 1;
00786 for (float f : floats) {
00787 if (f == last) continue;
00788 float testf = std::nextafter(last, std::numeric_limits<float>::max());
00789 runnable(testf);
00790 runnable(-testf);
00791 last = testf;
00792 if (f == last) continue;
00793 double step = (double{f} - last) / iters_per_float;
00794 for (double d = last + step; d < f; d += step) {
00795 testf = d;
00796 if (testf != last) {
00797 runnable(testf);
00798 runnable(-testf);
00799 last = testf;
00800 }
00801 }
00802 testf = std::nextafter(f, 0.0f);
00803 if (testf > last) {
00804 runnable(testf);
00805 runnable(-testf);
00806 last = testf;
00807 }
00808 if (f != last) {
00809 runnable(f);
00810 runnable(-f);
00811 last = f;
00812 }
00813 }
00814 }
00815
00816 TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
00817 uint64_t test_count = 0;
00818 std::vector<double> mismatches;
00819 auto checker = [&](double d) {
00820 if (d != d) return;
00821 ++test_count;
00822 char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
00823 SixDigitsToBuffer(d, sixdigitsbuf);
00824 char snprintfbuf[kSixDigitsToBufferSize] = {0};
00825 snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
00826 if (strcmp(sixdigitsbuf, snprintfbuf) != 0) {
00827 mismatches.push_back(d);
00828 if (mismatches.size() < 10) {
00829 ABSL_RAW_LOG(ERROR, "%s",
00830 absl::StrCat("Six-digit failure with double. ", "d=", d,
00831 "=", d, " sixdigits=", sixdigitsbuf,
00832 " printf(%g)=", snprintfbuf)
00833 .c_str());
00834 }
00835 }
00836 };
00837
00838 checker(5e-324);
00839 checker(1e-308);
00840 checker(1.0);
00841 checker(1.000005);
00842 checker(1.7976931348623157e308);
00843 checker(0.00390625);
00844 #ifndef _MSC_VER
00845
00846
00847 checker(0.001953125);
00848 #endif
00849 checker(0.005859375);
00850
00851 checker(1.089095e-15);
00852 checker(3.274195e-55);
00853 checker(6.534355e-146);
00854 checker(2.920845e+234);
00855
00856 if (mismatches.empty()) {
00857 test_count = 0;
00858 ExhaustiveFloat(kFloatNumCases, checker);
00859
00860 test_count = 0;
00861 std::vector<int> digit_testcases{
00862 100000, 100001, 100002, 100005, 100010, 100020, 100050, 100100,
00863 195312, 195313,
00864 200000, 500000, 800000,
00865 585937, 585938,
00866 900000, 990000, 999000, 999900, 999990, 999996, 999997, 999998, 999999};
00867 if (kFloatNumCases >= 1e9) {
00868
00869
00870 constexpr int min_mantissa = 100000, max_mantissa = 999999;
00871 digit_testcases.resize(max_mantissa - min_mantissa + 1);
00872 std::iota(digit_testcases.begin(), digit_testcases.end(), min_mantissa);
00873 }
00874
00875 for (int exponent = -324; exponent <= 308; ++exponent) {
00876 double powten = absl::strings_internal::Pow10(exponent);
00877 if (powten == 0) powten = 5e-324;
00878 if (kFloatNumCases >= 1e9) {
00879
00880 char buf[kSixDigitsToBufferSize];
00881 ABSL_RAW_LOG(
00882 INFO, "%s",
00883 absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten,
00884 ") (",
00885 std::string(buf, SixDigitsToBuffer(powten, buf)), ")")
00886 .c_str());
00887 }
00888 for (int digits : digit_testcases) {
00889 if (exponent == 308 && digits >= 179769) break;
00890 double digiform = (digits + 0.5) * 0.00001;
00891 double testval = digiform * powten;
00892 double pretestval = nextafter(testval, 0);
00893 double posttestval = nextafter(testval, 1.7976931348623157e308);
00894 checker(testval);
00895 checker(pretestval);
00896 checker(posttestval);
00897 }
00898 }
00899 } else {
00900 EXPECT_EQ(mismatches.size(), 0);
00901 for (size_t i = 0; i < mismatches.size(); ++i) {
00902 if (i > 100) i = mismatches.size() - 1;
00903 double d = mismatches[i];
00904 char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
00905 SixDigitsToBuffer(d, sixdigitsbuf);
00906 char snprintfbuf[kSixDigitsToBufferSize] = {0};
00907 snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
00908 double before = nextafter(d, 0.0);
00909 double after = nextafter(d, 1.7976931348623157e308);
00910 char b1[32], b2[kSixDigitsToBufferSize];
00911 ABSL_RAW_LOG(
00912 ERROR, "%s",
00913 absl::StrCat(
00914 "Mismatch #", i, " d=", d, " (", ToNineDigits(d), ")",
00915 " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf,
00916 "'", " Before.=", PerfectDtoa(before), " ",
00917 (SixDigitsToBuffer(before, b2), b2),
00918 " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1),
00919 " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2),
00920 " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1),
00921 " After.=.", PerfectDtoa(after), " ",
00922 (SixDigitsToBuffer(after, b2), b2),
00923 " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1))
00924 .c_str());
00925 }
00926 }
00927 }
00928
00929 TEST(StrToInt32, Partial) {
00930 struct Int32TestLine {
00931 std::string input;
00932 bool status;
00933 int32_t value;
00934 };
00935 const int32_t int32_min = std::numeric_limits<int32_t>::min();
00936 const int32_t int32_max = std::numeric_limits<int32_t>::max();
00937 Int32TestLine int32_test_line[] = {
00938 {"", false, 0},
00939 {" ", false, 0},
00940 {"-", false, 0},
00941 {"123@@@", false, 123},
00942 {absl::StrCat(int32_min, int32_max), false, int32_min},
00943 {absl::StrCat(int32_max, int32_max), false, int32_max},
00944 };
00945
00946 for (const Int32TestLine& test_line : int32_test_line) {
00947 int32_t value = -2;
00948 bool status = safe_strto32_base(test_line.input, &value, 10);
00949 EXPECT_EQ(test_line.status, status) << test_line.input;
00950 EXPECT_EQ(test_line.value, value) << test_line.input;
00951 value = -2;
00952 status = safe_strto32_base(test_line.input, &value, 10);
00953 EXPECT_EQ(test_line.status, status) << test_line.input;
00954 EXPECT_EQ(test_line.value, value) << test_line.input;
00955 value = -2;
00956 status = safe_strto32_base(absl::string_view(test_line.input), &value, 10);
00957 EXPECT_EQ(test_line.status, status) << test_line.input;
00958 EXPECT_EQ(test_line.value, value) << test_line.input;
00959 }
00960 }
00961
00962 TEST(StrToUint32, Partial) {
00963 struct Uint32TestLine {
00964 std::string input;
00965 bool status;
00966 uint32_t value;
00967 };
00968 const uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
00969 Uint32TestLine uint32_test_line[] = {
00970 {"", false, 0},
00971 {" ", false, 0},
00972 {"-", false, 0},
00973 {"123@@@", false, 123},
00974 {absl::StrCat(uint32_max, uint32_max), false, uint32_max},
00975 };
00976
00977 for (const Uint32TestLine& test_line : uint32_test_line) {
00978 uint32_t value = 2;
00979 bool status = safe_strtou32_base(test_line.input, &value, 10);
00980 EXPECT_EQ(test_line.status, status) << test_line.input;
00981 EXPECT_EQ(test_line.value, value) << test_line.input;
00982 value = 2;
00983 status = safe_strtou32_base(test_line.input, &value, 10);
00984 EXPECT_EQ(test_line.status, status) << test_line.input;
00985 EXPECT_EQ(test_line.value, value) << test_line.input;
00986 value = 2;
00987 status = safe_strtou32_base(absl::string_view(test_line.input), &value, 10);
00988 EXPECT_EQ(test_line.status, status) << test_line.input;
00989 EXPECT_EQ(test_line.value, value) << test_line.input;
00990 }
00991 }
00992
00993 TEST(StrToInt64, Partial) {
00994 struct Int64TestLine {
00995 std::string input;
00996 bool status;
00997 int64_t value;
00998 };
00999 const int64_t int64_min = std::numeric_limits<int64_t>::min();
01000 const int64_t int64_max = std::numeric_limits<int64_t>::max();
01001 Int64TestLine int64_test_line[] = {
01002 {"", false, 0},
01003 {" ", false, 0},
01004 {"-", false, 0},
01005 {"123@@@", false, 123},
01006 {absl::StrCat(int64_min, int64_max), false, int64_min},
01007 {absl::StrCat(int64_max, int64_max), false, int64_max},
01008 };
01009
01010 for (const Int64TestLine& test_line : int64_test_line) {
01011 int64_t value = -2;
01012 bool status = safe_strto64_base(test_line.input, &value, 10);
01013 EXPECT_EQ(test_line.status, status) << test_line.input;
01014 EXPECT_EQ(test_line.value, value) << test_line.input;
01015 value = -2;
01016 status = safe_strto64_base(test_line.input, &value, 10);
01017 EXPECT_EQ(test_line.status, status) << test_line.input;
01018 EXPECT_EQ(test_line.value, value) << test_line.input;
01019 value = -2;
01020 status = safe_strto64_base(absl::string_view(test_line.input), &value, 10);
01021 EXPECT_EQ(test_line.status, status) << test_line.input;
01022 EXPECT_EQ(test_line.value, value) << test_line.input;
01023 }
01024 }
01025
01026 TEST(StrToUint64, Partial) {
01027 struct Uint64TestLine {
01028 std::string input;
01029 bool status;
01030 uint64_t value;
01031 };
01032 const uint64_t uint64_max = std::numeric_limits<uint64_t>::max();
01033 Uint64TestLine uint64_test_line[] = {
01034 {"", false, 0},
01035 {" ", false, 0},
01036 {"-", false, 0},
01037 {"123@@@", false, 123},
01038 {absl::StrCat(uint64_max, uint64_max), false, uint64_max},
01039 };
01040
01041 for (const Uint64TestLine& test_line : uint64_test_line) {
01042 uint64_t value = 2;
01043 bool status = safe_strtou64_base(test_line.input, &value, 10);
01044 EXPECT_EQ(test_line.status, status) << test_line.input;
01045 EXPECT_EQ(test_line.value, value) << test_line.input;
01046 value = 2;
01047 status = safe_strtou64_base(test_line.input, &value, 10);
01048 EXPECT_EQ(test_line.status, status) << test_line.input;
01049 EXPECT_EQ(test_line.value, value) << test_line.input;
01050 value = 2;
01051 status = safe_strtou64_base(absl::string_view(test_line.input), &value, 10);
01052 EXPECT_EQ(test_line.status, status) << test_line.input;
01053 EXPECT_EQ(test_line.value, value) << test_line.input;
01054 }
01055 }
01056
01057 TEST(StrToInt32Base, PrefixOnly) {
01058 struct Int32TestLine {
01059 std::string input;
01060 bool status;
01061 int32_t value;
01062 };
01063 Int32TestLine int32_test_line[] = {
01064 { "", false, 0 },
01065 { "-", false, 0 },
01066 { "-0", true, 0 },
01067 { "0", true, 0 },
01068 { "0x", false, 0 },
01069 { "-0x", false, 0 },
01070 };
01071 const int base_array[] = { 0, 2, 8, 10, 16 };
01072
01073 for (const Int32TestLine& line : int32_test_line) {
01074 for (const int base : base_array) {
01075 int32_t value = 2;
01076 bool status = safe_strto32_base(line.input.c_str(), &value, base);
01077 EXPECT_EQ(line.status, status) << line.input << " " << base;
01078 EXPECT_EQ(line.value, value) << line.input << " " << base;
01079 value = 2;
01080 status = safe_strto32_base(line.input, &value, base);
01081 EXPECT_EQ(line.status, status) << line.input << " " << base;
01082 EXPECT_EQ(line.value, value) << line.input << " " << base;
01083 value = 2;
01084 status = safe_strto32_base(absl::string_view(line.input), &value, base);
01085 EXPECT_EQ(line.status, status) << line.input << " " << base;
01086 EXPECT_EQ(line.value, value) << line.input << " " << base;
01087 }
01088 }
01089 }
01090
01091 TEST(StrToUint32Base, PrefixOnly) {
01092 struct Uint32TestLine {
01093 std::string input;
01094 bool status;
01095 uint32_t value;
01096 };
01097 Uint32TestLine uint32_test_line[] = {
01098 { "", false, 0 },
01099 { "0", true, 0 },
01100 { "0x", false, 0 },
01101 };
01102 const int base_array[] = { 0, 2, 8, 10, 16 };
01103
01104 for (const Uint32TestLine& line : uint32_test_line) {
01105 for (const int base : base_array) {
01106 uint32_t value = 2;
01107 bool status = safe_strtou32_base(line.input.c_str(), &value, base);
01108 EXPECT_EQ(line.status, status) << line.input << " " << base;
01109 EXPECT_EQ(line.value, value) << line.input << " " << base;
01110 value = 2;
01111 status = safe_strtou32_base(line.input, &value, base);
01112 EXPECT_EQ(line.status, status) << line.input << " " << base;
01113 EXPECT_EQ(line.value, value) << line.input << " " << base;
01114 value = 2;
01115 status = safe_strtou32_base(absl::string_view(line.input), &value, base);
01116 EXPECT_EQ(line.status, status) << line.input << " " << base;
01117 EXPECT_EQ(line.value, value) << line.input << " " << base;
01118 }
01119 }
01120 }
01121
01122 TEST(StrToInt64Base, PrefixOnly) {
01123 struct Int64TestLine {
01124 std::string input;
01125 bool status;
01126 int64_t value;
01127 };
01128 Int64TestLine int64_test_line[] = {
01129 { "", false, 0 },
01130 { "-", false, 0 },
01131 { "-0", true, 0 },
01132 { "0", true, 0 },
01133 { "0x", false, 0 },
01134 { "-0x", false, 0 },
01135 };
01136 const int base_array[] = { 0, 2, 8, 10, 16 };
01137
01138 for (const Int64TestLine& line : int64_test_line) {
01139 for (const int base : base_array) {
01140 int64_t value = 2;
01141 bool status = safe_strto64_base(line.input.c_str(), &value, base);
01142 EXPECT_EQ(line.status, status) << line.input << " " << base;
01143 EXPECT_EQ(line.value, value) << line.input << " " << base;
01144 value = 2;
01145 status = safe_strto64_base(line.input, &value, base);
01146 EXPECT_EQ(line.status, status) << line.input << " " << base;
01147 EXPECT_EQ(line.value, value) << line.input << " " << base;
01148 value = 2;
01149 status = safe_strto64_base(absl::string_view(line.input), &value, base);
01150 EXPECT_EQ(line.status, status) << line.input << " " << base;
01151 EXPECT_EQ(line.value, value) << line.input << " " << base;
01152 }
01153 }
01154 }
01155
01156 TEST(StrToUint64Base, PrefixOnly) {
01157 struct Uint64TestLine {
01158 std::string input;
01159 bool status;
01160 uint64_t value;
01161 };
01162 Uint64TestLine uint64_test_line[] = {
01163 { "", false, 0 },
01164 { "0", true, 0 },
01165 { "0x", false, 0 },
01166 };
01167 const int base_array[] = { 0, 2, 8, 10, 16 };
01168
01169 for (const Uint64TestLine& line : uint64_test_line) {
01170 for (const int base : base_array) {
01171 uint64_t value = 2;
01172 bool status = safe_strtou64_base(line.input.c_str(), &value, base);
01173 EXPECT_EQ(line.status, status) << line.input << " " << base;
01174 EXPECT_EQ(line.value, value) << line.input << " " << base;
01175 value = 2;
01176 status = safe_strtou64_base(line.input, &value, base);
01177 EXPECT_EQ(line.status, status) << line.input << " " << base;
01178 EXPECT_EQ(line.value, value) << line.input << " " << base;
01179 value = 2;
01180 status = safe_strtou64_base(absl::string_view(line.input), &value, base);
01181 EXPECT_EQ(line.status, status) << line.input << " " << base;
01182 EXPECT_EQ(line.value, value) << line.input << " " << base;
01183 }
01184 }
01185 }
01186
01187 }