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 #include <cfenv> // NOLINT(build/c++11)
21 #include <cinttypes>
22 #include <climits>
23 #include <cmath>
24 #include <cstddef>
25 #include <cstdint>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cstring>
29 #include <limits>
30 #include <numeric>
31 #include <random>
32 #include <set>
33 #include <string>
34 #include <vector>
35 
36 #include "gmock/gmock.h"
37 #include "gtest/gtest.h"
39 #include "absl/strings/str_cat.h"
40 
43 
44 namespace {
45 
55 using absl::SimpleAtoi;
56 using testing::Eq;
57 using testing::MatchesRegex;
58 
59 // Number of floats to test with.
60 // 5,000,000 is a reasonable default for a test that only takes a few seconds.
61 // 1,000,000,000+ triggers checking for all possible mantissa values for
62 // double-precision tests. 2,000,000,000+ triggers checking for every possible
63 // single-precision float.
64 const int kFloatNumCases = 5000000;
65 
66 // This is a slow, brute-force routine to compute the exact base-10
67 // representation of a double-precision floating-point number. It
68 // is useful for debugging only.
69 std::string PerfectDtoa(double d) {
70  if (d == 0) return "0";
71  if (d < 0) return "-" + PerfectDtoa(-d);
72 
73  // Basic theory: decompose d into mantissa and exp, where
74  // d = mantissa * 2^exp, and exp is as close to zero as possible.
75  int64_t mantissa, exp = 0;
76  while (d >= 1ULL << 63) ++exp, d *= 0.5;
77  while ((mantissa = d) != d) --exp, d *= 2.0;
78 
79  // Then convert mantissa to ASCII, and either double it (if
80  // exp > 0) or halve it (if exp < 0) repeatedly. "halve it"
81  // in this case means multiplying it by five and dividing by 10.
82  constexpr int maxlen = 1100; // worst case is actually 1030 or so.
83  char buf[maxlen + 5];
84  for (int64_t num = mantissa, pos = maxlen; --pos >= 0;) {
85  buf[pos] = '0' + (num % 10);
86  num /= 10;
87  }
88  char* begin = &buf[0];
89  char* end = buf + maxlen;
90  for (int i = 0; i != exp; i += (exp > 0) ? 1 : -1) {
91  int carry = 0;
92  for (char* p = end; --p != begin;) {
93  int dig = *p - '0';
94  dig = dig * (exp > 0 ? 2 : 5) + carry;
95  carry = dig / 10;
96  dig %= 10;
97  *p = '0' + dig;
98  }
99  }
100  if (exp < 0) {
101  // "dividing by 10" above means we have to add the decimal point.
102  memmove(end + 1 + exp, end + exp, 1 - exp);
103  end[exp] = '.';
104  ++end;
105  }
106  while (*begin == '0' && begin[1] != '.') ++begin;
107  return {begin, end};
108 }
109 
110 TEST(ToString, PerfectDtoa) {
111  EXPECT_THAT(PerfectDtoa(1), Eq("1"));
112  EXPECT_THAT(PerfectDtoa(0.1),
113  Eq("0.1000000000000000055511151231257827021181583404541015625"));
114  EXPECT_THAT(PerfectDtoa(1e24), Eq("999999999999999983222784"));
115  EXPECT_THAT(PerfectDtoa(5e-324), MatchesRegex("0.0000.*625"));
116  for (int i = 0; i < 100; ++i) {
117  for (double multiplier :
118  {1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) {
119  double d = multiplier * i;
120  std::string s = PerfectDtoa(d);
121  EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr));
122  }
123  }
124 }
125 
126 template <typename integer>
127 struct MyInteger {
128  integer i;
129  explicit constexpr MyInteger(integer i) : i(i) {}
130  constexpr operator integer() const { return i; }
131 
132  constexpr MyInteger operator+(MyInteger other) const { return i + other.i; }
133  constexpr MyInteger operator-(MyInteger other) const { return i - other.i; }
134  constexpr MyInteger operator*(MyInteger other) const { return i * other.i; }
135  constexpr MyInteger operator/(MyInteger other) const { return i / other.i; }
136 
137  constexpr bool operator<(MyInteger other) const { return i < other.i; }
138  constexpr bool operator<=(MyInteger other) const { return i <= other.i; }
139  constexpr bool operator==(MyInteger other) const { return i == other.i; }
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 
144  integer as_integer() const { return i; }
145 };
146 
147 typedef MyInteger<int64_t> MyInt64;
148 typedef MyInteger<uint64_t> MyUInt64;
149 
150 void CheckInt32(int32_t x) {
152  char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
153  std::string expected = std::to_string(x);
154  EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
155 
156  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
157  EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
158 }
159 
160 void CheckInt64(int64_t x) {
162  buffer[0] = '*';
163  buffer[23] = '*';
164  buffer[24] = '*';
165  char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
166  std::string expected = std::to_string(x);
167  EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
168  EXPECT_EQ(buffer[0], '*');
169  EXPECT_EQ(buffer[23], '*');
170  EXPECT_EQ(buffer[24], '*');
171 
172  char* my_actual =
173  absl::numbers_internal::FastIntToBuffer(MyInt64(x), &buffer[1]);
174  EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
175 }
176 
177 void CheckUInt32(uint32_t x) {
179  char* actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
180  std::string expected = std::to_string(x);
181  EXPECT_EQ(expected, std::string(buffer, actual)) << " Input " << x;
182 
183  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, buffer);
184  EXPECT_EQ(expected, std::string(buffer, generic_actual)) << " Input " << x;
185 }
186 
187 void CheckUInt64(uint64_t x) {
189  char* actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
190  std::string expected = std::to_string(x);
191  EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
192 
193  char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
194  EXPECT_EQ(expected, std::string(&buffer[1], generic_actual))
195  << " Input " << x;
196 
197  char* my_actual =
198  absl::numbers_internal::FastIntToBuffer(MyUInt64(x), &buffer[1]);
199  EXPECT_EQ(expected, std::string(&buffer[1], my_actual)) << " Input " << x;
200 }
201 
202 void CheckHex64(uint64_t v) {
203  char expected[16 + 1];
204  std::string actual = absl::StrCat(absl::Hex(v, absl::kZeroPad16));
205  snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast<uint64_t>(v));
206  EXPECT_EQ(expected, actual) << " Input " << v;
207 }
208 
209 TEST(Numbers, TestFastPrints) {
210  for (int i = -100; i <= 100; i++) {
211  CheckInt32(i);
212  CheckInt64(i);
213  }
214  for (int i = 0; i <= 100; i++) {
215  CheckUInt32(i);
216  CheckUInt64(i);
217  }
218  // Test min int to make sure that works
219  CheckInt32(INT_MIN);
220  CheckInt32(INT_MAX);
221  CheckInt64(LONG_MIN);
222  CheckInt64(uint64_t{1000000000});
223  CheckInt64(uint64_t{9999999999});
224  CheckInt64(uint64_t{100000000000000});
225  CheckInt64(uint64_t{999999999999999});
226  CheckInt64(uint64_t{1000000000000000000});
227  CheckInt64(uint64_t{1199999999999999999});
228  CheckInt64(int64_t{-700000000000000000});
229  CheckInt64(LONG_MAX);
230  CheckUInt32(std::numeric_limits<uint32_t>::max());
231  CheckUInt64(uint64_t{1000000000});
232  CheckUInt64(uint64_t{9999999999});
233  CheckUInt64(uint64_t{100000000000000});
234  CheckUInt64(uint64_t{999999999999999});
235  CheckUInt64(uint64_t{1000000000000000000});
236  CheckUInt64(uint64_t{1199999999999999999});
237  CheckUInt64(std::numeric_limits<uint64_t>::max());
238 
239  for (int i = 0; i < 10000; i++) {
240  CheckHex64(i);
241  }
242  CheckHex64(uint64_t{0x123456789abcdef0});
243 }
244 
245 template <typename int_type, typename in_val_type>
246 void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) {
247  std::string s = absl::StrCat(in_value);
248  int_type x = static_cast<int_type>(~exp_value);
249  EXPECT_TRUE(SimpleAtoi(s, &x))
250  << "in_value=" << in_value << " s=" << s << " x=" << x;
251  EXPECT_EQ(exp_value, x);
252  x = static_cast<int_type>(~exp_value);
253  EXPECT_TRUE(SimpleAtoi(s.c_str(), &x));
254  EXPECT_EQ(exp_value, x);
255 }
256 
257 template <typename int_type, typename in_val_type>
258 void VerifySimpleAtoiBad(in_val_type in_value) {
259  std::string s = absl::StrCat(in_value);
260  int_type x;
261  EXPECT_FALSE(SimpleAtoi(s, &x));
262  EXPECT_FALSE(SimpleAtoi(s.c_str(), &x));
263 }
264 
265 TEST(NumbersTest, Atoi) {
266  // SimpleAtoi(absl::string_view, int32_t)
267  VerifySimpleAtoiGood<int32_t>(0, 0);
268  VerifySimpleAtoiGood<int32_t>(42, 42);
269  VerifySimpleAtoiGood<int32_t>(-42, -42);
270 
271  VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::min(),
272  std::numeric_limits<int32_t>::min());
273  VerifySimpleAtoiGood<int32_t>(std::numeric_limits<int32_t>::max(),
274  std::numeric_limits<int32_t>::max());
275 
276  // SimpleAtoi(absl::string_view, uint32_t)
277  VerifySimpleAtoiGood<uint32_t>(0, 0);
278  VerifySimpleAtoiGood<uint32_t>(42, 42);
279  VerifySimpleAtoiBad<uint32_t>(-42);
280 
281  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int32_t>::min());
282  VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<int32_t>::max(),
283  std::numeric_limits<int32_t>::max());
284  VerifySimpleAtoiGood<uint32_t>(std::numeric_limits<uint32_t>::max(),
285  std::numeric_limits<uint32_t>::max());
286  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::min());
287  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<int64_t>::max());
288  VerifySimpleAtoiBad<uint32_t>(std::numeric_limits<uint64_t>::max());
289 
290  // SimpleAtoi(absl::string_view, int64_t)
291  VerifySimpleAtoiGood<int64_t>(0, 0);
292  VerifySimpleAtoiGood<int64_t>(42, 42);
293  VerifySimpleAtoiGood<int64_t>(-42, -42);
294 
295  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::min(),
296  std::numeric_limits<int32_t>::min());
297  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int32_t>::max(),
298  std::numeric_limits<int32_t>::max());
299  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<uint32_t>::max(),
300  std::numeric_limits<uint32_t>::max());
301  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::min(),
302  std::numeric_limits<int64_t>::min());
303  VerifySimpleAtoiGood<int64_t>(std::numeric_limits<int64_t>::max(),
304  std::numeric_limits<int64_t>::max());
305  VerifySimpleAtoiBad<int64_t>(std::numeric_limits<uint64_t>::max());
306 
307  // SimpleAtoi(absl::string_view, uint64_t)
308  VerifySimpleAtoiGood<uint64_t>(0, 0);
309  VerifySimpleAtoiGood<uint64_t>(42, 42);
310  VerifySimpleAtoiBad<uint64_t>(-42);
311 
312  VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int32_t>::min());
313  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int32_t>::max(),
314  std::numeric_limits<int32_t>::max());
315  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint32_t>::max(),
316  std::numeric_limits<uint32_t>::max());
317  VerifySimpleAtoiBad<uint64_t>(std::numeric_limits<int64_t>::min());
318  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<int64_t>::max(),
319  std::numeric_limits<int64_t>::max());
320  VerifySimpleAtoiGood<uint64_t>(std::numeric_limits<uint64_t>::max(),
321  std::numeric_limits<uint64_t>::max());
322 
323  // Some other types
324  VerifySimpleAtoiGood<int>(-42, -42);
325  VerifySimpleAtoiGood<int32_t>(-42, -42);
326  VerifySimpleAtoiGood<uint32_t>(42, 42);
327  VerifySimpleAtoiGood<unsigned int>(42, 42);
328  VerifySimpleAtoiGood<int64_t>(-42, -42);
329  VerifySimpleAtoiGood<long>(-42, -42); // NOLINT(runtime/int)
330  VerifySimpleAtoiGood<uint64_t>(42, 42);
331  VerifySimpleAtoiGood<size_t>(42, 42);
332  VerifySimpleAtoiGood<std::string::size_type>(42, 42);
333 }
334 
335 TEST(NumbersTest, Atoenum) {
336  enum E01 {
337  E01_zero = 0,
338  E01_one = 1,
339  };
340 
341  VerifySimpleAtoiGood<E01>(E01_zero, E01_zero);
342  VerifySimpleAtoiGood<E01>(E01_one, E01_one);
343 
344  enum E_101 {
345  E_101_minusone = -1,
346  E_101_zero = 0,
347  E_101_one = 1,
348  };
349 
350  VerifySimpleAtoiGood<E_101>(E_101_minusone, E_101_minusone);
351  VerifySimpleAtoiGood<E_101>(E_101_zero, E_101_zero);
352  VerifySimpleAtoiGood<E_101>(E_101_one, E_101_one);
353 
354  enum E_bigint {
355  E_bigint_zero = 0,
356  E_bigint_one = 1,
357  E_bigint_max31 = static_cast<int32_t>(0x7FFFFFFF),
358  };
359 
360  VerifySimpleAtoiGood<E_bigint>(E_bigint_zero, E_bigint_zero);
361  VerifySimpleAtoiGood<E_bigint>(E_bigint_one, E_bigint_one);
362  VerifySimpleAtoiGood<E_bigint>(E_bigint_max31, E_bigint_max31);
363 
364  enum E_fullint {
365  E_fullint_zero = 0,
366  E_fullint_one = 1,
367  E_fullint_max31 = static_cast<int32_t>(0x7FFFFFFF),
368  E_fullint_min32 = INT32_MIN,
369  };
370 
371  VerifySimpleAtoiGood<E_fullint>(E_fullint_zero, E_fullint_zero);
372  VerifySimpleAtoiGood<E_fullint>(E_fullint_one, E_fullint_one);
373  VerifySimpleAtoiGood<E_fullint>(E_fullint_max31, E_fullint_max31);
374  VerifySimpleAtoiGood<E_fullint>(E_fullint_min32, E_fullint_min32);
375 
376  enum E_biguint {
377  E_biguint_zero = 0,
378  E_biguint_one = 1,
379  E_biguint_max31 = static_cast<uint32_t>(0x7FFFFFFF),
380  E_biguint_max32 = static_cast<uint32_t>(0xFFFFFFFF),
381  };
382 
383  VerifySimpleAtoiGood<E_biguint>(E_biguint_zero, E_biguint_zero);
384  VerifySimpleAtoiGood<E_biguint>(E_biguint_one, E_biguint_one);
385  VerifySimpleAtoiGood<E_biguint>(E_biguint_max31, E_biguint_max31);
386  VerifySimpleAtoiGood<E_biguint>(E_biguint_max32, E_biguint_max32);
387 }
388 
389 TEST(stringtest, safe_strto32_base) {
390  int32_t value;
391  EXPECT_TRUE(safe_strto32_base("0x34234324", &value, 16));
392  EXPECT_EQ(0x34234324, value);
393 
394  EXPECT_TRUE(safe_strto32_base("0X34234324", &value, 16));
395  EXPECT_EQ(0x34234324, value);
396 
397  EXPECT_TRUE(safe_strto32_base("34234324", &value, 16));
398  EXPECT_EQ(0x34234324, value);
399 
400  EXPECT_TRUE(safe_strto32_base("0", &value, 16));
401  EXPECT_EQ(0, value);
402 
403  EXPECT_TRUE(safe_strto32_base(" \t\n -0x34234324", &value, 16));
404  EXPECT_EQ(-0x34234324, value);
405 
406  EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 16));
407  EXPECT_EQ(-0x34234324, value);
408 
409  EXPECT_TRUE(safe_strto32_base("7654321", &value, 8));
410  EXPECT_EQ(07654321, value);
411 
412  EXPECT_TRUE(safe_strto32_base("-01234", &value, 8));
413  EXPECT_EQ(-01234, value);
414 
415  EXPECT_FALSE(safe_strto32_base("1834", &value, 8));
416 
417  // Autodetect base.
418  EXPECT_TRUE(safe_strto32_base("0", &value, 0));
419  EXPECT_EQ(0, value);
420 
421  EXPECT_TRUE(safe_strto32_base("077", &value, 0));
422  EXPECT_EQ(077, value); // Octal interpretation
423 
424  // Leading zero indicates octal, but then followed by invalid digit.
425  EXPECT_FALSE(safe_strto32_base("088", &value, 0));
426 
427  // Leading 0x indicated hex, but then followed by invalid digit.
428  EXPECT_FALSE(safe_strto32_base("0xG", &value, 0));
429 
430  // Base-10 version.
431  EXPECT_TRUE(safe_strto32_base("34234324", &value, 10));
432  EXPECT_EQ(34234324, value);
433 
434  EXPECT_TRUE(safe_strto32_base("0", &value, 10));
435  EXPECT_EQ(0, value);
436 
437  EXPECT_TRUE(safe_strto32_base(" \t\n -34234324", &value, 10));
438  EXPECT_EQ(-34234324, value);
439 
440  EXPECT_TRUE(safe_strto32_base("34234324 \n\t ", &value, 10));
441  EXPECT_EQ(34234324, value);
442 
443  // Invalid ints.
444  EXPECT_FALSE(safe_strto32_base("", &value, 10));
445  EXPECT_FALSE(safe_strto32_base(" ", &value, 10));
446  EXPECT_FALSE(safe_strto32_base("abc", &value, 10));
447  EXPECT_FALSE(safe_strto32_base("34234324a", &value, 10));
448  EXPECT_FALSE(safe_strto32_base("34234.3", &value, 10));
449 
450  // Out of bounds.
451  EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
452  EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
453 
454  // String version.
455  EXPECT_TRUE(safe_strto32_base(std::string("0x1234"), &value, 16));
456  EXPECT_EQ(0x1234, value);
457 
458  // Base-10 std::string version.
459  EXPECT_TRUE(safe_strto32_base("1234", &value, 10));
460  EXPECT_EQ(1234, value);
461 }
462 
463 TEST(stringtest, safe_strto32_range) {
464  // These tests verify underflow/overflow behaviour.
465  int32_t value;
466  EXPECT_FALSE(safe_strto32_base("2147483648", &value, 10));
467  EXPECT_EQ(std::numeric_limits<int32_t>::max(), value);
468 
469  EXPECT_TRUE(safe_strto32_base("-2147483648", &value, 10));
470  EXPECT_EQ(std::numeric_limits<int32_t>::min(), value);
471 
472  EXPECT_FALSE(safe_strto32_base("-2147483649", &value, 10));
473  EXPECT_EQ(std::numeric_limits<int32_t>::min(), value);
474 }
475 
476 TEST(stringtest, safe_strto64_range) {
477  // These tests verify underflow/overflow behaviour.
478  int64_t value;
479  EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
480  EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
481 
482  EXPECT_TRUE(safe_strto64_base("-9223372036854775808", &value, 10));
483  EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
484 
485  EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
486  EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
487 }
488 
489 TEST(stringtest, safe_strto32_leading_substring) {
490  // These tests verify this comment in numbers.h:
491  // On error, returns false, and sets *value to: [...]
492  // conversion of leading substring if available ("123@@@" -> 123)
493  // 0 if no leading substring available
494  int32_t value;
495  EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 10));
496  EXPECT_EQ(4069, value);
497 
498  EXPECT_FALSE(safe_strto32_base("04069@@@", &value, 8));
499  EXPECT_EQ(0406, value);
500 
501  EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 10));
502  EXPECT_EQ(4069, value);
503 
504  EXPECT_FALSE(safe_strto32_base("04069balloons", &value, 16));
505  EXPECT_EQ(0x4069ba, value);
506 
507  EXPECT_FALSE(safe_strto32_base("@@@", &value, 10));
508  EXPECT_EQ(0, value); // there was no leading substring
509 }
510 
511 TEST(stringtest, safe_strto64_leading_substring) {
512  // These tests verify this comment in numbers.h:
513  // On error, returns false, and sets *value to: [...]
514  // conversion of leading substring if available ("123@@@" -> 123)
515  // 0 if no leading substring available
516  int64_t value;
517  EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 10));
518  EXPECT_EQ(4069, value);
519 
520  EXPECT_FALSE(safe_strto64_base("04069@@@", &value, 8));
521  EXPECT_EQ(0406, value);
522 
523  EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 10));
524  EXPECT_EQ(4069, value);
525 
526  EXPECT_FALSE(safe_strto64_base("04069balloons", &value, 16));
527  EXPECT_EQ(0x4069ba, value);
528 
529  EXPECT_FALSE(safe_strto64_base("@@@", &value, 10));
530  EXPECT_EQ(0, value); // there was no leading substring
531 }
532 
533 TEST(stringtest, safe_strto64_base) {
534  int64_t value;
535  EXPECT_TRUE(safe_strto64_base("0x3423432448783446", &value, 16));
536  EXPECT_EQ(int64_t{0x3423432448783446}, value);
537 
538  EXPECT_TRUE(safe_strto64_base("3423432448783446", &value, 16));
539  EXPECT_EQ(int64_t{0x3423432448783446}, value);
540 
541  EXPECT_TRUE(safe_strto64_base("0", &value, 16));
542  EXPECT_EQ(0, value);
543 
544  EXPECT_TRUE(safe_strto64_base(" \t\n -0x3423432448783446", &value, 16));
545  EXPECT_EQ(int64_t{-0x3423432448783446}, value);
546 
547  EXPECT_TRUE(safe_strto64_base(" \t\n -3423432448783446", &value, 16));
548  EXPECT_EQ(int64_t{-0x3423432448783446}, value);
549 
550  EXPECT_TRUE(safe_strto64_base("123456701234567012", &value, 8));
551  EXPECT_EQ(int64_t{0123456701234567012}, value);
552 
553  EXPECT_TRUE(safe_strto64_base("-017777777777777", &value, 8));
554  EXPECT_EQ(int64_t{-017777777777777}, value);
555 
556  EXPECT_FALSE(safe_strto64_base("19777777777777", &value, 8));
557 
558  // Autodetect base.
559  EXPECT_TRUE(safe_strto64_base("0", &value, 0));
560  EXPECT_EQ(0, value);
561 
562  EXPECT_TRUE(safe_strto64_base("077", &value, 0));
563  EXPECT_EQ(077, value); // Octal interpretation
564 
565  // Leading zero indicates octal, but then followed by invalid digit.
566  EXPECT_FALSE(safe_strto64_base("088", &value, 0));
567 
568  // Leading 0x indicated hex, but then followed by invalid digit.
569  EXPECT_FALSE(safe_strto64_base("0xG", &value, 0));
570 
571  // Base-10 version.
572  EXPECT_TRUE(safe_strto64_base("34234324487834466", &value, 10));
573  EXPECT_EQ(int64_t{34234324487834466}, value);
574 
575  EXPECT_TRUE(safe_strto64_base("0", &value, 10));
576  EXPECT_EQ(0, value);
577 
578  EXPECT_TRUE(safe_strto64_base(" \t\n -34234324487834466", &value, 10));
579  EXPECT_EQ(int64_t{-34234324487834466}, value);
580 
581  EXPECT_TRUE(safe_strto64_base("34234324487834466 \n\t ", &value, 10));
582  EXPECT_EQ(int64_t{34234324487834466}, value);
583 
584  // Invalid ints.
585  EXPECT_FALSE(safe_strto64_base("", &value, 10));
586  EXPECT_FALSE(safe_strto64_base(" ", &value, 10));
587  EXPECT_FALSE(safe_strto64_base("abc", &value, 10));
588  EXPECT_FALSE(safe_strto64_base("34234324487834466a", &value, 10));
589  EXPECT_FALSE(safe_strto64_base("34234487834466.3", &value, 10));
590 
591  // Out of bounds.
592  EXPECT_FALSE(safe_strto64_base("9223372036854775808", &value, 10));
593  EXPECT_FALSE(safe_strto64_base("-9223372036854775809", &value, 10));
594 
595  // String version.
596  EXPECT_TRUE(safe_strto64_base(std::string("0x1234"), &value, 16));
597  EXPECT_EQ(0x1234, value);
598 
599  // Base-10 std::string version.
600  EXPECT_TRUE(safe_strto64_base("1234", &value, 10));
601  EXPECT_EQ(1234, value);
602 }
603 
604 const size_t kNumRandomTests = 10000;
605 
606 template <typename IntType>
607 void test_random_integer_parse_base(bool (*parse_func)(absl::string_view,
608  IntType* value,
609  int base)) {
610  using RandomEngine = std::minstd_rand0;
611  std::random_device rd;
612  RandomEngine rng(rd());
613  std::uniform_int_distribution<IntType> random_int(
614  std::numeric_limits<IntType>::min());
615  std::uniform_int_distribution<int> random_base(2, 35);
616  for (size_t i = 0; i < kNumRandomTests; i++) {
617  IntType value = random_int(rng);
618  int base = random_base(rng);
619  std::string str_value;
620  EXPECT_TRUE(Itoa<IntType>(value, base, &str_value));
621  IntType parsed_value;
622 
623  // Test successful parse
624  EXPECT_TRUE(parse_func(str_value, &parsed_value, base));
625  EXPECT_EQ(parsed_value, value);
626 
627  // Test overflow
628  EXPECT_FALSE(
629  parse_func(absl::StrCat(std::numeric_limits<IntType>::max(), value),
630  &parsed_value, base));
631 
632  // Test underflow
633  if (std::numeric_limits<IntType>::min() < 0) {
634  EXPECT_FALSE(
635  parse_func(absl::StrCat(std::numeric_limits<IntType>::min(), value),
636  &parsed_value, base));
637  } else {
638  EXPECT_FALSE(parse_func(absl::StrCat("-", value), &parsed_value, base));
639  }
640  }
641 }
642 
643 TEST(stringtest, safe_strto32_random) {
644  test_random_integer_parse_base<int32_t>(&safe_strto32_base);
645 }
646 TEST(stringtest, safe_strto64_random) {
647  test_random_integer_parse_base<int64_t>(&safe_strto64_base);
648 }
649 TEST(stringtest, safe_strtou32_random) {
650  test_random_integer_parse_base<uint32_t>(&safe_strtou32_base);
651 }
652 TEST(stringtest, safe_strtou64_random) {
653  test_random_integer_parse_base<uint64_t>(&safe_strtou64_base);
654 }
655 
656 TEST(stringtest, safe_strtou32_base) {
657  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
658  const auto& e = strtouint32_test_cases()[i];
659  uint32_t value;
660  EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
661  << "str=\"" << e.str << "\" base=" << e.base;
662  if (e.expect_ok) {
663  EXPECT_EQ(e.expected, value) << "i=" << i << " str=\"" << e.str
664  << "\" base=" << e.base;
665  }
666  }
667 }
668 
669 TEST(stringtest, safe_strtou32_base_length_delimited) {
670  for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
671  const auto& e = strtouint32_test_cases()[i];
672  std::string tmp(e.str);
673  tmp.append("12"); // Adds garbage at the end.
674 
675  uint32_t value;
676  EXPECT_EQ(e.expect_ok,
677  safe_strtou32_base(absl::string_view(tmp.data(), strlen(e.str)),
678  &value, e.base))
679  << "str=\"" << e.str << "\" base=" << e.base;
680  if (e.expect_ok) {
681  EXPECT_EQ(e.expected, value) << "i=" << i << " str=" << e.str
682  << " base=" << e.base;
683  }
684  }
685 }
686 
687 TEST(stringtest, safe_strtou64_base) {
688  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
689  const auto& e = strtouint64_test_cases()[i];
690  uint64_t value;
691  EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
692  << "str=\"" << e.str << "\" base=" << e.base;
693  if (e.expect_ok) {
694  EXPECT_EQ(e.expected, value) << "str=" << e.str << " base=" << e.base;
695  }
696  }
697 }
698 
699 TEST(stringtest, safe_strtou64_base_length_delimited) {
700  for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
701  const auto& e = strtouint64_test_cases()[i];
702  std::string tmp(e.str);
703  tmp.append("12"); // Adds garbage at the end.
704 
705  uint64_t value;
706  EXPECT_EQ(e.expect_ok,
707  safe_strtou64_base(absl::string_view(tmp.data(), strlen(e.str)),
708  &value, e.base))
709  << "str=\"" << e.str << "\" base=" << e.base;
710  if (e.expect_ok) {
711  EXPECT_EQ(e.expected, value) << "str=\"" << e.str << "\" base=" << e.base;
712  }
713  }
714 }
715 
716 // feenableexcept() and fedisableexcept() are missing on Mac OS X, MSVC,
717 // and WebAssembly.
718 #if defined(_MSC_VER) || defined(__APPLE__) || defined(__EMSCRIPTEN__)
719 #define ABSL_MISSING_FEENABLEEXCEPT 1
720 #define ABSL_MISSING_FEDISABLEEXCEPT 1
721 #endif
722 
723 class SimpleDtoaTest : public testing::Test {
724  protected:
725  void SetUp() override {
726  // Store the current floating point env & clear away any pending exceptions.
727  feholdexcept(&fp_env_);
728 #ifndef ABSL_MISSING_FEENABLEEXCEPT
729  // Turn on floating point exceptions.
730  feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
731 #endif
732  }
733 
734  void TearDown() override {
735  // Restore the floating point environment to the original state.
736  // In theory fedisableexcept is unnecessary; fesetenv will also do it.
737  // In practice, our toolchains have subtle bugs.
738 #ifndef ABSL_MISSING_FEDISABLEEXCEPT
739  fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
740 #endif
741  fesetenv(&fp_env_);
742  }
743 
744  std::string ToNineDigits(double value) {
745  char buffer[16]; // more than enough for %.9g
746  snprintf(buffer, sizeof(buffer), "%.9g", value);
747  return buffer;
748  }
749 
750  fenv_t fp_env_;
751 };
752 
753 // Run the given runnable functor for "cases" test cases, chosen over the
754 // available range of float. pi and e and 1/e are seeded, and then all
755 // available integer powers of 2 and 10 are multiplied against them. In
756 // addition to trying all those values, we try the next higher and next lower
757 // float, and then we add additional test cases evenly distributed between them.
758 // Each test case is passed to runnable as both a positive and negative value.
759 template <typename R>
760 void ExhaustiveFloat(uint32_t cases, R&& runnable) {
761  runnable(0.0f);
762  runnable(-0.0f);
763  if (cases >= 2e9) { // more than 2 billion? Might as well run them all.
764  for (float f = 0; f < std::numeric_limits<float>::max(); ) {
765  f = nextafterf(f, std::numeric_limits<float>::max());
766  runnable(-f);
767  runnable(f);
768  }
769  return;
770  }
771  std::set<float> floats = {3.4028234e38f};
772  for (float f : {1.0, 3.14159265, 2.718281828, 1 / 2.718281828}) {
773  for (float testf = f; testf != 0; testf *= 0.1f) floats.insert(testf);
774  for (float testf = f; testf != 0; testf *= 0.5f) floats.insert(testf);
775  for (float testf = f; testf < 3e38f / 2; testf *= 2.0f)
776  floats.insert(testf);
777  for (float testf = f; testf < 3e38f / 10; testf *= 10) floats.insert(testf);
778  }
779 
780  float last = *floats.begin();
781 
782  runnable(last);
783  runnable(-last);
784  int iters_per_float = cases / floats.size();
785  if (iters_per_float == 0) iters_per_float = 1;
786  for (float f : floats) {
787  if (f == last) continue;
788  float testf = std::nextafter(last, std::numeric_limits<float>::max());
789  runnable(testf);
790  runnable(-testf);
791  last = testf;
792  if (f == last) continue;
793  double step = (double{f} - last) / iters_per_float;
794  for (double d = last + step; d < f; d += step) {
795  testf = d;
796  if (testf != last) {
797  runnable(testf);
798  runnable(-testf);
799  last = testf;
800  }
801  }
802  testf = std::nextafter(f, 0.0f);
803  if (testf > last) {
804  runnable(testf);
805  runnable(-testf);
806  last = testf;
807  }
808  if (f != last) {
809  runnable(f);
810  runnable(-f);
811  last = f;
812  }
813  }
814 }
815 
816 TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
817  uint64_t test_count = 0;
818  std::vector<double> mismatches;
819  auto checker = [&](double d) {
820  if (d != d) return; // rule out NaNs
821  ++test_count;
822  char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
823  SixDigitsToBuffer(d, sixdigitsbuf);
824  char snprintfbuf[kSixDigitsToBufferSize] = {0};
825  snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
826  if (strcmp(sixdigitsbuf, snprintfbuf) != 0) {
827  mismatches.push_back(d);
828  if (mismatches.size() < 10) {
829  ABSL_RAW_LOG(ERROR, "%s",
830  absl::StrCat("Six-digit failure with double. ", "d=", d,
831  "=", d, " sixdigits=", sixdigitsbuf,
832  " printf(%g)=", snprintfbuf)
833  .c_str());
834  }
835  }
836  };
837  // Some quick sanity checks...
838  checker(5e-324);
839  checker(1e-308);
840  checker(1.0);
841  checker(1.000005);
842  checker(1.7976931348623157e308);
843  checker(0.00390625);
844 #ifndef _MSC_VER
845  // on MSVC, snprintf() rounds it to 0.00195313. SixDigitsToBuffer() rounds it
846  // to 0.00195312 (round half to even).
847  checker(0.001953125);
848 #endif
849  checker(0.005859375);
850  // Some cases where the rounding is very very close
851  checker(1.089095e-15);
852  checker(3.274195e-55);
853  checker(6.534355e-146);
854  checker(2.920845e+234);
855 
856  if (mismatches.empty()) {
857  test_count = 0;
858  ExhaustiveFloat(kFloatNumCases, checker);
859 
860  test_count = 0;
861  std::vector<int> digit_testcases{
862  100000, 100001, 100002, 100005, 100010, 100020, 100050, 100100, // misc
863  195312, 195313, // 1.953125 is a case where we round down, just barely.
864  200000, 500000, 800000, // misc mid-range cases
865  585937, 585938, // 5.859375 is a case where we round up, just barely.
866  900000, 990000, 999000, 999900, 999990, 999996, 999997, 999998, 999999};
867  if (kFloatNumCases >= 1e9) {
868  // If at least 1 billion test cases were requested, user wants an
869  // exhaustive test. So let's test all mantissas, too.
870  constexpr int min_mantissa = 100000, max_mantissa = 999999;
871  digit_testcases.resize(max_mantissa - min_mantissa + 1);
872  std::iota(digit_testcases.begin(), digit_testcases.end(), min_mantissa);
873  }
874 
875  for (int exponent = -324; exponent <= 308; ++exponent) {
876  double powten = absl::strings_internal::Pow10(exponent);
877  if (powten == 0) powten = 5e-324;
878  if (kFloatNumCases >= 1e9) {
879  // The exhaustive test takes a very long time, so log progress.
880  char buf[kSixDigitsToBufferSize];
881  ABSL_RAW_LOG(
882  INFO, "%s",
883  absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten,
884  ") (",
885  std::string(buf, SixDigitsToBuffer(powten, buf)), ")")
886  .c_str());
887  }
888  for (int digits : digit_testcases) {
889  if (exponent == 308 && digits >= 179769) break; // don't overflow!
890  double digiform = (digits + 0.5) * 0.00001;
891  double testval = digiform * powten;
892  double pretestval = nextafter(testval, 0);
893  double posttestval = nextafter(testval, 1.7976931348623157e308);
894  checker(testval);
895  checker(pretestval);
896  checker(posttestval);
897  }
898  }
899  } else {
900  EXPECT_EQ(mismatches.size(), 0);
901  for (size_t i = 0; i < mismatches.size(); ++i) {
902  if (i > 100) i = mismatches.size() - 1;
903  double d = mismatches[i];
904  char sixdigitsbuf[kSixDigitsToBufferSize] = {0};
905  SixDigitsToBuffer(d, sixdigitsbuf);
906  char snprintfbuf[kSixDigitsToBufferSize] = {0};
907  snprintf(snprintfbuf, kSixDigitsToBufferSize, "%g", d);
908  double before = nextafter(d, 0.0);
909  double after = nextafter(d, 1.7976931348623157e308);
910  char b1[32], b2[kSixDigitsToBufferSize];
911  ABSL_RAW_LOG(
912  ERROR, "%s",
913  absl::StrCat(
914  "Mismatch #", i, " d=", d, " (", ToNineDigits(d), ")",
915  " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf,
916  "'", " Before.=", PerfectDtoa(before), " ",
917  (SixDigitsToBuffer(before, b2), b2),
918  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1),
919  " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2),
920  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1),
921  " After.=.", PerfectDtoa(after), " ",
922  (SixDigitsToBuffer(after, b2), b2),
923  " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1))
924  .c_str());
925  }
926  }
927 }
928 
929 TEST(StrToInt32, Partial) {
930  struct Int32TestLine {
931  std::string input;
932  bool status;
933  int32_t value;
934  };
935  const int32_t int32_min = std::numeric_limits<int32_t>::min();
936  const int32_t int32_max = std::numeric_limits<int32_t>::max();
937  Int32TestLine int32_test_line[] = {
938  {"", false, 0},
939  {" ", false, 0},
940  {"-", false, 0},
941  {"123@@@", false, 123},
942  {absl::StrCat(int32_min, int32_max), false, int32_min},
943  {absl::StrCat(int32_max, int32_max), false, int32_max},
944  };
945 
946  for (const Int32TestLine& test_line : int32_test_line) {
947  int32_t value = -2;
948  bool status = safe_strto32_base(test_line.input, &value, 10);
949  EXPECT_EQ(test_line.status, status) << test_line.input;
950  EXPECT_EQ(test_line.value, value) << test_line.input;
951  value = -2;
952  status = safe_strto32_base(test_line.input, &value, 10);
953  EXPECT_EQ(test_line.status, status) << test_line.input;
954  EXPECT_EQ(test_line.value, value) << test_line.input;
955  value = -2;
956  status = safe_strto32_base(absl::string_view(test_line.input), &value, 10);
957  EXPECT_EQ(test_line.status, status) << test_line.input;
958  EXPECT_EQ(test_line.value, value) << test_line.input;
959  }
960 }
961 
962 TEST(StrToUint32, Partial) {
963  struct Uint32TestLine {
964  std::string input;
965  bool status;
966  uint32_t value;
967  };
968  const uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
969  Uint32TestLine uint32_test_line[] = {
970  {"", false, 0},
971  {" ", false, 0},
972  {"-", false, 0},
973  {"123@@@", false, 123},
974  {absl::StrCat(uint32_max, uint32_max), false, uint32_max},
975  };
976 
977  for (const Uint32TestLine& test_line : uint32_test_line) {
978  uint32_t value = 2;
979  bool status = safe_strtou32_base(test_line.input, &value, 10);
980  EXPECT_EQ(test_line.status, status) << test_line.input;
981  EXPECT_EQ(test_line.value, value) << test_line.input;
982  value = 2;
983  status = safe_strtou32_base(test_line.input, &value, 10);
984  EXPECT_EQ(test_line.status, status) << test_line.input;
985  EXPECT_EQ(test_line.value, value) << test_line.input;
986  value = 2;
987  status = safe_strtou32_base(absl::string_view(test_line.input), &value, 10);
988  EXPECT_EQ(test_line.status, status) << test_line.input;
989  EXPECT_EQ(test_line.value, value) << test_line.input;
990  }
991 }
992 
993 TEST(StrToInt64, Partial) {
994  struct Int64TestLine {
995  std::string input;
996  bool status;
997  int64_t value;
998  };
999  const int64_t int64_min = std::numeric_limits<int64_t>::min();
1000  const int64_t int64_max = std::numeric_limits<int64_t>::max();
1001  Int64TestLine int64_test_line[] = {
1002  {"", false, 0},
1003  {" ", false, 0},
1004  {"-", false, 0},
1005  {"123@@@", false, 123},
1006  {absl::StrCat(int64_min, int64_max), false, int64_min},
1007  {absl::StrCat(int64_max, int64_max), false, int64_max},
1008  };
1009 
1010  for (const Int64TestLine& test_line : int64_test_line) {
1011  int64_t value = -2;
1012  bool status = safe_strto64_base(test_line.input, &value, 10);
1013  EXPECT_EQ(test_line.status, status) << test_line.input;
1014  EXPECT_EQ(test_line.value, value) << test_line.input;
1015  value = -2;
1016  status = safe_strto64_base(test_line.input, &value, 10);
1017  EXPECT_EQ(test_line.status, status) << test_line.input;
1018  EXPECT_EQ(test_line.value, value) << test_line.input;
1019  value = -2;
1020  status = safe_strto64_base(absl::string_view(test_line.input), &value, 10);
1021  EXPECT_EQ(test_line.status, status) << test_line.input;
1022  EXPECT_EQ(test_line.value, value) << test_line.input;
1023  }
1024 }
1025 
1026 TEST(StrToUint64, Partial) {
1027  struct Uint64TestLine {
1028  std::string input;
1029  bool status;
1030  uint64_t value;
1031  };
1032  const uint64_t uint64_max = std::numeric_limits<uint64_t>::max();
1033  Uint64TestLine uint64_test_line[] = {
1034  {"", false, 0},
1035  {" ", false, 0},
1036  {"-", false, 0},
1037  {"123@@@", false, 123},
1038  {absl::StrCat(uint64_max, uint64_max), false, uint64_max},
1039  };
1040 
1041  for (const Uint64TestLine& test_line : uint64_test_line) {
1042  uint64_t value = 2;
1043  bool status = safe_strtou64_base(test_line.input, &value, 10);
1044  EXPECT_EQ(test_line.status, status) << test_line.input;
1045  EXPECT_EQ(test_line.value, value) << test_line.input;
1046  value = 2;
1047  status = safe_strtou64_base(test_line.input, &value, 10);
1048  EXPECT_EQ(test_line.status, status) << test_line.input;
1049  EXPECT_EQ(test_line.value, value) << test_line.input;
1050  value = 2;
1051  status = safe_strtou64_base(absl::string_view(test_line.input), &value, 10);
1052  EXPECT_EQ(test_line.status, status) << test_line.input;
1053  EXPECT_EQ(test_line.value, value) << test_line.input;
1054  }
1055 }
1056 
1057 TEST(StrToInt32Base, PrefixOnly) {
1058  struct Int32TestLine {
1059  std::string input;
1060  bool status;
1061  int32_t value;
1062  };
1063  Int32TestLine int32_test_line[] = {
1064  { "", false, 0 },
1065  { "-", false, 0 },
1066  { "-0", true, 0 },
1067  { "0", true, 0 },
1068  { "0x", false, 0 },
1069  { "-0x", false, 0 },
1070  };
1071  const int base_array[] = { 0, 2, 8, 10, 16 };
1072 
1073  for (const Int32TestLine& line : int32_test_line) {
1074  for (const int base : base_array) {
1075  int32_t value = 2;
1076  bool status = safe_strto32_base(line.input.c_str(), &value, base);
1077  EXPECT_EQ(line.status, status) << line.input << " " << base;
1078  EXPECT_EQ(line.value, value) << line.input << " " << base;
1079  value = 2;
1080  status = safe_strto32_base(line.input, &value, base);
1081  EXPECT_EQ(line.status, status) << line.input << " " << base;
1082  EXPECT_EQ(line.value, value) << line.input << " " << base;
1083  value = 2;
1084  status = safe_strto32_base(absl::string_view(line.input), &value, base);
1085  EXPECT_EQ(line.status, status) << line.input << " " << base;
1086  EXPECT_EQ(line.value, value) << line.input << " " << base;
1087  }
1088  }
1089 }
1090 
1091 TEST(StrToUint32Base, PrefixOnly) {
1092  struct Uint32TestLine {
1093  std::string input;
1094  bool status;
1095  uint32_t value;
1096  };
1097  Uint32TestLine uint32_test_line[] = {
1098  { "", false, 0 },
1099  { "0", true, 0 },
1100  { "0x", false, 0 },
1101  };
1102  const int base_array[] = { 0, 2, 8, 10, 16 };
1103 
1104  for (const Uint32TestLine& line : uint32_test_line) {
1105  for (const int base : base_array) {
1106  uint32_t value = 2;
1107  bool status = safe_strtou32_base(line.input.c_str(), &value, base);
1108  EXPECT_EQ(line.status, status) << line.input << " " << base;
1109  EXPECT_EQ(line.value, value) << line.input << " " << base;
1110  value = 2;
1111  status = safe_strtou32_base(line.input, &value, base);
1112  EXPECT_EQ(line.status, status) << line.input << " " << base;
1113  EXPECT_EQ(line.value, value) << line.input << " " << base;
1114  value = 2;
1115  status = safe_strtou32_base(absl::string_view(line.input), &value, base);
1116  EXPECT_EQ(line.status, status) << line.input << " " << base;
1117  EXPECT_EQ(line.value, value) << line.input << " " << base;
1118  }
1119  }
1120 }
1121 
1122 TEST(StrToInt64Base, PrefixOnly) {
1123  struct Int64TestLine {
1124  std::string input;
1125  bool status;
1126  int64_t value;
1127  };
1128  Int64TestLine int64_test_line[] = {
1129  { "", false, 0 },
1130  { "-", false, 0 },
1131  { "-0", true, 0 },
1132  { "0", true, 0 },
1133  { "0x", false, 0 },
1134  { "-0x", false, 0 },
1135  };
1136  const int base_array[] = { 0, 2, 8, 10, 16 };
1137 
1138  for (const Int64TestLine& line : int64_test_line) {
1139  for (const int base : base_array) {
1140  int64_t value = 2;
1141  bool status = safe_strto64_base(line.input.c_str(), &value, base);
1142  EXPECT_EQ(line.status, status) << line.input << " " << base;
1143  EXPECT_EQ(line.value, value) << line.input << " " << base;
1144  value = 2;
1145  status = safe_strto64_base(line.input, &value, base);
1146  EXPECT_EQ(line.status, status) << line.input << " " << base;
1147  EXPECT_EQ(line.value, value) << line.input << " " << base;
1148  value = 2;
1149  status = safe_strto64_base(absl::string_view(line.input), &value, base);
1150  EXPECT_EQ(line.status, status) << line.input << " " << base;
1151  EXPECT_EQ(line.value, value) << line.input << " " << base;
1152  }
1153  }
1154 }
1155 
1156 TEST(StrToUint64Base, PrefixOnly) {
1157  struct Uint64TestLine {
1158  std::string input;
1159  bool status;
1160  uint64_t value;
1161  };
1162  Uint64TestLine uint64_test_line[] = {
1163  { "", false, 0 },
1164  { "0", true, 0 },
1165  { "0x", false, 0 },
1166  };
1167  const int base_array[] = { 0, 2, 8, 10, 16 };
1168 
1169  for (const Uint64TestLine& line : uint64_test_line) {
1170  for (const int base : base_array) {
1171  uint64_t value = 2;
1172  bool status = safe_strtou64_base(line.input.c_str(), &value, base);
1173  EXPECT_EQ(line.status, status) << line.input << " " << base;
1174  EXPECT_EQ(line.value, value) << line.input << " " << base;
1175  value = 2;
1176  status = safe_strtou64_base(line.input, &value, base);
1177  EXPECT_EQ(line.status, status) << line.input << " " << base;
1178  EXPECT_EQ(line.value, value) << line.input << " " << base;
1179  value = 2;
1180  status = safe_strtou64_base(absl::string_view(line.input), &value, base);
1181  EXPECT_EQ(line.status, status) << line.input << " " << base;
1182  EXPECT_EQ(line.value, value) << line.input << " " << base;
1183  }
1184  }
1185 }
1186 
1187 } // namespace
int v
Definition: variant_test.cc:81
double Pow10(int exp)
bool safe_strtou64_base(absl::string_view text, uint64_t *value, int base)
Definition: numbers.cc:900
char * FastIntToBuffer(int32_t, char *)
Definition: numbers.cc:241
char * begin
#define ABSL_RAW_LOG(severity,...)
Definition: raw_logging.h:42
bool operator<(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
size_t SixDigitsToBuffer(double d, char *buffer)
Definition: numbers.cc:510
uint128 operator-(uint128 lhs, uint128 rhs)
Definition: int128.h:662
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: str_cat.cc:98
CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept
uint64_t mantissa
Definition: charconv.cc:238
bool Itoa(IntType value, int base, std::string *destination)
char * end
char buf[N]
uint128 operator*(uint128 lhs, uint128 rhs)
Definition: int128.h:671
bool safe_strtou32_base(absl::string_view text, uint32_t *value, int base)
Definition: numbers.cc:896
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
T::second_type b2
const std::array< uint64_test_case, 34 > & strtouint64_test_cases()
bool safe_strto32_base(absl::string_view text, int32_t *value, int base)
Definition: numbers.cc:888
T::second_type b1
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type *out)
Definition: numbers.h:183
size_t value
uint128 operator+(uint128 lhs, uint128 rhs)
Definition: int128.h:653
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
TEST_F(GraphCyclesTest, NoCycle)
int exponent
Definition: charconv.cc:239
static const int kSixDigitsToBufferSize
Definition: numbers.h:94
bool safe_strto64_base(absl::string_view text, int64_t *value, int base)
Definition: numbers.cc:892
const std::array< uint32_test_case, 27 > & strtouint32_test_cases()
TEST(Symbolize, Unimplemented)
static const int kFastToBufferSize
Definition: numbers.h:93
uint128 operator/(uint128 lhs, uint128 rhs)
Definition: int128.cc:154
bool operator<=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:19