numbers_test_common.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 contains common things needed by numbers_test.cc,
  16. // numbers_legacy_test.cc and numbers_benchmark.cc.
  17. #ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
  18. #define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
  19. #include <array>
  20. #include <cstdint>
  21. #include <limits>
  22. #include <string>
  23. #include "absl/base/config.h"
  24. namespace absl {
  25. ABSL_NAMESPACE_BEGIN
  26. namespace strings_internal {
  27. template <typename IntType>
  28. inline bool Itoa(IntType value, int base, std::string* destination) {
  29. destination->clear();
  30. if (base <= 1 || base > 36) {
  31. return false;
  32. }
  33. if (value == 0) {
  34. destination->push_back('0');
  35. return true;
  36. }
  37. bool negative = value < 0;
  38. while (value != 0) {
  39. const IntType next_value = value / base;
  40. // Can't use std::abs here because of problems when IntType is unsigned.
  41. int remainder =
  42. static_cast<int>(value > next_value * base ? value - next_value * base
  43. : next_value * base - value);
  44. char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
  45. destination->insert(0, 1, c);
  46. value = next_value;
  47. }
  48. if (negative) {
  49. destination->insert(0, 1, '-');
  50. }
  51. return true;
  52. }
  53. struct uint32_test_case {
  54. const char* str;
  55. bool expect_ok;
  56. int base; // base to pass to the conversion function
  57. uint32_t expected;
  58. };
  59. inline const std::array<uint32_test_case, 27>& strtouint32_test_cases() {
  60. static const std::array<uint32_test_case, 27> test_cases{{
  61. {"0xffffffff", true, 16, (std::numeric_limits<uint32_t>::max)()},
  62. {"0x34234324", true, 16, 0x34234324},
  63. {"34234324", true, 16, 0x34234324},
  64. {"0", true, 16, 0},
  65. {" \t\n 0xffffffff", true, 16, (std::numeric_limits<uint32_t>::max)()},
  66. {" \f\v 46", true, 10, 46}, // must accept weird whitespace
  67. {" \t\n 72717222", true, 8, 072717222},
  68. {" \t\n 072717222", true, 8, 072717222},
  69. {" \t\n 072717228", false, 8, 07271722},
  70. {"0", true, 0, 0},
  71. // Base-10 version.
  72. {"34234324", true, 0, 34234324},
  73. {"4294967295", true, 0, (std::numeric_limits<uint32_t>::max)()},
  74. {"34234324 \n\t", true, 10, 34234324},
  75. // Unusual base
  76. {"0", true, 3, 0},
  77. {"2", true, 3, 2},
  78. {"11", true, 3, 4},
  79. // Invalid uints.
  80. {"", false, 0, 0},
  81. {" ", false, 0, 0},
  82. {"abc", false, 0, 0}, // would be valid hex, but prefix is missing
  83. {"34234324a", false, 0, 34234324},
  84. {"34234.3", false, 0, 34234},
  85. {"-1", false, 0, 0},
  86. {" -123", false, 0, 0},
  87. {" \t\n -123", false, 0, 0},
  88. // Out of bounds.
  89. {"4294967296", false, 0, (std::numeric_limits<uint32_t>::max)()},
  90. {"0x100000000", false, 0, (std::numeric_limits<uint32_t>::max)()},
  91. {nullptr, false, 0, 0},
  92. }};
  93. return test_cases;
  94. }
  95. struct uint64_test_case {
  96. const char* str;
  97. bool expect_ok;
  98. int base;
  99. uint64_t expected;
  100. };
  101. inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() {
  102. static const std::array<uint64_test_case, 34> test_cases{{
  103. {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
  104. {"3423432448783446", true, 16, int64_t{0x3423432448783446}},
  105. {"0", true, 16, 0},
  106. {"000", true, 0, 0},
  107. {"0", true, 0, 0},
  108. {" \t\n 0xffffffffffffffff", true, 16,
  109. (std::numeric_limits<uint64_t>::max)()},
  110. {"012345670123456701234", true, 8, int64_t{012345670123456701234}},
  111. {"12345670123456701234", true, 8, int64_t{012345670123456701234}},
  112. {"12845670123456701234", false, 8, 0},
  113. // Base-10 version.
  114. {"34234324487834466", true, 0, int64_t{34234324487834466}},
  115. {" \t\n 18446744073709551615", true, 0,
  116. (std::numeric_limits<uint64_t>::max)()},
  117. {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
  118. {" \f\v 46", true, 10, 46}, // must accept weird whitespace
  119. // Unusual base
  120. {"0", true, 3, 0},
  121. {"2", true, 3, 2},
  122. {"11", true, 3, 4},
  123. {"0", true, 0, 0},
  124. // Invalid uints.
  125. {"", false, 0, 0},
  126. {" ", false, 0, 0},
  127. {"abc", false, 0, 0},
  128. {"34234324487834466a", false, 0, 0},
  129. {"34234487834466.3", false, 0, 0},
  130. {"-1", false, 0, 0},
  131. {" -123", false, 0, 0},
  132. {" \t\n -123", false, 0, 0},
  133. // Out of bounds.
  134. {"18446744073709551616", false, 10, 0},
  135. {"18446744073709551616", false, 0, 0},
  136. {"0x10000000000000000", false, 16,
  137. (std::numeric_limits<uint64_t>::max)()},
  138. {"0X10000000000000000", false, 16,
  139. (std::numeric_limits<uint64_t>::max)()}, // 0X versus 0x.
  140. {"0x10000000000000000", false, 0, (std::numeric_limits<uint64_t>::max)()},
  141. {"0X10000000000000000", false, 0,
  142. (std::numeric_limits<uint64_t>::max)()}, // 0X versus 0x.
  143. {"0x1234", true, 16, 0x1234},
  144. // Base-10 string version.
  145. {"1234", true, 0, 1234},
  146. {nullptr, false, 0, 0},
  147. }};
  148. return test_cases;
  149. }
  150. } // namespace strings_internal
  151. ABSL_NAMESPACE_END
  152. } // namespace absl
  153. #endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_