bloaty/third_party/abseil-cpp/absl/strings/numbers_test.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // This file tests string processing functions related to numeric values.
16 
17 #include "absl/strings/numbers.h"
18 
19 #include <sys/types.h>
20 
21 #include <cfenv> // NOLINT(build/c++11)
22 #include <cinttypes>
23 #include <climits>
24 #include <cmath>
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29 #include <cstring>
30 #include <limits>
31 #include <numeric>
32 #include <random>
33 #include <set>
34 #include <string>
35 #include <vector>
36 
37 #include "gmock/gmock.h"
38 #include "gtest/gtest.h"
39 #include "absl/base/internal/raw_logging.h"
40 #include "absl/random/distributions.h"
41 #include "absl/random/random.h"
42 #include "absl/strings/internal/numbers_test_common.h"
43 #include "absl/strings/internal/ostringstream.h"
44 #include "absl/strings/internal/pow10_helper.h"
45 #include "absl/strings/str_cat.h"
46 
47 namespace {
48 
49 using absl::SimpleAtoi;
59 using testing::Eq;
61 
62 // Number of floats to test with.
63 // 5,000,000 is a reasonable default for a test that only takes a few seconds.
64 // 1,000,000,000+ triggers checking for all possible mantissa values for
65 // double-precision tests. 2,000,000,000+ triggers checking for every possible
66 // single-precision float.
67 const int kFloatNumCases = 5000000;
68 
69 // This is a slow, brute-force routine to compute the exact base-10
70 // representation of a double-precision floating-point number. It
71 // is useful for debugging only.
72 std::string PerfectDtoa(double d) {
73  if (d == 0) return "0";
74  if (d < 0) return "-" + PerfectDtoa(-d);
75 
76  // Basic theory: decompose d into mantissa and exp, where
77  // d = mantissa * 2^exp, and exp is as close to zero as possible.
78  int64_t mantissa, exp = 0;
79  while (d >= 1ULL << 63) ++exp, d *= 0.5;
80  while ((mantissa = d) != d) --exp, d *= 2.0;
81 
82  // Then convert mantissa to ASCII, and either double it (if
83  // exp > 0) or halve it (if exp < 0) repeatedly. "halve it"
84  // in this case means multiplying it by five and dividing by 10.
85  constexpr int maxlen = 1100; // worst case is actually 1030 or so.
86  char buf[maxlen + 5];
87  for (int64_t num = mantissa, pos = maxlen; --pos >= 0;) {
88  buf[pos] = '0' + (num % 10);
89  num /= 10;
90  }
91  char* begin = &buf[0];
92  char* end = buf + maxlen;
93  for (int i = 0; i != exp; i += (exp > 0) ? 1 : -1) {
94  int carry = 0;
95  for (char* p = end; --p != begin;) {
96  int dig = *p - '0';
97  dig = dig * (exp > 0 ? 2 : 5) + carry;
98  carry = dig / 10;
99  dig %= 10;
100  *p = '0' + dig;
101  }
102  }
103  if (exp < 0) {
104  // "dividing by 10" above means we have to add the decimal point.
105  memmove(end + 1 + exp, end + exp, 1 - exp);
106  end[exp] = '.';
107  ++end;
108  }
109  while (*begin == '0' && begin[1] != '.') ++begin;
110  return {begin, end};
111 }
112 
113 TEST(ToString, PerfectDtoa) {
114  EXPECT_THAT(PerfectDtoa(1), Eq("1"));
115  EXPECT_THAT(PerfectDtoa(0.1),
116  Eq("0.1000000000000000055511151231257827021181583404541015625"));
117  EXPECT_THAT(PerfectDtoa(1e24), Eq("999999999999999983222784"));
118  EXPECT_THAT(PerfectDtoa(5e-324), MatchesRegex("0.0000.*625"));
119  for (int i = 0; i < 100; ++i) {
120  for (double multiplier :
121  {1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) {
122  double d = multiplier * i;
123  std::string s = PerfectDtoa(d);
124  EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr));
125  }
126  }
127 }
128 
129 template <typename integer>
130 struct MyInteger {
131  integer i;
132  explicit constexpr MyInteger(integer i) : i(i) {}
133  constexpr operator integer() const { return i; }
134 
135  constexpr MyInteger operator+(MyInteger other) const { return i + other.i; }
136  constexpr MyInteger operator-(MyInteger other) const { return i - other.i; }
137  constexpr MyInteger operator*(MyInteger other) const { return i * other.i; }
138  constexpr MyInteger operator/(MyInteger other) const { return i / other.i; }
139 
140  constexpr bool operator<(MyInteger other) const { return i < other.i; }
141  constexpr bool operator<=(MyInteger other) const { return i <= other.i; }
142  constexpr bool operator==(MyInteger other) const { return i == other.i; }
143  constexpr bool operator>=(MyInteger other) const { return i >= other.i; }
144  constexpr bool operator>(MyInteger other) const { return i > other.i; }
145  constexpr bool operator!=(MyInteger other) const { return i != other.i; }
146 
147  integer as_integer() const { return i; }
148 };
149 
150 typedef MyInteger<int64_t> MyInt64;
151 typedef MyInteger<uint64_t> MyUInt64;
152 
153 void CheckInt32(int32_t x) {
156  std::string expected = std::to_string(x);
157  EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
158 
159  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
160  EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
161 }
162 
163 void CheckInt64(int64_t x) {
165  buffer[0] = '*';
166  buffer[23] = '*';
167  buffer[24] = '*';
168  char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
169  std::string expected = std::to_string(x);
170  EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
171  EXPECT_EQ(buffer[0], '*');
172  EXPECT_EQ(buffer[23], '*');
173  EXPECT_EQ(buffer[24], '*');
174 
175  char* my_actual =
177  EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
178 }
179 
180 void CheckUInt32(uint32_t x) {
183  std::string expected = std::to_string(x);
184  EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
185 
186  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
187  EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
188 }
189 
190 void CheckUInt64(uint64_t x) {
192  char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
193  std::string expected = std::to_string(x);
194  EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
195 
196  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
197  EXPECT_EQ(expected, std::string(&buffer[1], generic_actual))
198  << " Input " << x;
199 
200  char* my_actual =
202  EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
203 }
204 
205 void CheckHex64(uint64_t v) {
206  char expected[16 + 1];
208  snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast<uint64_t>(v));
209  EXPECT_EQ(expected, actual) << " Input " << v;
211  snprintf(expected, sizeof(expected), "%16" PRIx64, static_cast<uint64_t>(v));
212  EXPECT_EQ(expected, actual) << " Input " << v;
213 }
214 
215 TEST(Numbers, TestFastPrints) {
216  for (int i = -100; i <= 100; i++) {
217  CheckInt32(i);
218  CheckInt64(i);
219  }
220  for (int i = 0; i <= 100; i++) {
221  CheckUInt32(i);
222  CheckUInt64(i);
223  }
224  // Test min int to make sure that works
225  CheckInt32(INT_MIN);
226  CheckInt32(INT_MAX);
227  CheckInt64(LONG_MIN);
228  CheckInt64(uint64_t{1000000000});
229  CheckInt64(uint64_t{9999999999});
230  CheckInt64(uint64_t{100000000000000});
231  CheckInt64(uint64_t{999999999999999});
232  CheckInt64(uint64_t{1000000000000000000});
233  CheckInt64(uint64_t{1199999999999999999});
234  CheckInt64(int64_t{-700000000000000000});
235  CheckInt64(LONG_MAX);
236  CheckUInt32(std::numeric_limits<uint32_t>::max());
237  CheckUInt64(uint64_t{1000000000});
238  CheckUInt64(uint64_t{9999999999});
239  CheckUInt64(uint64_t{100000000000000});
240  CheckUInt64(uint64_t{999999999999999});
241  CheckUInt64(uint64_t{1000000000000000000});
242  CheckUInt64(uint64_t{1199999999999999999});
243  CheckUInt64(std::numeric_limits<uint64_t>::max());
244 
245  for (int i = 0; i < 10000; i++) {
246  CheckHex64(i);
247  }
248  CheckHex64(uint64_t{0x123456789abcdef0});
249 }
250 
251 template <typename int_type, typename in_val_type>
252 void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) {
253  std::string s;
254  // (u)int128 can be streamed but not StrCat'd.
256  int_type x = static_cast<int_type>(~exp_value);
257  EXPECT_TRUE(SimpleAtoi(s, &x))
258  << "in_value=" << in_value << " s=" << s << " x=" << x;
259  EXPECT_EQ(exp_value, x);
260  x = static_cast<int_type>(~exp_value);
261  EXPECT_TRUE(SimpleAtoi(s.c_str(), &x));
262  EXPECT_EQ(exp_value, x);
263 }
264 
265 template <typename int_type, typename in_val_type>
266 void VerifySimpleAtoiBad(in_val_type in_value) {
267  std::string s;
268  // (u)int128 can be streamed but not StrCat'd.
270  int_type x;
271  EXPECT_FALSE(SimpleAtoi(s, &x));
272  EXPECT_FALSE(SimpleAtoi(s.c_str(), &x));
273 }
274 
275 TEST(NumbersTest, Atoi) {
276  // SimpleAtoi(absl::string_view, int32_t)
277  VerifySimpleAtoiGood<int32_t>(0, 0);
278  VerifySimpleAtoiGood<int32_t>(42, 42);
279  VerifySimpleAtoiGood<int32_t>(-42, -42);
280 
281  VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::min(),
283  VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::max(),
285 
286  // SimpleAtoi(absl::string_view, uint32_t)
287  VerifySimpleAtoiGood<uint32_t>(0, 0);
288  VerifySimpleAtoiGood<uint32_t>(42, 42);
289  VerifySimpleAtoiBad<uint32_t>(-42);
290 
291  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int32_t>::min());
292  VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<int32_t>::max(),
294  VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<uint32_t>::max(),
296  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::min());
297  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::max());
298  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<uint64_t>::max());
299 
300  // SimpleAtoi(absl::string_view, int64_t)
301  VerifySimpleAtoiGood<int64_t>(0, 0);
302  VerifySimpleAtoiGood<int64_t>(42, 42);
303  VerifySimpleAtoiGood<int64_t>(-42, -42);
304 
305  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::min(),
307  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::max(),
309  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<uint32_t>::max(),
311  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::min(),
313  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::max(),
315  VerifySimpleAtoiBad<int64_t>(std::numeric_limits<uint64_t>::max());
316 
317  // SimpleAtoi(absl::string_view, uint64_t)
318  VerifySimpleAtoiGood<uint64_t>(0, 0);
319  VerifySimpleAtoiGood<uint64_t>(42, 42);
320  VerifySimpleAtoiBad<uint64_t>(-42);
321 
322  VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int32_t>::min());
323  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int32_t>::max(),
325  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint32_t>::max(),
327  VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int64_t>::min());
328  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int64_t>::max(),
330  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint64_t>::max(),
332 
333  // SimpleAtoi(absl::string_view, absl::uint128)
334  VerifySimpleAtoiGood<absl::uint128>(0, 0);
335  VerifySimpleAtoiGood<absl::uint128>(42, 42);
336  VerifySimpleAtoiBad<absl::uint128>(-42);
337 
338  VerifySimpleAtoiBad<absl::uint128>(std::numeric_limits<int32_t>::min());
339  VerifySimpleAtoiGood<absl::uint128>(std::numeric_limits<int32_t>::max(),
341  VerifySimpleAtoiGood<absl::uint128>(std::numeric_limits<uint32_t>::max(),
343  VerifySimpleAtoiBad<absl::uint128>(std::numeric_limits<int64_t>::min());
344  VerifySimpleAtoiGood<absl::uint128>(std::numeric_limits<int64_t>::max(),
346  VerifySimpleAtoiGood<absl::uint128>(std::numeric_limits<uint64_t>::max(),
348  VerifySimpleAtoiGood<absl::uint128>(
351 
352  // SimpleAtoi(absl::string_view, absl::int128)
353  VerifySimpleAtoiGood<absl::int128>(0, 0);
354  VerifySimpleAtoiGood<absl::int128>(42, 42);
355  VerifySimpleAtoiGood<absl::int128>(-42, -42);
356 
357  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int32_t>::min(),
359  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int32_t>::max(),
361  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<uint32_t>::max(),
363  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int64_t>::min(),
365  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<int64_t>::max(),
367  VerifySimpleAtoiGood<absl::int128>(std::numeric_limits<uint64_t>::max(),
369  VerifySimpleAtoiGood<absl::int128>(
372  VerifySimpleAtoiGood<absl::int128>(
375  VerifySimpleAtoiBad<absl::int128>(std::numeric_limits<absl::uint128>::max());
376 
377  // Some other types
378  VerifySimpleAtoiGood<int>(-42, -42);
379  VerifySimpleAtoiGood<int32_t>(-42, -42);
380  VerifySimpleAtoiGood<uint32_t>(42, 42);
381  VerifySimpleAtoiGood<unsigned int>(42, 42);
382  VerifySimpleAtoiGood<int64_t>(-42, -42);
383  VerifySimpleAtoiGood<long>(-42, -42); // NOLINT: runtime-int
384  VerifySimpleAtoiGood<uint64_t>(42, 42);
385  VerifySimpleAtoiGood<size_t>(42, 42);
386  VerifySimpleAtoiGood<std::string::size_type>(42, 42);
387 }
388 
389 TEST(NumbersTest, Atod) {
390  double d;
391  EXPECT_TRUE(absl::SimpleAtod("nan", &d));
393 }
394 
395 TEST(NumbersTest, Prefixes) {
396  double d;
397  EXPECT_FALSE(absl::SimpleAtod("++1", &d));
398  EXPECT_FALSE(absl::SimpleAtod("+-1", &d));
399  EXPECT_FALSE(absl::SimpleAtod("-+1", &d));
400  EXPECT_FALSE(absl::SimpleAtod("--1", &d));
401  EXPECT_TRUE(absl::SimpleAtod("-1", &d));
402  EXPECT_EQ(d, -1.);
403  EXPECT_TRUE(absl::SimpleAtod("+1", &d));
404  EXPECT_EQ(d, +1.);
405 
406  float f;
407  EXPECT_FALSE(absl::SimpleAtof("++1", &f));
408  EXPECT_FALSE(absl::SimpleAtof("+-1", &f));
409  EXPECT_FALSE(absl::SimpleAtof("-+1", &f));
410  EXPECT_FALSE(absl::SimpleAtof("--1", &f));
411  EXPECT_TRUE(absl::SimpleAtof("-1", &f));
412  EXPECT_EQ(f, -1.f);
413  EXPECT_TRUE(absl::SimpleAtof("+1", &f));
414  EXPECT_EQ(f, +1.f);
415 }
416 
417 TEST(NumbersTest, Atoenum) {
418  enum E01 {
419  E01_zero = 0,
420  E01_one = 1,
421  };
422 
423  VerifySimpleAtoiGood<E01>(E01_zero, E01_zero);
424  VerifySimpleAtoiGood<E01>(E01_one, E01_one);
425 
426  enum E_101 {
427  E_101_minusone = -1,
428  E_101_zero = 0,
429  E_101_one = 1,
430  };
431 
432  VerifySimpleAtoiGood<E_101>(E_101_minusone, E_101_minusone);
433  VerifySimpleAtoiGood<E_101>(E_101_zero, E_101_zero);
434  VerifySimpleAtoiGood<E_101>(E_101_one, E_101_one);
435 
436  enum E_bigint {
437  E_bigint_zero = 0,
438  E_bigint_one = 1,
439  E_bigint_max31 = static_cast<int32_t>(0x7FFFFFFF),
440  };
441 
442  VerifySimpleAtoiGood<E_bigint>(E_bigint_zero, E_bigint_zero);
443  VerifySimpleAtoiGood<E_bigint>(E_bigint_one, E_bigint_one);
444  VerifySimpleAtoiGood<E_bigint>(E_bigint_max31, E_bigint_max31);
445 
446  enum E_fullint {
447  E_fullint_zero = 0,
448  E_fullint_one = 1,
449  E_fullint_max31 = static_cast<int32_t>(0x7FFFFFFF),
450  E_fullint_min32 = INT32_MIN,
451  };
452 
453  VerifySimpleAtoiGood<E_fullint>(E_fullint_zero, E_fullint_zero);
454  VerifySimpleAtoiGood<E_fullint>(E_fullint_one, E_fullint_one);
455  VerifySimpleAtoiGood<E_fullint>(E_fullint_max31, E_fullint_max31);
456  VerifySimpleAtoiGood<E_fullint>(E_fullint_min32, E_fullint_min32);
457 
458  enum E_biguint {
459  E_biguint_zero = 0,
460  E_biguint_one = 1,
461  E_biguint_max31 = static_cast<uint32_t>(0x7FFFFFFF),
462  E_biguint_max32 = static_cast<uint32_t>(0xFFFFFFFF),
463  };
464 
465  VerifySimpleAtoiGood<E_biguint>(E_biguint_zero, E_biguint_zero);
466  VerifySimpleAtoiGood<E_biguint>(E_biguint_one, E_biguint_one);
467  VerifySimpleAtoiGood<E_biguint>(E_biguint_max31, E_biguint_max31);
468  VerifySimpleAtoiGood<E_biguint>(E_biguint_max32, E_biguint_max32);
469 }
470 
471 TEST(stringtest, safe_strto32_base) {
472  int32_t value;
473  EXPECT_TRUE(safe_strto32_base("0x34234324", &value, 16));
474  EXPECT_EQ(0x34234324, value);
475 
476  EXPECT_TRUE(safe_strto32_base("0X34234324", &value, 16));
477  EXPECT_EQ(0x34234324, value);
478 
479  EXPECT_TRUE(safe_strto32_base("34234324", &value, 16));
480  EXPECT_EQ(0x34234324, value);
481 
482  EXPECT_TRUE(safe_strto32_base("0", &value, 16));
483  EXPECT_EQ(0, value);
484 
485  EXPECT_TRUE(safe_strto32_base(" \t\n -0x34234324", &value, 16));
486  EXPECT_EQ(-0x34234324, value);
487 
488  EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 16));
489  EXPECT_EQ(-0x34234324, value);
490 
491  EXPECT_TRUE(safe_strto32_base("7654321", &value, 8));
492  EXPECT_EQ(07654321, value);
493 
494  EXPECT_TRUE(safe_strto32_base("-01234", &value, 8));
495  EXPECT_EQ(-01234, value);
496 
497  EXPECT_FALSE(safe_strto32_base("1834", &value, 8));
498 
499  // Autodetect base.
501  EXPECT_EQ(0, value);
502 
503  EXPECT_TRUE(safe_strto32_base("077", &value, 0));
504  EXPECT_EQ(077, value); // Octal interpretation
505 
506  // Leading zero indicates octal, but then followed by invalid digit.
507  EXPECT_FALSE(safe_strto32_base("088", &value, 0));
508 
509  // Leading 0x indicated hex, but then followed by invalid digit.
510  EXPECT_FALSE(safe_strto32_base("0xG", &value, 0));
511 
512  // Base-10 version.
513  EXPECT_TRUE(safe_strto32_base("34234324", &value, 10));
514  EXPECT_EQ(34234324, value);
515 
516  EXPECT_TRUE(safe_strto32_base("0", &value, 10));
517  EXPECT_EQ(0, value);
518 
519  EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 10));
520  EXPECT_EQ(-34234324, value);
521 
522  EXPECT_TRUE(safe_strto32_base("34234324 \n\t ", &value, 10));
523  EXPECT_EQ(34234324, value);
524 
525  // Invalid ints.
528  EXPECT_FALSE(safe_strto32_base("abc", &value, 10));
529  EXPECT_FALSE(safe_strto32_base("34234324a", &value, 10));
530  EXPECT_FALSE(safe_strto32_base("34234.3", &value, 10));
531 
532  // Out of bounds.
533  EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
534  EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
535 
536  // String version.
538  EXPECT_EQ(0x1234, value);
539 
540  // Base-10 string version.
541  EXPECT_TRUE(safe_strto32_base("1234", &value, 10));
542  EXPECT_EQ(1234, value);
543 }
544 
545 TEST(stringtest, safe_strto32_range) {
546  // These tests verify underflow/overflow behaviour.
547  int32_t value;
548  EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
550 
551  EXPECT_TRUE(safe_strto32_base("-2147483648", &value, 10));
553 
554  EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
556 }
557 
558 TEST(stringtest, safe_strto64_range) {
559  // These tests verify underflow/overflow behaviour.
560  int64_t value;
561  EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
563 
564  EXPECT_TRUE(safe_strto64_base("-9223372036854775808", &value, 10));
566 
567  EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
569 }
570 
571 TEST(stringtest, safe_strto32_leading_substring) {
572  // These tests verify this comment in numbers.h:
573  // On error, returns false, and sets *value to: [...]
574  // conversion of leading substring if available ("123@@@" -> 123)
575  // 0 if no leading substring available
576  int32_t value;
577  EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 10));
578  EXPECT_EQ(4069, value);
579 
580  EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 8));
581  EXPECT_EQ(0406, value);
582 
583  EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 10));
584  EXPECT_EQ(4069, value);
585 
586  EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 16));
587  EXPECT_EQ(0x4069ba, value);
588 
589  EXPECT_FALSE(safe_strto32_base("@@@", &value, 10));
590  EXPECT_EQ(0, value); // there was no leading substring
591 }
592 
593 TEST(stringtest, safe_strto64_leading_substring) {
594  // These tests verify this comment in numbers.h:
595  // On error, returns false, and sets *value to: [...]
596  // conversion of leading substring if available ("123@@@" -> 123)
597  // 0 if no leading substring available
598  int64_t value;
599  EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 10));
600  EXPECT_EQ(4069, value);
601 
602  EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 8));
603  EXPECT_EQ(0406, value);
604 
605  EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 10));
606  EXPECT_EQ(4069, value);
607 
608  EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 16));
609  EXPECT_EQ(0x4069ba, value);
610 
611  EXPECT_FALSE(safe_strto64_base("@@@", &value, 10));
612  EXPECT_EQ(0, value); // there was no leading substring
613 }
614 
615 TEST(stringtest, safe_strto64_base) {
616  int64_t value;
617  EXPECT_TRUE(safe_strto64_base("0x3423432448783446", &value, 16));
618  EXPECT_EQ(int64_t{0x3423432448783446}, value);
619 
620  EXPECT_TRUE(safe_strto64_base("3423432448783446", &value, 16));
621  EXPECT_EQ(int64_t{0x3423432448783446}, value);
622 
623  EXPECT_TRUE(safe_strto64_base("0", &value, 16));
624  EXPECT_EQ(0, value);
625 
626  EXPECT_TRUE(safe_strto64_base(" \t\n -0x3423432448783446", &value, 16));
627  EXPECT_EQ(int64_t{-0x3423432448783446}, value);
628 
629  EXPECT_TRUE(safe_strto64_base(" \t\n -3423432448783446", &value, 16));
630  EXPECT_EQ(int64_t{-0x3423432448783446}, value);
631 
632  EXPECT_TRUE(safe_strto64_base("123456701234567012", &value, 8));
633  EXPECT_EQ(int64_t{0123456701234567012}, value);
634 
635  EXPECT_TRUE(safe_strto64_base("-017777777777777", &value, 8));
636  EXPECT_EQ(int64_t{-017777777777777}, value);
637 
638  EXPECT_FALSE(safe_strto64_base("19777777777777", &value, 8));
639 
640  // Autodetect base.
642  EXPECT_EQ(0, value);
643 
644  EXPECT_TRUE(safe_strto64_base("077", &value, 0));
645  EXPECT_EQ(077, value); // Octal interpretation
646 
647  // Leading zero indicates octal, but then followed by invalid digit.
648  EXPECT_FALSE(safe_strto64_base("088", &value, 0));
649 
650  // Leading 0x indicated hex, but then followed by invalid digit.
651  EXPECT_FALSE(safe_strto64_base("0xG", &value, 0));
652 
653  // Base-10 version.
654  EXPECT_TRUE(safe_strto64_base("34234324487834466", &value, 10));
655  EXPECT_EQ(int64_t{34234324487834466}, value);
656 
657  EXPECT_TRUE(safe_strto64_base("0", &value, 10));
658  EXPECT_EQ(0, value);
659 
660  EXPECT_TRUE(safe_strto64_base(" \t\n -34234324487834466", &value, 10));
661  EXPECT_EQ(int64_t{-34234324487834466}, value);
662 
663  EXPECT_TRUE(safe_strto64_base("34234324487834466 \n\t ", &value, 10));
664  EXPECT_EQ(int64_t{34234324487834466}, value);
665 
666  // Invalid ints.
669  EXPECT_FALSE(safe_strto64_base("abc", &value, 10));
670  EXPECT_FALSE(safe_strto64_base("34234324487834466a", &value, 10));
671  EXPECT_FALSE(safe_strto64_base("34234487834466.3", &value, 10));
672 
673  // Out of bounds.
674  EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
675  EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
676 
677  // String version.
679  EXPECT_EQ(0x1234, value);
680 
681  // Base-10 string version.
682  EXPECT_TRUE(safe_strto64_base("1234", &value, 10));
683  EXPECT_EQ(1234, value);
684 }
685 
686 const size_t kNumRandomTests = 10000;
687 
688 template <typename IntType>
689 void test_random_integer_parse_base(bool (*parse_func)(absl::string_view,
690  IntType* value,
691  int base)) {
692  using RandomEngine = std::minstd_rand0;
693  std::random_device rd;
694  RandomEngine rng(rd());
695  std::uniform_int_distribution<IntType> random_int(
697  std::uniform_int_distribution<int> random_base(2, 35);
698  for (size_t i = 0; i < kNumRandomTests; i++) {
699  IntType value = random_int(rng);
700  int base = random_base(rng);
701  std::string str_value;
702  EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
703  IntType parsed_value;
704 
705  // Test successful parse
706  EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
707  EXPECT_EQ(parsed_value, value);
708 
709  // Test overflow
710  EXPECT_FALSE(
712  &parsed_value, base));
713 
714  // Test underflow
716  EXPECT_FALSE(
718  &parsed_value, base));
719  } else {
720  EXPECT_FALSE(parse_func(absl::StrCat("-", value), &parsed_value, base));
721  }
722  }
723 }
724 
725 TEST(stringtest, safe_strto32_random) {
726  test_random_integer_parse_base<int32_t>(&safe_strto32_base);
727 }
728 TEST(stringtest, safe_strto64_random) {
729  test_random_integer_parse_base<int64_t>(&safe_strto64_base);
730 }
731 TEST(stringtest, safe_strtou32_random) {
732  test_random_integer_parse_base<uint32_t>(&safe_strtou32_base);
733 }
734 TEST(stringtest, safe_strtou64_random) {
735  test_random_integer_parse_base<uint64_t>(&safe_strtou64_base);
736 }
737 TEST(stringtest, safe_strtou128_random) {
738  // random number generators don't work for uint128, and
739  // uint128 can be streamed but not StrCat'd, so this code must be custom
740  // implemented for uint128, but is generally the same as what's above.
741  // test_random_integer_parse_base<absl::uint128>(
742  // &absl::numbers_internal::safe_strtou128_base);
743  using RandomEngine = std::minstd_rand0;
744  using IntType = absl::uint128;
745  constexpr auto parse_func = &absl::numbers_internal::safe_strtou128_base;
746 
747  std::random_device rd;
748  RandomEngine rng(rd());
749  std::uniform_int_distribution<uint64_t> random_uint64(
751  std::uniform_int_distribution<int> random_base(2, 35);
752 
753  for (size_t i = 0; i < kNumRandomTests; i++) {
754  IntType value = random_uint64(rng);
755  value = (value << 64) + random_uint64(rng);
756  int base = random_base(rng);
757  std::string str_value;
758  EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
759  IntType parsed_value;
760 
761  // Test successful parse
762  EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
763  EXPECT_EQ(parsed_value, value);
764 
765  // Test overflow
766  std::string s;
769  EXPECT_FALSE(parse_func(s, &parsed_value, base));
770 
771  // Test underflow
772  s.clear();
774  EXPECT_FALSE(parse_func(s, &parsed_value, base));
775  }
776 }
777 TEST(stringtest, safe_strto128_random) {
778  // random number generators don't work for int128, and
779  // int128 can be streamed but not StrCat'd, so this code must be custom
780  // implemented for int128, but is generally the same as what's above.
781  // test_random_integer_parse_base<absl::int128>(
782  // &absl::numbers_internal::safe_strto128_base);
783  using RandomEngine = std::minstd_rand0;
784  using IntType = absl::int128;
785  constexpr auto parse_func = &absl::numbers_internal::safe_strto128_base;
786 
787  std::random_device rd;
788  RandomEngine rng(rd());
789  std::uniform_int_distribution<int64_t> random_int64(
791  std::uniform_int_distribution<uint64_t> random_uint64(
793  std::uniform_int_distribution<int> random_base(2, 35);
794 
795  for (size_t i = 0; i < kNumRandomTests; ++i) {
796  int64_t high = random_int64(rng);
797  uint64_t low = random_uint64(rng);
798  IntType value = absl::MakeInt128(high, low);
799 
800  int base = random_base(rng);
801  std::string str_value;
802  EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
803  IntType parsed_value;
804 
805  // Test successful parse
806  EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
807  EXPECT_EQ(parsed_value, value);
808 
809  // Test overflow
810  std::string s;
813  EXPECT_FALSE(parse_func(s, &parsed_value, base));
814 
815  // Test underflow
816  s.clear();
819  EXPECT_FALSE(parse_func(s, &parsed_value, base));
820  }
821 }
822 
823 TEST(stringtest, safe_strtou32_base) {
824  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
825  const auto& e = strtouint32_test_cases()[i];
826  uint32_t value;
827  EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
828  << "str=\"" << e.str << "\" base=" << e.base;
829  if (e.expect_ok) {
830  EXPECT_EQ(e.expected, value) << "i=" << i << " str=\"" << e.str
831  << "\" base=" << e.base;
832  }
833  }
834 }
835 
836 TEST(stringtest, safe_strtou32_base_length_delimited) {
837  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
838  const auto& e = strtouint32_test_cases()[i];
839  std::string tmp(e.str);
840  tmp.append("12"); // Adds garbage at the end.
841 
842  uint32_t value;
843  EXPECT_EQ(e.expect_ok,
844  safe_strtou32_base(absl::string_view(tmp.data(), strlen(e.str)),
845  &value, e.base))
846  << "str=\"" << e.str << "\" base=" << e.base;
847  if (e.expect_ok) {
848  EXPECT_EQ(e.expected, value) << "i=" << i << " str=" << e.str
849  << " base=" << e.base;
850  }
851  }
852 }
853 
854 TEST(stringtest, safe_strtou64_base) {
855  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
856  const auto& e = strtouint64_test_cases()[i];
857  uint64_t value;
858  EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
859  << "str=\"" << e.str << "\" base=" << e.base;
860  if (e.expect_ok) {
861  EXPECT_EQ(e.expected, value) << "str=" << e.str << " base=" << e.base;
862  }
863  }
864 }
865 
866 TEST(stringtest, safe_strtou64_base_length_delimited) {
867  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
868  const auto& e = strtouint64_test_cases()[i];
869  std::string tmp(e.str);
870  tmp.append("12"); // Adds garbage at the end.
871 
872  uint64_t value;
873  EXPECT_EQ(e.expect_ok,
874  safe_strtou64_base(absl::string_view(tmp.data(), strlen(e.str)),
875  &value, e.base))
876  << "str=\"" << e.str << "\" base=" << e.base;
877  if (e.expect_ok) {
878  EXPECT_EQ(e.expected, value) << "str=\"" << e.str << "\" base=" << e.base;
879  }
880  }
881 }
882 
883 // feenableexcept() and fedisableexcept() are extensions supported by some libc
884 // implementations.
885 #if defined(__GLIBC__) || defined(__BIONIC__)
886 #define ABSL_HAVE_FEENABLEEXCEPT 1
887 #define ABSL_HAVE_FEDISABLEEXCEPT 1
888 #endif
889 
890 class SimpleDtoaTest : public testing::Test {
891  protected:
892  void SetUp() override {
893  // Store the current floating point env & clear away any pending exceptions.
894  feholdexcept(&fp_env_);
895 #ifdef ABSL_HAVE_FEENABLEEXCEPT
896  // Turn on floating point exceptions.
897  feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
898 #endif
899  }
900 
901  void TearDown() override {
902  // Restore the floating point environment to the original state.
903  // In theory fedisableexcept is unnecessary; fesetenv will also do it.
904  // In practice, our toolchains have subtle bugs.
905 #ifdef ABSL_HAVE_FEDISABLEEXCEPT
906  fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
907 #endif
908  fesetenv(&fp_env_);
909  }
910 
911  std::string ToNineDigits(double value) {
912  char buffer[16]; // more than enough for %.9g
913  snprintf(buffer, sizeof(buffer), "%.9g", value);
914  return buffer;
915  }
916 
917  fenv_t fp_env_;
918 };
919 
920 // Run the given runnable functor for "cases" test cases, chosen over the
921 // available range of float. pi and e and 1/e are seeded, and then all
922 // available integer powers of 2 and 10 are multiplied against them. In
923 // addition to trying all those values, we try the next higher and next lower
924 // float, and then we add additional test cases evenly distributed between them.
925 // Each test case is passed to runnable as both a positive and negative value.
926 template <typename R>
927 void ExhaustiveFloat(uint32_t cases, R&& runnable) {
928  runnable(0.0f);
929  runnable(-0.0f);
930  if (cases >= 2e9) { // more than 2 billion? Might as well run them all.
931  for (float f = 0; f < std::numeric_limits<float>::max(); ) {
932  f = nextafterf(f, std::numeric_limits<float>::max());
933  runnable(-f);
934  runnable(f);
935  }
936  return;
937  }
938  std::set<float> floats = {3.4028234e38f};
939  for (float f : {1.0, 3.14159265, 2.718281828, 1 / 2.718281828}) {
940  for (float testf = f; testf != 0; testf *= 0.1f) floats.insert(testf);
941  for (float testf = f; testf != 0; testf *= 0.5f) floats.insert(testf);
942  for (float testf = f; testf < 3e38f / 2; testf *= 2.0f)
943  floats.insert(testf);
944  for (float testf = f; testf < 3e38f / 10; testf *= 10) floats.insert(testf);
945  }
946 
947  float last = *floats.begin();
948 
949  runnable(last);
950  runnable(-last);
951  int iters_per_float = cases / floats.size();
952  if (iters_per_float == 0) iters_per_float = 1;
953  for (float f : floats) {
954  if (f == last) continue;
955  float testf = std::nextafter(last, std::numeric_limits<float>::max());
956  runnable(testf);
957  runnable(-testf);
958  last = testf;
959  if (f == last) continue;
960  double step = (double{f} - last) / iters_per_float;
961  for (double d = last + step; d < f; d += step) {
962  testf = d;
963  if (testf != last) {
964  runnable(testf);
965  runnable(-testf);
966  last = testf;
967  }
968  }
969  testf = std::nextafter(f, 0.0f);
970  if (testf > last) {
971  runnable(testf);
972  runnable(-testf);
973  last = testf;
974  }
975  if (f != last) {
976  runnable(f);
977  runnable(-f);
978  last = f;
979  }
980  }
981 }
982 
983 TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
984  uint64_t test_count = 0;
985  std::vector<double> mismatches;
986  auto checker = [&](double d) {
987  if (d != d) return; // rule out NaNs
988  ++test_count;
989  char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
990  SixDigitsToBuffer(d, sixdigitsbuf);
991  char snprintfbuf[kSixDigitsToBufferSize] = {0};
992  snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
993  if (strcmp(sixdigitsbuf, snprintfbuf) != 0) {
994  mismatches.push_back(d);
995  if (mismatches.size() < 10) {
996  ABSL_RAW_LOG(ERROR, "%s",
997  absl::StrCat("Six-digit failure with double. ", "d=", d,
998  "=", d, " sixdigits=", sixdigitsbuf,
999  " printf(%g)=", snprintfbuf)
1000  .c_str());
1001  }
1002  }
1003  };
1004  // Some quick sanity checks...
1005  checker(5e-324);
1006  checker(1e-308);
1007  checker(1.0);
1008  checker(1.000005);
1009  checker(1.7976931348623157e308);
1010  checker(0.00390625);
1011 #ifndef _MSC_VER
1012  // on MSVC, snprintf() rounds it to 0.00195313. SixDigitsToBuffer() rounds it
1013  // to 0.00195312 (round half to even).
1014  checker(0.001953125);
1015 #endif
1016  checker(0.005859375);
1017  // Some cases where the rounding is very very close
1018  checker(1.089095e-15);
1019  checker(3.274195e-55);
1020  checker(6.534355e-146);
1021  checker(2.920845e+234);
1022 
1023  if (mismatches.empty()) {
1024  test_count = 0;
1025  ExhaustiveFloat(kFloatNumCases, checker);
1026 
1027  test_count = 0;
1028  std::vector<int> digit_testcases{
1029  100000, 100001, 100002, 100005, 100010, 100020, 100050, 100100, // misc
1030  195312, 195313, // 1.953125 is a case where we round down, just barely.
1031  200000, 500000, 800000, // misc mid-range cases
1032  585937, 585938, // 5.859375 is a case where we round up, just barely.
1033  900000, 990000, 999000, 999900, 999990, 999996, 999997, 999998, 999999};
1034  if (kFloatNumCases >= 1e9) {
1035  // If at least 1 billion test cases were requested, user wants an
1036  // exhaustive test. So let's test all mantissas, too.
1037  constexpr int min_mantissa = 100000, max_mantissa = 999999;
1038  digit_testcases.resize(max_mantissa - min_mantissa + 1);
1039  std::iota(digit_testcases.begin(), digit_testcases.end(), min_mantissa);
1040  }
1041 
1042  for (int exponent = -324; exponent <= 308; ++exponent) {
1043  double powten = absl::strings_internal::Pow10(exponent);
1044  if (powten == 0) powten = 5e-324;
1045  if (kFloatNumCases >= 1e9) {
1046  // The exhaustive test takes a very long time, so log progress.
1048  ABSL_RAW_LOG(
1049  INFO, "%s",
1050  absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten,
1051  ") (",
1052  std::string(buf, SixDigitsToBuffer(powten, buf)), ")")
1053  .c_str());
1054  }
1055  for (int digits : digit_testcases) {
1056  if (exponent == 308 && digits >= 179769) break; // don't overflow!
1057  double digiform = (digits + 0.5) * 0.00001;
1058  double testval = digiform * powten;
1059  double pretestval = nextafter(testval, 0);
1060  double posttestval = nextafter(testval, 1.7976931348623157e308);
1061  checker(testval);
1062  checker(pretestval);
1063  checker(posttestval);
1064  }
1065  }
1066  } else {
1067  EXPECT_EQ(mismatches.size(), 0);
1068  for (size_t i = 0; i < mismatches.size(); ++i) {
1069  if (i > 100) i = mismatches.size() - 1;
1070  double d = mismatches[i];
1071  char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
1072  SixDigitsToBuffer(d, sixdigitsbuf);
1073  char snprintfbuf[kSixDigitsToBufferSize] = {0};
1074  snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
1075  double before = nextafter(d, 0.0);
1076  double after = nextafter(d, 1.7976931348623157e308);
1077  char b1[32], b2[kSixDigitsToBufferSize];
1078  ABSL_RAW_LOG(
1079  ERROR, "%s",
1080  absl::StrCat(
1081  "Mismatch #", i, " d=", d, " (", ToNineDigits(d), ")",
1082  " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf,
1083  "'", " Before.=", PerfectDtoa(before), " ",
1085  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1),
1086  " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2),
1087  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1),
1088  " After.=.", PerfectDtoa(after), " ",
1090  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1))
1091  .c_str());
1092  }
1093  }
1094 }
1095 
1096 TEST(StrToInt32, Partial) {
1097  struct Int32TestLine {
1099  bool status;
1100  int32_t value;
1101  };
1102  const int32_t int32_min = std::numeric_limits<int32_t>::min();
1103  const int32_t int32_max = std::numeric_limits<int32_t>::max();
1104  Int32TestLine int32_test_line[] = {
1105  {"", false, 0},
1106  {" ", false, 0},
1107  {"-", false, 0},
1108  {"123@@@", false, 123},
1109  {absl::StrCat(int32_min, int32_max), false, int32_min},
1110  {absl::StrCat(int32_max, int32_max), false, int32_max},
1111  };
1112 
1113  for (const Int32TestLine& test_line : int32_test_line) {
1114  int32_t value = -2;
1115  bool status = safe_strto32_base(test_line.input, &value, 10);
1116  EXPECT_EQ(test_line.status, status) << test_line.input;
1117  EXPECT_EQ(test_line.value, value) << test_line.input;
1118  value = -2;
1119  status = safe_strto32_base(test_line.input, &value, 10);
1120  EXPECT_EQ(test_line.status, status) << test_line.input;
1121  EXPECT_EQ(test_line.value, value) << test_line.input;
1122  value = -2;
1123  status = safe_strto32_base(absl::string_view(test_line.input), &value, 10);
1124  EXPECT_EQ(test_line.status, status) << test_line.input;
1125  EXPECT_EQ(test_line.value, value) << test_line.input;
1126  }
1127 }
1128 
1129 TEST(StrToUint32, Partial) {
1130  struct Uint32TestLine {
1132  bool status;
1133  uint32_t value;
1134  };
1135  const uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
1136  Uint32TestLine uint32_test_line[] = {
1137  {"", false, 0},
1138  {" ", false, 0},
1139  {"-", false, 0},
1140  {"123@@@", false, 123},
1141  {absl::StrCat(uint32_max, uint32_max), false, uint32_max},
1142  };
1143 
1144  for (const Uint32TestLine& test_line : uint32_test_line) {
1145  uint32_t value = 2;
1146  bool status = safe_strtou32_base(test_line.input, &value, 10);
1147  EXPECT_EQ(test_line.status, status) << test_line.input;
1148  EXPECT_EQ(test_line.value, value) << test_line.input;
1149  value = 2;
1150  status = safe_strtou32_base(test_line.input, &value, 10);
1151  EXPECT_EQ(test_line.status, status) << test_line.input;
1152  EXPECT_EQ(test_line.value, value) << test_line.input;
1153  value = 2;
1154  status = safe_strtou32_base(absl::string_view(test_line.input), &value, 10);
1155  EXPECT_EQ(test_line.status, status) << test_line.input;
1156  EXPECT_EQ(test_line.value, value) << test_line.input;
1157  }
1158 }
1159 
1160 TEST(StrToInt64, Partial) {
1161  struct Int64TestLine {
1163  bool status;
1164  int64_t value;
1165  };
1166  const int64_t int64_min = std::numeric_limits<int64_t>::min();
1167  const int64_t int64_max = std::numeric_limits<int64_t>::max();
1168  Int64TestLine int64_test_line[] = {
1169  {"", false, 0},
1170  {" ", false, 0},
1171  {"-", false, 0},
1172  {"123@@@", false, 123},
1173  {absl::StrCat(int64_min, int64_max), false, int64_min},
1174  {absl::StrCat(int64_max, int64_max), false, int64_max},
1175  };
1176 
1177  for (const Int64TestLine& test_line : int64_test_line) {
1178  int64_t value = -2;
1179  bool status = safe_strto64_base(test_line.input, &value, 10);
1180  EXPECT_EQ(test_line.status, status) << test_line.input;
1181  EXPECT_EQ(test_line.value, value) << test_line.input;
1182  value = -2;
1183  status = safe_strto64_base(test_line.input, &value, 10);
1184  EXPECT_EQ(test_line.status, status) << test_line.input;
1185  EXPECT_EQ(test_line.value, value) << test_line.input;
1186  value = -2;
1187  status = safe_strto64_base(absl::string_view(test_line.input), &value, 10);
1188  EXPECT_EQ(test_line.status, status) << test_line.input;
1189  EXPECT_EQ(test_line.value, value) << test_line.input;
1190  }
1191 }
1192 
1193 TEST(StrToUint64, Partial) {
1194  struct Uint64TestLine {
1196  bool status;
1197  uint64_t value;
1198  };
1199  const uint64_t uint64_max = std::numeric_limits<uint64_t>::max();
1200  Uint64TestLine uint64_test_line[] = {
1201  {"", false, 0},
1202  {" ", false, 0},
1203  {"-", false, 0},
1204  {"123@@@", false, 123},
1205  {absl::StrCat(uint64_max, uint64_max), false, uint64_max},
1206  };
1207 
1208  for (const Uint64TestLine& test_line : uint64_test_line) {
1209  uint64_t value = 2;
1210  bool status = safe_strtou64_base(test_line.input, &value, 10);
1211  EXPECT_EQ(test_line.status, status) << test_line.input;
1212  EXPECT_EQ(test_line.value, value) << test_line.input;
1213  value = 2;
1214  status = safe_strtou64_base(test_line.input, &value, 10);
1215  EXPECT_EQ(test_line.status, status) << test_line.input;
1216  EXPECT_EQ(test_line.value, value) << test_line.input;
1217  value = 2;
1218  status = safe_strtou64_base(absl::string_view(test_line.input), &value, 10);
1219  EXPECT_EQ(test_line.status, status) << test_line.input;
1220  EXPECT_EQ(test_line.value, value) << test_line.input;
1221  }
1222 }
1223 
1224 TEST(StrToInt32Base, PrefixOnly) {
1225  struct Int32TestLine {
1227  bool status;
1228  int32_t value;
1229  };
1230  Int32TestLine int32_test_line[] = {
1231  { "", false, 0 },
1232  { "-", false, 0 },
1233  { "-0", true, 0 },
1234  { "0", true, 0 },
1235  { "0x", false, 0 },
1236  { "-0x", false, 0 },
1237  };
1238  const int base_array[] = { 0, 2, 8, 10, 16 };
1239 
1240  for (const Int32TestLine& line : int32_test_line) {
1241  for (const int base : base_array) {
1242  int32_t value = 2;
1243  bool status = safe_strto32_base(line.input.c_str(), &value, base);
1244  EXPECT_EQ(line.status, status) << line.input << " " << base;
1245  EXPECT_EQ(line.value, value) << line.input << " " << base;
1246  value = 2;
1247  status = safe_strto32_base(line.input, &value, base);
1248  EXPECT_EQ(line.status, status) << line.input << " " << base;
1249  EXPECT_EQ(line.value, value) << line.input << " " << base;
1250  value = 2;
1252  EXPECT_EQ(line.status, status) << line.input << " " << base;
1253  EXPECT_EQ(line.value, value) << line.input << " " << base;
1254  }
1255  }
1256 }
1257 
1258 TEST(StrToUint32Base, PrefixOnly) {
1259  struct Uint32TestLine {
1261  bool status;
1262  uint32_t value;
1263  };
1264  Uint32TestLine uint32_test_line[] = {
1265  { "", false, 0 },
1266  { "0", true, 0 },
1267  { "0x", false, 0 },
1268  };
1269  const int base_array[] = { 0, 2, 8, 10, 16 };
1270 
1271  for (const Uint32TestLine& line : uint32_test_line) {
1272  for (const int base : base_array) {
1273  uint32_t value = 2;
1274  bool status = safe_strtou32_base(line.input.c_str(), &value, base);
1275  EXPECT_EQ(line.status, status) << line.input << " " << base;
1276  EXPECT_EQ(line.value, value) << line.input << " " << base;
1277  value = 2;
1278  status = safe_strtou32_base(line.input, &value, base);
1279  EXPECT_EQ(line.status, status) << line.input << " " << base;
1280  EXPECT_EQ(line.value, value) << line.input << " " << base;
1281  value = 2;
1283  EXPECT_EQ(line.status, status) << line.input << " " << base;
1284  EXPECT_EQ(line.value, value) << line.input << " " << base;
1285  }
1286  }
1287 }
1288 
1289 TEST(StrToInt64Base, PrefixOnly) {
1290  struct Int64TestLine {
1292  bool status;
1293  int64_t value;
1294  };
1295  Int64TestLine int64_test_line[] = {
1296  { "", false, 0 },
1297  { "-", false, 0 },
1298  { "-0", true, 0 },
1299  { "0", true, 0 },
1300  { "0x", false, 0 },
1301  { "-0x", false, 0 },
1302  };
1303  const int base_array[] = { 0, 2, 8, 10, 16 };
1304 
1305  for (const Int64TestLine& line : int64_test_line) {
1306  for (const int base : base_array) {
1307  int64_t value = 2;
1308  bool status = safe_strto64_base(line.input.c_str(), &value, base);
1309  EXPECT_EQ(line.status, status) << line.input << " " << base;
1310  EXPECT_EQ(line.value, value) << line.input << " " << base;
1311  value = 2;
1312  status = safe_strto64_base(line.input, &value, base);
1313  EXPECT_EQ(line.status, status) << line.input << " " << base;
1314  EXPECT_EQ(line.value, value) << line.input << " " << base;
1315  value = 2;
1317  EXPECT_EQ(line.status, status) << line.input << " " << base;
1318  EXPECT_EQ(line.value, value) << line.input << " " << base;
1319  }
1320  }
1321 }
1322 
1323 TEST(StrToUint64Base, PrefixOnly) {
1324  struct Uint64TestLine {
1326  bool status;
1327  uint64_t value;
1328  };
1329  Uint64TestLine uint64_test_line[] = {
1330  { "", false, 0 },
1331  { "0", true, 0 },
1332  { "0x", false, 0 },
1333  };
1334  const int base_array[] = { 0, 2, 8, 10, 16 };
1335 
1336  for (const Uint64TestLine& line : uint64_test_line) {
1337  for (const int base : base_array) {
1338  uint64_t value = 2;
1339  bool status = safe_strtou64_base(line.input.c_str(), &value, base);
1340  EXPECT_EQ(line.status, status) << line.input << " " << base;
1341  EXPECT_EQ(line.value, value) << line.input << " " << base;
1342  value = 2;
1343  status = safe_strtou64_base(line.input, &value, base);
1344  EXPECT_EQ(line.status, status) << line.input << " " << base;
1345  EXPECT_EQ(line.value, value) << line.input << " " << base;
1346  value = 2;
1348  EXPECT_EQ(line.status, status) << line.input << " " << base;
1349  EXPECT_EQ(line.value, value) << line.input << " " << base;
1350  }
1351  }
1352 }
1353 
1354 void TestFastHexToBufferZeroPad16(uint64_t v) {
1355  char buf[16];
1357  absl::string_view res(buf, 16);
1358  char buf2[17];
1359  snprintf(buf2, sizeof(buf2), "%016" PRIx64, v);
1360  EXPECT_EQ(res, buf2) << v;
1361  size_t expected_digits = snprintf(buf2, sizeof(buf2), "%" PRIx64, v);
1362  EXPECT_EQ(digits, expected_digits) << v;
1363 }
1364 
1366  TestFastHexToBufferZeroPad16(std::numeric_limits<uint64_t>::min());
1367  TestFastHexToBufferZeroPad16(std::numeric_limits<uint64_t>::max());
1368  TestFastHexToBufferZeroPad16(std::numeric_limits<int64_t>::min());
1369  TestFastHexToBufferZeroPad16(std::numeric_limits<int64_t>::max());
1370  absl::BitGen rng;
1371  for (int i = 0; i < 100000; ++i) {
1372  TestFastHexToBufferZeroPad16(
1375  }
1376 }
1377 
1378 } // namespace
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
grpc_event_engine::experimental::slice_detail::operator==
bool operator==(const BaseSlice &a, const BaseSlice &b)
Definition: include/grpc/event_engine/slice.h:117
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::numbers_internal::FastHexToBufferZeroPad16
size_t FastHexToBufferZeroPad16(uint64_t val, char *out)
Definition: abseil-cpp/absl/strings/numbers.h:245
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
grpc_core::operator+
Duration operator+(Duration lhs, Duration rhs)
Definition: src/core/lib/gprpp/time.h:229
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
tests.google.protobuf.internal.message_test.isnan
def isnan(val)
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:65
absl::SimpleAtof
ABSL_NAMESPACE_BEGIN bool SimpleAtof(absl::string_view str, float *out)
Definition: abseil-cpp/absl/strings/numbers.cc:46
exponent
int exponent
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1100
absl::strings_internal::strtouint32_test_cases
const std::array< uint32_test_case, 27 > & strtouint32_test_cases()
Definition: abseil-cpp/absl/strings/internal/numbers_test_common.h:69
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::strings_internal::Itoa
bool Itoa(IntType value, int base, std::string *destination)
Definition: abseil-cpp/absl/strings/internal/numbers_test_common.h:33
status
absl::Status status
Definition: rls.cc:251
absl::strings_internal::OStringStream
Definition: abseil-cpp/absl/strings/internal/ostringstream.h:63
absl::numbers_internal::SixDigitsToBuffer
size_t SixDigitsToBuffer(double d, char *buffer)
Definition: abseil-cpp/absl/strings/numbers.cc:486
absl::FormatConversionChar::s
@ s
xds_manager.p
p
Definition: xds_manager.py:60
testing::MatchesRegex
PolymorphicMatcher< internal::MatchesRegexMatcher > MatchesRegex(const internal::RE *regex)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8824
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
std::numeric_limits< absl::int128 >::max
static constexpr absl::int128() max()
Definition: abseil-cpp/absl/numeric/int128.h:526
absl::kZeroPad16
@ kZeroPad16
Definition: abseil-cpp/absl/strings/str_cat.h:101
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
grpc::operator>=
bool operator>=(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:143
absl::numbers_internal::safe_strto32_base
bool safe_strto32_base(absl::string_view text, int32_t *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1067
absl::strings_internal::strtouint64_test_cases
const std::array< uint64_test_case, 34 > & strtouint64_test_cases()
Definition: abseil-cpp/absl/strings/internal/numbers_test_common.h:117
testing::Test::TearDown
virtual void TearDown()
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:2270
grpc::operator<
bool operator<(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:140
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
before
IntBeforeRegisterTypedTestSuiteP before
Definition: googletest/googletest/test/gtest-typed-test_test.cc:376
grpc_core::operator-
Duration operator-(Duration lhs, Duration rhs)
Definition: src/core/lib/gprpp/time.h:234
ULL
#define ULL(x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:57
grpc::operator<=
bool operator<=(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:141
absl::SimpleAtoi
ABSL_NAMESPACE_BEGIN ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type *out)
Definition: abseil-cpp/absl/strings/numbers.h:271
absl::Hex
Definition: abseil-cpp/absl/strings/str_cat.h:134
absl::FormatConversionChar::e
@ e
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
std::numeric_limits< absl::uint128 >::max
static constexpr absl::uint128() max()
Definition: abseil-cpp/absl/numeric/int128.h:291
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
ToString
std::string ToString(const grpc::string_ref &r)
Definition: string_ref_helper.cc:24
absl::int128
Definition: abseil-cpp/absl/numeric/int128.h:338
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
b2
T::second_type b2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:308
python_utils.jobset.INFO
INFO
Definition: jobset.py:111
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
testing::Eq
internal::EqMatcher< T > Eq(T x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8561
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
grpc::operator>
bool operator>(string_ref x, string_ref y)
Definition: grpcpp/impl/codegen/string_ref.h:142
test_count
int test_count
Definition: bloaty/third_party/protobuf/conformance/conformance_cpp.cc:69
operator!=
bool operator!=(const Bytes &a, const Bytes &b)
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:58
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
absl::SimpleAtod
bool SimpleAtod(absl::string_view str, double *out)
Definition: abseil-cpp/absl/strings/numbers.cc:77
min
#define min(a, b)
Definition: qsort.h:83
mantissa
MantissaType mantissa
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1098
absl::numbers_internal::safe_strtou32_base
bool safe_strtou32_base(absl::string_view text, uint32_t *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1079
d
static const fe d
Definition: curve25519_tables.h:19
RandomEngine
std::mt19937_64 RandomEngine
Definition: abseil-cpp/absl/strings/cord_test.cc:50
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
after
IntAfterTypedTestSuiteP after
Definition: googletest/googletest/test/gtest-typed-test_test.cc:375
value
const char * value
Definition: hpack_parser_table.cc:165
testing::Test::SetUp
virtual void SetUp()
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:2264
b1
T::second_type b1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:306
INT32_MIN
#define INT32_MIN
Definition: stdint-msvc2008.h:136
absl::numbers_internal::safe_strto128_base
bool safe_strto128_base(absl::string_view text, int128 *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1075
grpc_core::operator*
Duration operator*(Duration lhs, double rhs)
Definition: src/core/lib/gprpp/time.h:257
std::numeric_limits< absl::int128 >::min
static constexpr absl::int128() min()
Definition: abseil-cpp/absl/numeric/int128.h:524
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >
step
static int step
Definition: test-mutexes.c:31
xds_manager.num
num
Definition: xds_manager.py:56
regen-readme.line
line
Definition: regen-readme.py:30
absl::numbers_internal::safe_strto64_base
bool safe_strto64_base(absl::string_view text, int64_t *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1071
absl::LogUniform
IntType LogUniform(URBG &&urbg, IntType lo, IntType hi, IntType base=2)
Definition: abseil-cpp/absl/random/distributions.h:374
buf2
static char buf2[32]
Definition: test-fs.c:127
absl::numbers_internal::kFastToBufferSize
static const int kFastToBufferSize
Definition: abseil-cpp/absl/strings/numbers.h:153
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
absl::numbers_internal::safe_strtou128_base
bool safe_strtou128_base(absl::string_view text, uint128 *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1087
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
EXPECT_DOUBLE_EQ
#define EXPECT_DOUBLE_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:28
absl::numbers_internal::kSixDigitsToBufferSize
static const int kSixDigitsToBufferSize
Definition: abseil-cpp/absl/strings/numbers.h:154
absl::kSpacePad16
@ kSpacePad16
Definition: abseil-cpp/absl/strings/str_cat.h:121
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
absl::numbers_internal::FastIntToBuffer
char * FastIntToBuffer(int32_t, char *)
Definition: abseil-cpp/absl/strings/numbers.cc:217
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
absl::MakeInt128
constexpr int128 MakeInt128(int64_t high, uint64_t low)
Definition: abseil-cpp/absl/numeric/int128.h:1040
ABSL_RAW_LOG
#define ABSL_RAW_LOG(severity,...)
Definition: abseil-cpp/absl/base/internal/raw_logging.h:44
absl::strings_internal::Pow10
double Pow10(int exp)
Definition: abseil-cpp/absl/strings/internal/pow10_helper.cc:110
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::uint128
Definition: abseil-cpp/absl/numeric/int128.h:104
TEST_F
#define TEST_F(test_fixture, test_name)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2367
grpc_core::operator/
Duration operator/(Duration lhs, int64_t rhs)
Definition: src/core/lib/gprpp/time.h:269
absl::numbers_internal::safe_strtou64_base
bool safe_strtou64_base(absl::string_view text, uint64_t *value, int base)
Definition: abseil-cpp/absl/strings/numbers.cc:1083


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:33