re2 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/LICENSE +15 -20
  2. package/README.md +63 -4
  3. package/binding.gyp +1 -2
  4. package/lib/addon.cc +9 -5
  5. package/lib/exec.cc +4 -4
  6. package/lib/match.cc +4 -4
  7. package/lib/new.cc +6 -6
  8. package/lib/pattern.cc +148 -1
  9. package/lib/replace.cc +5 -4
  10. package/lib/search.cc +1 -1
  11. package/lib/set.cc +85 -10
  12. package/lib/test.cc +1 -1
  13. package/lib/unicode_properties.h +15840 -0
  14. package/lib/wrapped_re2.h +40 -4
  15. package/lib/wrapped_re2_set.h +3 -1
  16. package/llms-full.txt +497 -0
  17. package/llms.txt +135 -0
  18. package/package.json +19 -11
  19. package/re2.d.ts +2 -0
  20. package/re2.js +1 -0
  21. package/vendor/abseil-cpp/CMake/AbseilDll.cmake +87 -74
  22. package/vendor/abseil-cpp/CMakeLists.txt +3 -3
  23. package/vendor/abseil-cpp/FAQ.md +130 -79
  24. package/vendor/abseil-cpp/MODULE.bazel +6 -7
  25. package/vendor/abseil-cpp/absl/BUILD.bazel +6 -0
  26. package/vendor/abseil-cpp/absl/algorithm/BUILD.bazel +4 -0
  27. package/vendor/abseil-cpp/absl/algorithm/CMakeLists.txt +4 -0
  28. package/vendor/abseil-cpp/absl/algorithm/algorithm.h +34 -2
  29. package/vendor/abseil-cpp/absl/algorithm/container.h +164 -17
  30. package/vendor/abseil-cpp/absl/algorithm/container_test.cc +390 -13
  31. package/vendor/abseil-cpp/absl/base/BUILD.bazel +53 -6
  32. package/vendor/abseil-cpp/absl/base/CMakeLists.txt +28 -4
  33. package/vendor/abseil-cpp/absl/base/attributes.h +61 -42
  34. package/vendor/abseil-cpp/absl/base/call_once.h +1 -0
  35. package/vendor/abseil-cpp/absl/base/casts.h +8 -1
  36. package/vendor/abseil-cpp/absl/base/casts_test.cc +3 -6
  37. package/vendor/abseil-cpp/absl/base/config.h +53 -9
  38. package/vendor/abseil-cpp/absl/base/exception_safety_testing_test.cc +9 -9
  39. package/vendor/abseil-cpp/absl/base/fast_type_id.h +30 -2
  40. package/vendor/abseil-cpp/absl/base/fast_type_id_test.cc +3 -0
  41. package/vendor/abseil-cpp/absl/base/internal/exception_safety_testing.h +15 -12
  42. package/vendor/abseil-cpp/absl/base/internal/hardening.h +136 -0
  43. package/vendor/abseil-cpp/absl/base/internal/hardening_test.cc +168 -0
  44. package/vendor/abseil-cpp/absl/base/internal/iterator_traits.h +2 -2
  45. package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -0
  46. package/vendor/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
  47. package/vendor/abseil-cpp/absl/base/internal/sysinfo.cc +1 -2
  48. package/vendor/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
  49. package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
  50. package/vendor/abseil-cpp/absl/base/macros.h +36 -20
  51. package/vendor/abseil-cpp/absl/base/nullability.h +4 -3
  52. package/vendor/abseil-cpp/absl/base/optimization.h +3 -2
  53. package/vendor/abseil-cpp/absl/base/optimization_test.cc +4 -3
  54. package/vendor/abseil-cpp/absl/base/options.h +55 -1
  55. package/vendor/abseil-cpp/absl/base/policy_checks.h +5 -5
  56. package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
  57. package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
  58. package/vendor/abseil-cpp/absl/base/throw_delegate_test.cc +19 -28
  59. package/vendor/abseil-cpp/absl/cleanup/BUILD.bazel +2 -0
  60. package/vendor/abseil-cpp/absl/cleanup/CMakeLists.txt +2 -0
  61. package/vendor/abseil-cpp/absl/cleanup/cleanup.h +3 -2
  62. package/vendor/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
  63. package/vendor/abseil-cpp/absl/container/BUILD.bazel +19 -7
  64. package/vendor/abseil-cpp/absl/container/CMakeLists.txt +6 -5
  65. package/vendor/abseil-cpp/absl/container/btree_benchmark.cc +3 -5
  66. package/vendor/abseil-cpp/absl/container/btree_set.h +5 -5
  67. package/vendor/abseil-cpp/absl/container/btree_test.cc +11 -14
  68. package/vendor/abseil-cpp/absl/container/chunked_queue.h +8 -6
  69. package/vendor/abseil-cpp/absl/container/chunked_queue_test.cc +5 -5
  70. package/vendor/abseil-cpp/absl/container/fixed_array.h +14 -13
  71. package/vendor/abseil-cpp/absl/container/fixed_array_test.cc +3 -3
  72. package/vendor/abseil-cpp/absl/container/flat_hash_map.h +18 -6
  73. package/vendor/abseil-cpp/absl/container/flat_hash_map_test.cc +34 -1
  74. package/vendor/abseil-cpp/absl/container/flat_hash_set.h +21 -7
  75. package/vendor/abseil-cpp/absl/container/flat_hash_set_test.cc +39 -7
  76. package/vendor/abseil-cpp/absl/container/inlined_vector.h +29 -29
  77. package/vendor/abseil-cpp/absl/container/inlined_vector_test.cc +2 -2
  78. package/vendor/abseil-cpp/absl/container/internal/btree.h +32 -24
  79. package/vendor/abseil-cpp/absl/container/internal/btree_container.h +16 -17
  80. package/vendor/abseil-cpp/absl/container/internal/common.h +6 -5
  81. package/vendor/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
  82. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple.h +16 -16
  83. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple_test.cc +13 -13
  84. package/vendor/abseil-cpp/absl/container/internal/container_memory.h +41 -31
  85. package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults.h +2 -2
  86. package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.h +4 -4
  87. package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits.h +3 -3
  88. package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +27 -19
  89. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +2 -2
  90. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.h +0 -17
  91. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +12 -30
  92. package/vendor/abseil-cpp/absl/container/internal/inlined_vector.h +28 -28
  93. package/vendor/abseil-cpp/absl/container/internal/layout.h +13 -13
  94. package/vendor/abseil-cpp/absl/container/internal/layout_test.cc +3 -2
  95. package/vendor/abseil-cpp/absl/container/internal/raw_hash_map.h +60 -62
  96. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc +59 -39
  97. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.h +619 -326
  98. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc +25 -2
  99. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc +4 -4
  100. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +575 -159
  101. package/vendor/abseil-cpp/absl/container/linked_hash_map.h +2 -2
  102. package/vendor/abseil-cpp/absl/container/node_hash_map.h +27 -15
  103. package/vendor/abseil-cpp/absl/container/node_hash_map_test.cc +34 -0
  104. package/vendor/abseil-cpp/absl/container/node_hash_set.h +25 -11
  105. package/vendor/abseil-cpp/absl/container/node_hash_set_test.cc +39 -7
  106. package/vendor/abseil-cpp/absl/container/sample_element_size_test.cc +7 -4
  107. package/vendor/abseil-cpp/absl/crc/BUILD.bazel +0 -1
  108. package/vendor/abseil-cpp/absl/crc/CMakeLists.txt +2 -3
  109. package/vendor/abseil-cpp/absl/crc/crc32c_benchmark.cc +2 -1
  110. package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.cc +6 -6
  111. package/vendor/abseil-cpp/absl/crc/internal/crc.cc +4 -6
  112. package/vendor/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
  113. package/vendor/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
  114. package/vendor/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +143 -81
  115. package/vendor/abseil-cpp/absl/debugging/BUILD.bazel +9 -31
  116. package/vendor/abseil-cpp/absl/debugging/CMakeLists.txt +3 -33
  117. package/vendor/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
  118. package/vendor/abseil-cpp/absl/debugging/internal/demangle_test.cc +2 -1
  119. package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc +12 -2
  120. package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.h +2 -3
  121. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +11 -0
  122. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -4
  123. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
  124. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +4 -0
  125. package/vendor/abseil-cpp/absl/debugging/internal/symbolize.h +46 -36
  126. package/vendor/abseil-cpp/absl/debugging/stacktrace.cc +18 -58
  127. package/vendor/abseil-cpp/absl/debugging/stacktrace.h +5 -48
  128. package/vendor/abseil-cpp/absl/debugging/stacktrace_test.cc +10 -124
  129. package/vendor/abseil-cpp/absl/debugging/symbolize.cc +20 -2
  130. package/vendor/abseil-cpp/absl/debugging/symbolize_elf.inc +58 -106
  131. package/vendor/abseil-cpp/absl/debugging/symbolize_test.cc +37 -36
  132. package/vendor/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
  133. package/vendor/abseil-cpp/absl/flags/BUILD.bazel +6 -3
  134. package/vendor/abseil-cpp/absl/flags/CMakeLists.txt +1 -1
  135. package/vendor/abseil-cpp/absl/flags/commandlineflag.h +8 -6
  136. package/vendor/abseil-cpp/absl/flags/commandlineflag_test.cc +1 -1
  137. package/vendor/abseil-cpp/absl/flags/flag_benchmark.cc +5 -5
  138. package/vendor/abseil-cpp/absl/flags/flag_test.cc +30 -30
  139. package/vendor/abseil-cpp/absl/flags/internal/flag.cc +4 -4
  140. package/vendor/abseil-cpp/absl/flags/internal/flag.h +6 -6
  141. package/vendor/abseil-cpp/absl/flags/marshalling.h +2 -28
  142. package/vendor/abseil-cpp/absl/flags/marshalling_test.cc +12 -11
  143. package/vendor/abseil-cpp/absl/flags/reflection_test.cc +1 -1
  144. package/vendor/abseil-cpp/absl/functional/BUILD.bazel +26 -1
  145. package/vendor/abseil-cpp/absl/functional/CMakeLists.txt +29 -1
  146. package/vendor/abseil-cpp/absl/functional/any_invocable.h +13 -14
  147. package/vendor/abseil-cpp/absl/functional/any_invocable_test.cc +46 -47
  148. package/vendor/abseil-cpp/absl/functional/bind_back.h +79 -0
  149. package/vendor/abseil-cpp/absl/functional/bind_back_test.cc +237 -0
  150. package/vendor/abseil-cpp/absl/functional/bind_front.h +7 -1
  151. package/vendor/abseil-cpp/absl/functional/bind_front_test.cc +4 -4
  152. package/vendor/abseil-cpp/absl/functional/function_ref_test.cc +2 -2
  153. package/vendor/abseil-cpp/absl/functional/internal/any_invocable.h +28 -28
  154. package/vendor/abseil-cpp/absl/functional/internal/back_binder.h +95 -0
  155. package/vendor/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
  156. package/vendor/abseil-cpp/absl/functional/internal/function_ref.h +2 -2
  157. package/vendor/abseil-cpp/absl/functional/overload_test.cc +13 -13
  158. package/vendor/abseil-cpp/absl/hash/BUILD.bazel +1 -2
  159. package/vendor/abseil-cpp/absl/hash/CMakeLists.txt +1 -2
  160. package/vendor/abseil-cpp/absl/hash/hash.h +1 -1
  161. package/vendor/abseil-cpp/absl/hash/hash_test.cc +14 -20
  162. package/vendor/abseil-cpp/absl/hash/hash_testing.h +11 -9
  163. package/vendor/abseil-cpp/absl/hash/internal/city.cc +39 -51
  164. package/vendor/abseil-cpp/absl/hash/internal/hash.cc +165 -47
  165. package/vendor/abseil-cpp/absl/hash/internal/hash.h +86 -27
  166. package/vendor/abseil-cpp/absl/hash/internal/low_level_hash_test.cc +36 -1
  167. package/vendor/abseil-cpp/absl/hash/internal/spy_hash_state.h +8 -5
  168. package/vendor/abseil-cpp/absl/log/BUILD.bazel +5 -2
  169. package/vendor/abseil-cpp/absl/log/CMakeLists.txt +5 -3
  170. package/vendor/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
  171. package/vendor/abseil-cpp/absl/log/internal/BUILD.bazel +15 -1
  172. package/vendor/abseil-cpp/absl/log/internal/log_message.cc +5 -4
  173. package/vendor/abseil-cpp/absl/log/internal/log_message.h +14 -0
  174. package/vendor/abseil-cpp/absl/log/internal/nullstream.h +1 -1
  175. package/vendor/abseil-cpp/absl/log/internal/proto.cc +13 -0
  176. package/vendor/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
  177. package/vendor/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
  178. package/vendor/abseil-cpp/absl/log/internal/structured_proto_test.cc +3 -3
  179. package/vendor/abseil-cpp/absl/log/internal/vlog_config.cc +2 -2
  180. package/vendor/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc +3 -3
  181. package/vendor/abseil-cpp/absl/log/log_format_test.cc +19 -2
  182. package/vendor/abseil-cpp/absl/log/log_modifier_methods_test.cc +18 -0
  183. package/vendor/abseil-cpp/absl/log/log_streamer.h +29 -2
  184. package/vendor/abseil-cpp/absl/log/log_streamer_test.cc +18 -0
  185. package/vendor/abseil-cpp/absl/log/scoped_mock_log_test.cc +1 -1
  186. package/vendor/abseil-cpp/absl/log/vlog_is_on.h +0 -2
  187. package/vendor/abseil-cpp/absl/log/vlog_is_on_test.cc +6 -5
  188. package/vendor/abseil-cpp/absl/memory/memory.h +55 -5
  189. package/vendor/abseil-cpp/absl/memory/memory_test.cc +55 -1
  190. package/vendor/abseil-cpp/absl/meta/BUILD.bazel +2 -0
  191. package/vendor/abseil-cpp/absl/meta/internal/requires.h +1 -1
  192. package/vendor/abseil-cpp/absl/meta/type_traits.h +119 -55
  193. package/vendor/abseil-cpp/absl/meta/type_traits_test.cc +7 -7
  194. package/vendor/abseil-cpp/absl/numeric/int128_test.cc +6 -6
  195. package/vendor/abseil-cpp/absl/profiling/BUILD.bazel +3 -1
  196. package/vendor/abseil-cpp/absl/profiling/hashtable.cc +0 -4
  197. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.cc +32 -33
  198. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.h +25 -2
  199. package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc +8 -5
  200. package/vendor/abseil-cpp/absl/random/BUILD.bazel +13 -1
  201. package/vendor/abseil-cpp/absl/random/CMakeLists.txt +23 -2
  202. package/vendor/abseil-cpp/absl/random/benchmarks.cc +1 -1
  203. package/vendor/abseil-cpp/absl/random/beta_distribution.h +2 -2
  204. package/vendor/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
  205. package/vendor/abseil-cpp/absl/random/bit_gen_ref_test.cc +43 -0
  206. package/vendor/abseil-cpp/absl/random/discrete_distribution.h +1 -1
  207. package/vendor/abseil-cpp/absl/random/distributions.h +17 -17
  208. package/vendor/abseil-cpp/absl/random/distributions_test.cc +4 -4
  209. package/vendor/abseil-cpp/absl/random/exponential_distribution.h +1 -1
  210. package/vendor/abseil-cpp/absl/random/internal/BUILD.bazel +4 -2
  211. package/vendor/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
  212. package/vendor/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
  213. package/vendor/abseil-cpp/absl/random/internal/generate_real.h +1 -1
  214. package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
  215. package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc +3 -2
  216. package/vendor/abseil-cpp/absl/random/internal/mock_helpers.h +14 -40
  217. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
  218. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base_test.cc +2 -2
  219. package/vendor/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
  220. package/vendor/abseil-cpp/absl/random/internal/pcg_engine_test.cc +3 -2
  221. package/vendor/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
  222. package/vendor/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
  223. package/vendor/abseil-cpp/absl/random/internal/randen_engine_test.cc +3 -2
  224. package/vendor/abseil-cpp/absl/random/internal/randen_test.cc +3 -2
  225. package/vendor/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
  226. package/vendor/abseil-cpp/absl/random/internal/seed_material.cc +4 -4
  227. package/vendor/abseil-cpp/absl/random/internal/seed_material.h +2 -1
  228. package/vendor/abseil-cpp/absl/random/internal/traits.h +21 -0
  229. package/vendor/abseil-cpp/absl/random/internal/traits_test.cc +5 -0
  230. package/vendor/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
  231. package/vendor/abseil-cpp/absl/random/internal/uniform_helper_test.cc +2 -1
  232. package/vendor/abseil-cpp/absl/random/mocking_access.h +74 -0
  233. package/vendor/abseil-cpp/absl/random/mocking_bit_gen.h +9 -19
  234. package/vendor/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
  235. package/vendor/abseil-cpp/absl/status/BUILD.bazel +81 -0
  236. package/vendor/abseil-cpp/absl/status/CMakeLists.txt +91 -0
  237. package/vendor/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
  238. package/vendor/abseil-cpp/absl/status/internal/status_internal.h +26 -2
  239. package/vendor/abseil-cpp/absl/status/internal/status_matchers.h +22 -8
  240. package/vendor/abseil-cpp/absl/status/internal/statusor_internal.h +43 -43
  241. package/vendor/abseil-cpp/absl/status/status.cc +62 -70
  242. package/vendor/abseil-cpp/absl/status/status.h +249 -23
  243. package/vendor/abseil-cpp/absl/status/status_benchmark.cc +12 -0
  244. package/vendor/abseil-cpp/absl/status/status_builder.cc +196 -0
  245. package/vendor/abseil-cpp/absl/status/status_builder.h +978 -0
  246. package/vendor/abseil-cpp/absl/status/status_builder_test.cc +380 -0
  247. package/vendor/abseil-cpp/absl/status/status_macros.h +484 -0
  248. package/vendor/abseil-cpp/absl/status/status_macros_test.cc +634 -0
  249. package/vendor/abseil-cpp/absl/status/status_matchers.h +2 -1
  250. package/vendor/abseil-cpp/absl/status/status_matchers_test.cc +3 -4
  251. package/vendor/abseil-cpp/absl/status/status_payload_printer.h +3 -2
  252. package/vendor/abseil-cpp/absl/status/status_test.cc +443 -13
  253. package/vendor/abseil-cpp/absl/status/statusor.h +69 -36
  254. package/vendor/abseil-cpp/absl/status/statusor_test.cc +132 -35
  255. package/vendor/abseil-cpp/absl/strings/BUILD.bazel +42 -7
  256. package/vendor/abseil-cpp/absl/strings/CMakeLists.txt +33 -4
  257. package/vendor/abseil-cpp/absl/strings/ascii.h +1 -2
  258. package/vendor/abseil-cpp/absl/strings/atod_manual_test.cc +5 -5
  259. package/vendor/abseil-cpp/absl/strings/cord.cc +26 -7
  260. package/vendor/abseil-cpp/absl/strings/cord.h +23 -13
  261. package/vendor/abseil-cpp/absl/strings/cord_buffer.h +4 -2
  262. package/vendor/abseil-cpp/absl/strings/cord_test.cc +85 -9
  263. package/vendor/abseil-cpp/absl/strings/escaping.cc +183 -35
  264. package/vendor/abseil-cpp/absl/strings/escaping.h +12 -2
  265. package/vendor/abseil-cpp/absl/strings/escaping_benchmark.cc +1 -3
  266. package/vendor/abseil-cpp/absl/strings/escaping_test.cc +22 -18
  267. package/vendor/abseil-cpp/absl/strings/has_absl_stringify_test.cc +2 -2
  268. package/vendor/abseil-cpp/absl/strings/has_ostream_operator_test.cc +2 -2
  269. package/vendor/abseil-cpp/absl/strings/internal/append_and_overwrite.h +10 -10
  270. package/vendor/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc +1 -1
  271. package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
  272. package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
  273. package/vendor/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
  274. package/vendor/abseil-cpp/absl/strings/internal/escaping.h +2 -26
  275. package/vendor/abseil-cpp/absl/strings/internal/generic_printer_internal.h +23 -2
  276. package/vendor/abseil-cpp/absl/strings/internal/generic_printer_test.cc +6 -2
  277. package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -24
  278. package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc +16 -41
  279. package/vendor/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
  280. package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
  281. package/vendor/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
  282. package/vendor/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +12 -20
  283. package/vendor/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +510 -307
  284. package/vendor/abseil-cpp/absl/strings/internal/str_join_internal.h +0 -1
  285. package/vendor/abseil-cpp/absl/strings/internal/str_split_internal.h +9 -10
  286. package/vendor/abseil-cpp/absl/strings/internal/string_constant_test.cc +6 -5
  287. package/vendor/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
  288. package/vendor/abseil-cpp/absl/strings/internal/stringify_stream.h +119 -0
  289. package/vendor/abseil-cpp/absl/strings/internal/stringify_stream_test.cc +111 -0
  290. package/vendor/abseil-cpp/absl/strings/numbers.cc +406 -0
  291. package/vendor/abseil-cpp/absl/strings/numbers.h +4 -0
  292. package/vendor/abseil-cpp/absl/strings/numbers_test.cc +33 -0
  293. package/vendor/abseil-cpp/absl/strings/resize_and_overwrite.h +10 -6
  294. package/vendor/abseil-cpp/absl/strings/str_cat.h +36 -1
  295. package/vendor/abseil-cpp/absl/strings/str_cat_benchmark.cc +1 -2
  296. package/vendor/abseil-cpp/absl/strings/str_cat_test.cc +28 -0
  297. package/vendor/abseil-cpp/absl/strings/str_join_test.cc +4 -4
  298. package/vendor/abseil-cpp/absl/strings/str_split.h +11 -6
  299. package/vendor/abseil-cpp/absl/strings/str_split_test.cc +13 -0
  300. package/vendor/abseil-cpp/absl/strings/substitute.h +2 -2
  301. package/vendor/abseil-cpp/absl/synchronization/BUILD.bazel +3 -0
  302. package/vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +21 -0
  303. package/vendor/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
  304. package/vendor/abseil-cpp/absl/synchronization/mutex.cc +13 -0
  305. package/vendor/abseil-cpp/absl/synchronization/mutex.h +32 -2
  306. package/vendor/abseil-cpp/absl/synchronization/mutex_test.cc +17 -3
  307. package/vendor/abseil-cpp/absl/time/BUILD.bazel +80 -0
  308. package/vendor/abseil-cpp/absl/time/CMakeLists.txt +73 -0
  309. package/vendor/abseil-cpp/absl/time/clock.h +3 -0
  310. package/vendor/abseil-cpp/absl/time/clock_interface.cc +71 -0
  311. package/vendor/abseil-cpp/absl/time/clock_interface.h +93 -0
  312. package/vendor/abseil-cpp/absl/time/clock_interface_test.cc +128 -0
  313. package/vendor/abseil-cpp/absl/time/format.cc +3 -10
  314. package/vendor/abseil-cpp/absl/time/format_test.cc +12 -0
  315. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +90 -89
  316. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +80 -5
  317. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +1 -2
  318. package/vendor/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
  319. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/version +1 -1
  320. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +0 -0
  321. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
  322. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +0 -0
  323. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +0 -0
  324. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +0 -0
  325. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +0 -0
  326. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +0 -0
  327. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +0 -0
  328. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +0 -0
  329. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +1 -1
  330. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab +3 -3
  331. package/vendor/abseil-cpp/absl/time/simulated_clock.cc +225 -0
  332. package/vendor/abseil-cpp/absl/time/simulated_clock.h +109 -0
  333. package/vendor/abseil-cpp/absl/time/simulated_clock_test.cc +614 -0
  334. package/vendor/abseil-cpp/absl/types/BUILD.bazel +116 -0
  335. package/vendor/abseil-cpp/absl/types/CMakeLists.txt +100 -0
  336. package/vendor/abseil-cpp/absl/types/any.h +26 -4
  337. package/vendor/abseil-cpp/absl/types/any_span.h +1067 -0
  338. package/vendor/abseil-cpp/absl/types/any_span_benchmark.cc +258 -0
  339. package/vendor/abseil-cpp/absl/types/any_span_test.cc +1210 -0
  340. package/vendor/abseil-cpp/absl/types/compare.h +4 -4
  341. package/vendor/abseil-cpp/absl/types/internal/any_span.h +477 -0
  342. package/vendor/abseil-cpp/absl/types/internal/span.h +5 -6
  343. package/vendor/abseil-cpp/absl/types/optional.h +30 -3
  344. package/vendor/abseil-cpp/absl/types/optional_ref.h +295 -0
  345. package/vendor/abseil-cpp/absl/types/optional_ref_test.cc +370 -0
  346. package/vendor/abseil-cpp/absl/types/source_location.cc +18 -0
  347. package/vendor/abseil-cpp/absl/types/source_location.h +172 -0
  348. package/vendor/abseil-cpp/absl/types/source_location_test.cc +139 -0
  349. package/vendor/abseil-cpp/absl/types/span.h +19 -23
  350. package/vendor/abseil-cpp/absl/types/variant.h +75 -18
  351. package/vendor/abseil-cpp/absl/types/variant_test.cc +23 -23
  352. package/vendor/abseil-cpp/absl/utility/BUILD.bazel +1 -0
  353. package/vendor/abseil-cpp/absl/utility/CMakeLists.txt +1 -0
  354. package/vendor/abseil-cpp/absl/utility/utility.h +99 -16
  355. package/vendor/abseil-cpp/ci/absl_alternate_options.h +2 -0
  356. package/vendor/abseil-cpp/ci/linux_arm_clang-latest_libcxx_bazel.sh +10 -4
  357. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_asan_bazel.sh +13 -6
  358. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_bazel.sh +10 -4
  359. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_tsan_bazel.sh +12 -5
  360. package/vendor/abseil-cpp/ci/linux_clang-latest_libstdcxx_bazel.sh +9 -2
  361. package/vendor/abseil-cpp/ci/linux_docker_containers.sh +4 -4
  362. package/vendor/abseil-cpp/ci/linux_gcc-floor_libstdcxx_bazel.sh +10 -3
  363. package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +8 -2
  364. package/vendor/abseil-cpp/ci/macos_xcode_bazel.sh +4 -3
  365. package/vendor/abseil-cpp/ci/macos_xcode_cmake.sh +2 -2
  366. package/vendor/abseil-cpp/ci/windows_clangcl_bazel.bat +1 -1
  367. package/vendor/abseil-cpp/ci/windows_msvc_bazel.bat +1 -1
  368. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.cc +0 -118
  369. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.h +0 -71
  370. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer_test.cc +0 -97
@@ -25,6 +25,7 @@
25
25
  #include <limits>
26
26
  #include <optional>
27
27
  #include <string>
28
+ #include <type_traits>
28
29
 
29
30
  #include "absl/base/attributes.h"
30
31
  #include "absl/base/config.h"
@@ -37,7 +38,6 @@
37
38
  #include "absl/strings/internal/str_format/extension.h"
38
39
  #include "absl/strings/numbers.h"
39
40
  #include "absl/strings/string_view.h"
40
- #include "absl/types/optional.h"
41
41
  #include "absl/types/span.h"
42
42
 
43
43
  namespace absl {
@@ -101,7 +101,7 @@ class StackArray {
101
101
  // Requires: `0 <= carry <= 9`
102
102
  template <typename Int>
103
103
  inline char MultiplyBy10WithCarry(Int* v, char carry) {
104
- using BiggerInt = absl::conditional_t<sizeof(Int) == 4, uint64_t, uint128>;
104
+ using BiggerInt = std::conditional_t<sizeof(Int) == 4, uint64_t, uint128>;
105
105
  BiggerInt tmp =
106
106
  10 * static_cast<BiggerInt>(*v) + static_cast<BiggerInt>(carry);
107
107
  *v = static_cast<Int>(tmp);
@@ -138,7 +138,7 @@ class BinaryToDecimal {
138
138
  // We will left shift a uint128 by `exp` bits, so we need `128+exp` total
139
139
  // bits. Round up to 32.
140
140
  // See constructor for details about adding `10%` to the value.
141
- return static_cast<size_t>((128 + exp + 31) / 32 * 11 / 10);
141
+ return static_cast<size_t>(((128 + exp + 31) / 32 * 11 + 9) / 10);
142
142
  }
143
143
 
144
144
  public:
@@ -250,6 +250,12 @@ class BinaryToDecimal {
250
250
  // Requires `-exp < 0` and
251
251
  // `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`.
252
252
  class FractionalDigitGenerator {
253
+ private:
254
+ static constexpr size_t ChunksNeeded(int exp) {
255
+ // We need 128 bits for mantissa and `exp` bits for exponent.
256
+ return static_cast<size_t>((128 + exp + 31) / 32);
257
+ }
258
+
253
259
  public:
254
260
  // Run the conversion for `v * 2^exp` and call `f(generator)`.
255
261
  // This function will allocate enough stack space to perform the conversion.
@@ -257,13 +263,15 @@ class FractionalDigitGenerator {
257
263
  uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) {
258
264
  using Limits = std::numeric_limits<MaxFloatType>;
259
265
  assert(-exp < 0);
260
- assert(-exp >= Limits::min_exponent - 128);
266
+ // We need enough precision to cover all digits of MaxFloatType, and we add
267
+ // 128 bits of headroom for fractional digit generation.
268
+ const int margin = Limits::digits + 128;
269
+ assert(-exp >= Limits::min_exponent - margin);
261
270
  static_assert(StackArray::kMaxCapacity >=
262
- (Limits::digits + 128 - Limits::min_exponent + 31) / 32,
271
+ ChunksNeeded(margin - Limits::min_exponent),
263
272
  "");
264
273
  StackArray::RunWithCapacity(
265
- static_cast<size_t>((Limits::digits + exp + 31) / 32),
266
- [=](absl::Span<uint32_t> input) {
274
+ ChunksNeeded(exp), [=](absl::Span<uint32_t> input) {
267
275
  f(FractionalDigitGenerator(input, v, exp));
268
276
  });
269
277
  }
@@ -645,7 +653,8 @@ void FormatFFast(Int v, int exp, const FormatState &state) {
645
653
  // Prints `v*2^exp` with the options from `state`.
646
654
  // This one is guaranteed to not have fractional digits, so we don't have to
647
655
  // worry about anything after the `.`.
648
- void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
656
+ void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState& state,
657
+ bool strip_trailing_zeros = false) {
649
658
  BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) {
650
659
  const size_t total_digits =
651
660
  btd.TotalDigits() + (state.ShouldPrintDot() ? state.precision + 1 : 0);
@@ -662,9 +671,12 @@ void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
662
671
  state.sink->Append(btd.CurrentDigits());
663
672
  } while (btd.AdvanceDigits());
664
673
 
665
- if (state.ShouldPrintDot())
674
+ if (state.ShouldPrintDot() && !strip_trailing_zeros) {
666
675
  state.sink->Append(1, '.');
667
- state.sink->Append(state.precision, '0');
676
+ }
677
+ if (!strip_trailing_zeros) {
678
+ state.sink->Append(state.precision, '0');
679
+ }
668
680
  state.sink->Append(padding.right_spaces, ' ');
669
681
  });
670
682
  }
@@ -674,20 +686,21 @@ void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) {
674
686
  // Prints `v*2^exp` with the options from `state`.
675
687
  // This one is guaranteed to be < 1.0, so we don't have to worry about integral
676
688
  // digits.
677
- void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) {
689
+ void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState& state,
690
+ size_t digits_to_trim = 0) {
691
+ const bool print_dot =
692
+ (state.precision > digits_to_trim) || state.conv.has_alt_flag();
678
693
  const size_t total_digits =
679
- /* 0 */ 1 + (state.ShouldPrintDot() ? state.precision + 1 : 0);
694
+ /* 0 */ 1 + (print_dot ? (state.precision - digits_to_trim) + 1 : 0);
680
695
  auto padding =
681
696
  ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state);
682
697
  padding.zeros += 1;
683
698
  state.sink->Append(padding.left_spaces, ' ');
684
699
  if (state.sign_char != '\0') state.sink->Append(1, state.sign_char);
685
700
  state.sink->Append(padding.zeros, '0');
686
-
687
- if (state.ShouldPrintDot()) state.sink->Append(1, '.');
688
-
701
+ if (print_dot) state.sink->Append(1, '.');
689
702
  // Print digits
690
- size_t digits_to_go = state.precision;
703
+ size_t digits_to_go = state.precision - digits_to_trim;
691
704
 
692
705
  FractionalDigitGenerator::RunConversion(
693
706
  v, exp, [&](FractionalDigitGenerator digit_gen) {
@@ -1151,25 +1164,6 @@ void RoundUp(Buffer *buffer, int *exp) {
1151
1164
  }
1152
1165
  }
1153
1166
 
1154
- void PrintExponent(int exp, char e, Buffer *out) {
1155
- out->push_back(e);
1156
- if (exp < 0) {
1157
- out->push_back('-');
1158
- exp = -exp;
1159
- } else {
1160
- out->push_back('+');
1161
- }
1162
- // Exponent digits.
1163
- if (exp > 99) {
1164
- out->push_back(static_cast<char>(exp / 100 + '0'));
1165
- out->push_back(static_cast<char>(exp / 10 % 10 + '0'));
1166
- out->push_back(static_cast<char>(exp % 10 + '0'));
1167
- } else {
1168
- out->push_back(static_cast<char>(exp / 10 + '0'));
1169
- out->push_back(static_cast<char>(exp % 10 + '0'));
1170
- }
1171
- }
1172
-
1173
1167
  template <typename Float, typename Int>
1174
1168
  constexpr bool CanFitMantissa() {
1175
1169
  return
@@ -1185,8 +1179,8 @@ constexpr bool CanFitMantissa() {
1185
1179
  template <typename Float>
1186
1180
  struct Decomposed {
1187
1181
  using MantissaType =
1188
- absl::conditional_t<std::is_same<long double, Float>::value, uint128,
1189
- uint64_t>;
1182
+ std::conditional_t<std::is_same<long double, Float>::value, uint128,
1183
+ uint64_t>;
1190
1184
  static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
1191
1185
  "");
1192
1186
  MantissaType mantissa;
@@ -1227,180 +1221,43 @@ size_t PrintIntegralDigits(Int digits, Buffer* out) {
1227
1221
  return printed;
1228
1222
  }
1229
1223
 
1230
- // Back out 'extra_digits' digits and round up if necessary.
1231
- void RemoveExtraPrecision(size_t extra_digits,
1232
- bool has_leftover_value,
1233
- Buffer* out,
1234
- int* exp_out) {
1235
- // Back out the extra digits
1236
- out->end -= extra_digits;
1237
-
1238
- bool needs_to_round_up = [&] {
1239
- // We look at the digit just past the end.
1240
- // There must be 'extra_digits' extra valid digits after end.
1241
- if (*out->end > '5') return true;
1242
- if (*out->end < '5') return false;
1243
- if (has_leftover_value || std::any_of(out->end + 1, out->end + extra_digits,
1244
- [](char c) { return c != '0'; }))
1245
- return true;
1246
-
1247
- // Ends in ...50*, round to even.
1248
- return out->last_digit() % 2 == 1;
1249
- }();
1250
-
1251
- if (needs_to_round_up) {
1252
- RoundUp<FormatStyle::Precision>(out, exp_out);
1224
+ std::optional<int> GetOneDigit(BinaryToDecimal& btd,
1225
+ absl::string_view& digits_view) {
1226
+ if (digits_view.empty() && !btd.AdvanceDigits()) {
1227
+ return std::nullopt;
1253
1228
  }
1229
+ char d = digits_view.front();
1230
+ digits_view.remove_prefix(1);
1231
+ return d - '0';
1254
1232
  }
1255
1233
 
1256
- // Print the value into the buffer.
1257
- // This will not include the exponent, which will be returned in 'exp_out' for
1258
- // Precision mode.
1259
- template <typename Int, typename Float, FormatStyle mode>
1260
- bool FloatToBufferImpl(Int int_mantissa,
1261
- int exp,
1262
- size_t precision,
1263
- Buffer* out,
1264
- int* exp_out) {
1265
- assert((CanFitMantissa<Float, Int>()));
1266
-
1267
- const int int_bits = std::numeric_limits<Int>::digits;
1268
-
1269
- // In precision mode, we start printing one char to the right because it will
1270
- // also include the '.'
1271
- // In fixed mode we put the dot afterwards on the right.
1272
- out->begin = out->end =
1273
- out->data + 1 + kMaxFixedPrecision + (mode == FormatStyle::Precision);
1274
-
1275
- if (exp >= 0) {
1276
- if (std::numeric_limits<Float>::digits + exp > int_bits) {
1277
- // The value will overflow the Int
1278
- return false;
1279
- }
1280
- size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa << exp, out);
1281
- size_t digits_to_zero_pad = precision;
1282
- if (mode == FormatStyle::Precision) {
1283
- *exp_out = static_cast<int>(digits_printed - 1);
1284
- if (digits_to_zero_pad < digits_printed - 1) {
1285
- RemoveExtraPrecision(digits_printed - 1 - digits_to_zero_pad, false,
1286
- out, exp_out);
1287
- return true;
1288
- }
1289
- digits_to_zero_pad -= digits_printed - 1;
1290
- }
1291
- for (; digits_to_zero_pad-- > 0;) out->push_back('0');
1292
- return true;
1293
- }
1294
-
1295
- exp = -exp;
1296
- // We need at least 4 empty bits for the next decimal digit.
1297
- // We will multiply by 10.
1298
- if (exp > int_bits - 4) return false;
1299
-
1300
- const Int mask = (Int{1} << exp) - 1;
1301
-
1302
- // Print the integral part first.
1303
- size_t digits_printed = PrintIntegralDigits<mode>(int_mantissa >> exp, out);
1304
- int_mantissa &= mask;
1234
+ struct DigitRun {
1235
+ std::optional<int> digit;
1236
+ size_t nines;
1237
+ };
1305
1238
 
1306
- size_t fractional_count = precision;
1307
- if (mode == FormatStyle::Precision) {
1308
- if (digits_printed == 0) {
1309
- // Find the first non-zero digit, when in Precision mode.
1310
- *exp_out = 0;
1311
- if (int_mantissa) {
1312
- while (int_mantissa <= mask) {
1313
- int_mantissa *= 10;
1314
- --*exp_out;
1315
- }
1316
- }
1317
- out->push_front(static_cast<char>(int_mantissa >> exp) + '0');
1318
- out->push_back('.');
1319
- int_mantissa &= mask;
1320
- } else {
1321
- // We already have a digit, and a '.'
1322
- *exp_out = static_cast<int>(digits_printed - 1);
1323
- if (fractional_count < digits_printed - 1) {
1324
- // If we had enough digits, return right away.
1325
- // The code below will try to round again otherwise.
1326
- RemoveExtraPrecision(digits_printed - 1 - fractional_count,
1327
- int_mantissa != 0, out, exp_out);
1328
- return true;
1329
- }
1330
- fractional_count -= digits_printed - 1;
1239
+ DigitRun GetDigits(BinaryToDecimal& btd, absl::string_view& digits_view) {
1240
+ auto peek_digit = [&]() -> std::optional<int> {
1241
+ if (digits_view.empty()) {
1242
+ if (!btd.AdvanceDigits()) return std::nullopt;
1243
+ digits_view = btd.CurrentDigits();
1331
1244
  }
1332
- }
1333
-
1334
- auto get_next_digit = [&] {
1335
- int_mantissa *= 10;
1336
- char digit = static_cast<char>(int_mantissa >> exp);
1337
- int_mantissa &= mask;
1338
- return digit;
1245
+ return digits_view.front() - '0';
1339
1246
  };
1340
1247
 
1341
- // Print fractional_count more digits, if available.
1342
- for (; fractional_count > 0; --fractional_count) {
1343
- out->push_back(get_next_digit() + '0');
1344
- }
1345
-
1346
- char next_digit = get_next_digit();
1347
- if (next_digit > 5 ||
1348
- (next_digit == 5 && (int_mantissa || out->last_digit() % 2 == 1))) {
1349
- RoundUp<mode>(out, exp_out);
1350
- }
1351
-
1352
- return true;
1353
- }
1354
-
1355
- template <FormatStyle mode, typename Float>
1356
- bool FloatToBuffer(Decomposed<Float> decomposed,
1357
- size_t precision,
1358
- Buffer* out,
1359
- int* exp) {
1360
- if (precision > kMaxFixedPrecision) return false;
1361
-
1362
- // Try with uint64_t.
1363
- if (CanFitMantissa<Float, std::uint64_t>() &&
1364
- FloatToBufferImpl<std::uint64_t, Float, mode>(
1365
- static_cast<std::uint64_t>(decomposed.mantissa), decomposed.exponent,
1366
- precision, out, exp))
1367
- return true;
1368
-
1369
- #if defined(ABSL_HAVE_INTRINSIC_INT128)
1370
- // If that is not enough, try with __uint128_t.
1371
- return CanFitMantissa<Float, __uint128_t>() &&
1372
- FloatToBufferImpl<__uint128_t, Float, mode>(
1373
- static_cast<__uint128_t>(decomposed.mantissa), decomposed.exponent,
1374
- precision, out, exp);
1375
- #endif
1376
- return false;
1377
- }
1248
+ auto digit_before_nines = GetOneDigit(btd, digits_view);
1249
+ if (!digit_before_nines.has_value()) return {std::nullopt, 0};
1378
1250
 
1379
- void WriteBufferToSink(char sign_char, absl::string_view str,
1380
- const FormatConversionSpecImpl &conv,
1381
- FormatSinkImpl *sink) {
1382
- size_t left_spaces = 0, zeros = 0, right_spaces = 0;
1383
- size_t missing_chars = 0;
1384
- if (conv.width() >= 0) {
1385
- const size_t conv_width_size_t = static_cast<size_t>(conv.width());
1386
- const size_t existing_chars =
1387
- str.size() + static_cast<size_t>(sign_char != 0);
1388
- if (conv_width_size_t > existing_chars)
1389
- missing_chars = conv_width_size_t - existing_chars;
1390
- }
1391
- if (conv.has_left_flag()) {
1392
- right_spaces = missing_chars;
1393
- } else if (conv.has_zero_flag()) {
1394
- zeros = missing_chars;
1395
- } else {
1396
- left_spaces = missing_chars;
1251
+ auto next_digit = peek_digit();
1252
+ size_t num_nines = 0;
1253
+ while (next_digit == 9) {
1254
+ // consume the 9
1255
+ GetOneDigit(btd, digits_view);
1256
+ ++num_nines;
1257
+ next_digit = peek_digit();
1397
1258
  }
1398
-
1399
- sink->Append(left_spaces, ' ');
1400
- if (sign_char != '\0') sink->Append(1, sign_char);
1401
- sink->Append(zeros, '0');
1402
- sink->Append(str);
1403
- sink->Append(right_spaces, ' ');
1259
+ return digit_before_nines == 9 ? DigitRun{std::nullopt, num_nines + 1}
1260
+ : DigitRun{digit_before_nines, num_nines};
1404
1261
  }
1405
1262
 
1406
1263
  template <typename Int>
@@ -1573,7 +1430,8 @@ void FormatEFast(Int v, int exp, bool uppercase, const FormatState& state) {
1573
1430
  }
1574
1431
 
1575
1432
  void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1576
- const FormatState& state) {
1433
+ const FormatState& state,
1434
+ size_t digits_to_trim = 0) {
1577
1435
  assert(exp < 0);
1578
1436
 
1579
1437
  FractionalDigitGenerator::RunConversion(
@@ -1597,11 +1455,16 @@ void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1597
1455
  }
1598
1456
  num_leading_zeros++;
1599
1457
  }
1600
-
1458
+ size_t precision = state.precision;
1459
+ if (precision > digits_to_trim) {
1460
+ precision -= digits_to_trim;
1461
+ } else {
1462
+ precision = 0;
1463
+ }
1601
1464
  bool change_to_zeros = false;
1602
- if (nines >= state.precision || state.precision == 0) {
1465
+ if (nines >= precision || state.precision == 0) {
1603
1466
  bool round_up = false;
1604
- if (nines == state.precision) {
1467
+ if (nines == precision) {
1605
1468
  round_up = digit_gen.IsGreaterThanHalf();
1606
1469
  } else {
1607
1470
  round_up = nines > 0 || digit_gen.IsGreaterThanHalf();
@@ -1624,10 +1487,12 @@ void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1624
1487
  char* exp_end =
1625
1488
  numbers_internal::FastIntToBuffer(scientific_exp, exp_start);
1626
1489
  const size_t total_digits =
1627
- 1 // First digit
1628
- + (state.ShouldPrintDot() ? 1 : 0) // Decimal point
1629
- + state.precision // Digits after decimal
1630
- + 1 // 'e' or 'E'
1490
+ 1 // First digit
1491
+ +
1492
+ ((precision > 0 || state.conv.has_alt_flag()) ? 1
1493
+ : 0) // Decimal point
1494
+ + precision // Digits after decimal
1495
+ + 1 // 'e' or 'E'
1631
1496
  + static_cast<size_t>(exp_end - exp_buffer); // Exponent digits
1632
1497
 
1633
1498
  const auto padding = ExtraWidthToPadding(
@@ -1639,10 +1504,10 @@ void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1639
1504
  }
1640
1505
 
1641
1506
  state.sink->Append(1, static_cast<char>(first_digit + '0'));
1642
- if (state.ShouldPrintDot()) {
1507
+ if (precision > 0 || state.conv.has_alt_flag()) {
1643
1508
  state.sink->Append(1, '.');
1644
1509
  }
1645
- size_t digits_to_go = state.precision;
1510
+ size_t digits_to_go = precision;
1646
1511
  size_t nines_to_print = std::min(nines, digits_to_go);
1647
1512
  state.sink->Append(nines_to_print, change_to_zeros ? '0' : '9');
1648
1513
  digits_to_go -= nines_to_print;
@@ -1682,49 +1547,9 @@ void FormatENegativeExpSlow(uint128 mantissa, int exp, bool uppercase,
1682
1547
  });
1683
1548
  }
1684
1549
 
1685
- std::optional<int> GetOneDigit(BinaryToDecimal& btd,
1686
- absl::string_view& digits_view) {
1687
- if (digits_view.empty()) {
1688
- if (!btd.AdvanceDigits()) return std::nullopt;
1689
- digits_view = btd.CurrentDigits();
1690
- }
1691
- char d = digits_view.front();
1692
- digits_view.remove_prefix(1);
1693
- return d - '0';
1694
- }
1695
-
1696
- struct DigitRun {
1697
- std::optional<int> digit;
1698
- size_t nines;
1699
- };
1700
-
1701
- DigitRun GetDigits(BinaryToDecimal& btd, absl::string_view& digits_view) {
1702
- auto peek_digit = [&]() -> std::optional<int> {
1703
- if (digits_view.empty()) {
1704
- if (!btd.AdvanceDigits()) return std::nullopt;
1705
- digits_view = btd.CurrentDigits();
1706
- }
1707
- return digits_view.front() - '0';
1708
- };
1709
-
1710
- auto digit_before_nines = GetOneDigit(btd, digits_view);
1711
- if (!digit_before_nines.has_value()) return {std::nullopt, 0};
1712
-
1713
- auto next_digit = peek_digit();
1714
- size_t num_nines = 0;
1715
- while (next_digit == 9) {
1716
- // consume the 9
1717
- GetOneDigit(btd, digits_view);
1718
- ++num_nines;
1719
- next_digit = peek_digit();
1720
- }
1721
- return digit_before_nines == 9
1722
- ? DigitRun{std::nullopt, num_nines + 1}
1723
- : DigitRun{digit_before_nines, num_nines};
1724
- }
1725
-
1726
1550
  void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1727
- const FormatState& state) {
1551
+ const FormatState& state,
1552
+ size_t digits_to_trim = 0) {
1728
1553
  BinaryToDecimal::RunConversion(
1729
1554
  mantissa, exp, [&](BinaryToDecimal btd) {
1730
1555
  int scientific_exp = static_cast<int>(btd.TotalDigits() - 1);
@@ -1764,9 +1589,14 @@ void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1764
1589
  char exp_buffer[numbers_internal::kFastToBufferSize];
1765
1590
  char* exp_buffer_end =
1766
1591
  numbers_internal::FastIntToBuffer(scientific_exp, exp_buffer);
1767
- const size_t total_digits_out =
1768
- 1 + state.ShouldPrintDot() + state.precision + 2 +
1769
- (static_cast<size_t>(exp_buffer_end - exp_buffer));
1592
+ const bool print_dot =
1593
+ (state.precision > digits_to_trim) || state.conv.has_alt_flag();
1594
+ const size_t exp_size =
1595
+ static_cast<size_t>(exp_buffer_end - exp_buffer) + 2 +
1596
+ (scientific_exp < 10 ? 1 : 0);
1597
+ const size_t total_digits_out = 1 + (print_dot ? 1 : 0) +
1598
+ (state.precision - digits_to_trim) +
1599
+ exp_size;
1770
1600
 
1771
1601
  const auto padding = ExtraWidthToPadding(
1772
1602
  total_digits_out + (state.sign_char != '\0' ? 1 : 0), state);
@@ -1777,19 +1607,30 @@ void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1777
1607
  }
1778
1608
  state.sink->Append(1, static_cast<char>(first_digit + '0'));
1779
1609
  --digits_to_go;
1780
- if (state.precision > 0 || state.ShouldPrintDot()) {
1610
+ if (print_dot) {
1781
1611
  state.sink->Append(1, '.');
1782
1612
  }
1783
- state.sink->Append(std::min(digits_to_go, nines),
1784
- change_to_zeros ? '0' : '9');
1785
- digits_to_go -= std::min(digits_to_go, nines);
1613
+
1614
+ size_t remaining_to_print = state.precision - digits_to_trim;
1615
+ auto append_with_trim = [&](size_t count, char c) {
1616
+ size_t to_append = std::min(count, remaining_to_print);
1617
+ if (to_append > 0) {
1618
+ state.sink->Append(to_append, c);
1619
+ remaining_to_print -= to_append;
1620
+ }
1621
+ };
1622
+
1623
+ size_t nines_to_append = std::min(digits_to_go, nines);
1624
+ append_with_trim(nines_to_append, change_to_zeros ? '0' : '9');
1625
+ digits_to_go -= nines_to_append;
1626
+
1786
1627
  while (digits_to_go > 0) {
1787
1628
  auto [digit_opt, curr_nines] = GetDigits(btd, digits_view);
1788
1629
  if (!digit_opt.has_value()) break;
1789
1630
  int digit = *digit_opt;
1790
1631
  if (curr_nines + 1 < digits_to_go) {
1791
- state.sink->Append(1, static_cast<char>(digit + '0'));
1792
- state.sink->Append(curr_nines, '9');
1632
+ append_with_trim(1, static_cast<char>(digit + '0'));
1633
+ append_with_trim(curr_nines, '9');
1793
1634
  digits_to_go -= curr_nines + 1;
1794
1635
  } else {
1795
1636
  bool need_round_up = false;
@@ -1803,16 +1644,16 @@ void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1803
1644
  // we know we need to round since nine is after precision ends
1804
1645
  need_round_up = true;
1805
1646
  }
1806
- state.sink->Append(1,
1807
- static_cast<char>(digit + need_round_up + '0'));
1808
- state.sink->Append(digits_to_go - 1, need_round_up ? '0' : '9');
1647
+ append_with_trim(1, static_cast<char>(digit + need_round_up + '0'));
1648
+ append_with_trim(digits_to_go - 1, need_round_up ? '0' : '9');
1809
1649
  digits_to_go = 0;
1810
1650
  }
1811
1651
  }
1812
1652
 
1813
1653
  if (digits_to_go > 0) {
1814
- state.sink->Append(digits_to_go, '0');
1654
+ append_with_trim(digits_to_go, '0');
1815
1655
  }
1656
+
1816
1657
  state.sink->Append(1, uppercase ? 'E' : 'e');
1817
1658
  state.sink->Append(1, scientific_exp >= 0 ? '+' : '-');
1818
1659
  if (scientific_exp < 10) {
@@ -1824,6 +1665,389 @@ void FormatEPositiveExpSlow(uint128 mantissa, int exp, bool uppercase,
1824
1665
  });
1825
1666
  }
1826
1667
 
1668
+ //
1669
+ template <typename Int>
1670
+ void FormatGFast(Int v, int exp, bool uppercase, const FormatState& state) {
1671
+ if (!v) {
1672
+ absl::string_view mantissa_str =
1673
+ state.ShouldPrintDot() && state.conv.has_alt_flag() ? "0." : "0";
1674
+ FinalPrint(state, mantissa_str, 0,
1675
+ state.conv.has_alt_flag() * state.precision, "");
1676
+ return;
1677
+ }
1678
+ constexpr int kInputBits = sizeof(Int) * 8;
1679
+ constexpr int kMaxFractionalDigits = 128;
1680
+ // We need enough headroom to the left of our starting pointer to support
1681
+ // a potential prefix shift for values between 1e-1 and 1e-4.
1682
+ // The prefix "0.000" is 5 chars, plus potential rounding carry (1 char).
1683
+ constexpr int kHeadroom = 32;
1684
+ constexpr int kBufferSize = kHeadroom + // headroom + rounding + '.'
1685
+ kMaxFixedPrecision + // Integral
1686
+ kMaxFractionalDigits; // Fractional
1687
+ const int total_bits = kInputBits - LeadingZeros(v) + exp;
1688
+ char buffer[kBufferSize];
1689
+ char* integral_start = buffer + kHeadroom;
1690
+ char* integral_end = buffer + kHeadroom + kMaxFixedPrecision;
1691
+ char* final_start;
1692
+ char* final_end;
1693
+ bool zero_integral = false;
1694
+ int scientific_exp = 0;
1695
+ size_t digits_printed = 0;
1696
+ size_t trailing_zeros = 0;
1697
+ bool has_more_non_zero = false;
1698
+
1699
+ auto check_integral_zeros = [](char* const begin, char* const end,
1700
+ const size_t precision,
1701
+ size_t digits_processed) -> bool {
1702
+ // When considering rounding to even, we care about the digits after the
1703
+ // round digit which means the total digits to move from the start is
1704
+ // precision + 2 since the first digit we print before the decimal point
1705
+ // is not a part of precision.
1706
+ size_t digit_upper_bound = precision + 2;
1707
+ if (digits_processed > digit_upper_bound) {
1708
+ return std::any_of(begin + digit_upper_bound, end,
1709
+ [](char c) { return c != '0'; });
1710
+ }
1711
+ return false;
1712
+ };
1713
+
1714
+ if (exp >= 0) {
1715
+ integral_end = total_bits <= 64
1716
+ ? numbers_internal::FastIntToBuffer(
1717
+ static_cast<uint64_t>(v) << exp, integral_start)
1718
+ : numbers_internal::FastIntToBuffer(
1719
+ static_cast<uint128>(v) << exp, integral_start);
1720
+ *integral_end = '0';
1721
+ final_start = integral_start;
1722
+ // Integral is guaranteed to be non-zero at this point.
1723
+ scientific_exp = static_cast<int>(integral_end - integral_start) - 1;
1724
+ digits_printed = static_cast<size_t>(integral_end - integral_start);
1725
+ final_end = integral_end;
1726
+ has_more_non_zero = check_integral_zeros(integral_start, integral_end,
1727
+ state.precision, digits_printed);
1728
+ } else {
1729
+ exp = -exp;
1730
+ if (exp < kInputBits) {
1731
+ integral_end =
1732
+ numbers_internal::FastIntToBuffer(v >> exp, integral_start);
1733
+ }
1734
+ *integral_end = '0';
1735
+ // We didn't move integral_start and it gets set to 0 in
1736
+ zero_integral = exp >= kInputBits || v >> exp == 0;
1737
+ if (!zero_integral) {
1738
+ digits_printed = static_cast<size_t>(integral_end - integral_start);
1739
+ has_more_non_zero = check_integral_zeros(integral_start, integral_end,
1740
+ state.precision, digits_printed);
1741
+ final_end = integral_end;
1742
+ }
1743
+ // Print fractional digits
1744
+ char* fractional_start = integral_end;
1745
+
1746
+ size_t digits_to_print = (state.precision + 1) >= digits_printed
1747
+ ? state.precision + 1 - digits_printed
1748
+ : 0;
1749
+ bool print_extra = digits_printed <= state.precision + 1;
1750
+ auto [fractional_end, skipped_zeros, has_nonzero_rem] =
1751
+ exp <= 64 ? PrintFractionalDigitsScientific(
1752
+ v, fractional_start, exp, digits_to_print + print_extra,
1753
+ zero_integral)
1754
+ : PrintFractionalDigitsScientific(
1755
+ static_cast<uint128>(v), fractional_start, exp,
1756
+ digits_to_print + print_extra, zero_integral);
1757
+ final_end = fractional_end;
1758
+ *fractional_end = '0';
1759
+ has_more_non_zero |= has_nonzero_rem;
1760
+ digits_printed += static_cast<size_t>(fractional_end - fractional_start);
1761
+ if (zero_integral) {
1762
+ scientific_exp = -1 * static_cast<int>(skipped_zeros + 1);
1763
+ } else {
1764
+ scientific_exp = static_cast<int>(integral_end - integral_start) - 1;
1765
+ }
1766
+ // Don't do any rounding here, we will do it ourselves.
1767
+ final_start = zero_integral ? fractional_start : integral_start;
1768
+ }
1769
+
1770
+ // For rounding
1771
+ if (digits_printed >= state.precision + 1) {
1772
+ final_start[-1] = '0';
1773
+ char* round_digit_ptr = final_start + 1 + state.precision;
1774
+ if (*round_digit_ptr > '5') {
1775
+ RoundUp(round_digit_ptr - 1);
1776
+ } else if (*round_digit_ptr == '5') {
1777
+ if (has_more_non_zero) {
1778
+ RoundUp(round_digit_ptr - 1);
1779
+ } else {
1780
+ RoundToEven(round_digit_ptr - 1);
1781
+ }
1782
+ }
1783
+ final_end = round_digit_ptr;
1784
+ if (final_start[-1] == '1') {
1785
+ --final_start;
1786
+ ++scientific_exp;
1787
+ --final_end;
1788
+ }
1789
+ } else {
1790
+ // Need to pad with zeros.
1791
+ trailing_zeros = state.precision - (digits_printed - 1);
1792
+ }
1793
+
1794
+ if (state.precision > 0 || state.ShouldPrintDot()) {
1795
+ final_start[-1] = *final_start;
1796
+ *final_start = '.';
1797
+ --final_start;
1798
+ }
1799
+ // We have scientific exp at this point
1800
+ if ((scientific_exp < 0 ||
1801
+ state.precision + 1 > static_cast<size_t>(scientific_exp)) &&
1802
+ scientific_exp >= -4) {
1803
+ if (scientific_exp < 0) {
1804
+ // Have 1.23456, needs 0.00123456
1805
+ // Move the first digit
1806
+ final_start[1] = *final_start;
1807
+ if (!state.ShouldPrintDot()) {
1808
+ ++final_end;
1809
+ }
1810
+ // Add some zeros
1811
+ for (; scientific_exp < -1; ++scientific_exp) {
1812
+ *final_start = '0';
1813
+ --final_start;
1814
+ }
1815
+ *final_start-- = '.';
1816
+ *final_start = '0';
1817
+ } else if (scientific_exp > 0) {
1818
+ // Have 1.23456, needs 1234.56
1819
+ // Move the '.' scientific_exp positions to the right.
1820
+ std::rotate(final_start + 1, final_start + 2,
1821
+ final_start + scientific_exp + 2);
1822
+ }
1823
+ scientific_exp = 0;
1824
+ }
1825
+ auto const& conv = state.conv;
1826
+ if (!conv.has_alt_flag()) {
1827
+ trailing_zeros = 0;
1828
+ while (final_end[-1] == '0') {
1829
+ --final_end;
1830
+ }
1831
+ if (final_end[-1] == '.') --final_end;
1832
+ }
1833
+ if (scientific_exp) {
1834
+ // We need to add 2 to the buffer size for the +/- sign and the e
1835
+ constexpr size_t kExpBufferSize = numbers_internal::kFastToBufferSize + 2;
1836
+ char exp_buffer[kExpBufferSize];
1837
+ char* exp_ptr_start = exp_buffer;
1838
+ char* exp_ptr = exp_ptr_start;
1839
+ *exp_ptr++ = uppercase ? 'E' : 'e';
1840
+ if (scientific_exp >= 0) {
1841
+ *exp_ptr++ = '+';
1842
+ } else {
1843
+ *exp_ptr++ = '-';
1844
+ scientific_exp = -scientific_exp;
1845
+ }
1846
+
1847
+ if (scientific_exp < 10) {
1848
+ *exp_ptr++ = '0';
1849
+ }
1850
+ exp_ptr = numbers_internal::FastIntToBuffer(scientific_exp, exp_ptr);
1851
+ FinalPrint(state,
1852
+ absl::string_view(
1853
+ final_start, static_cast<size_t>((final_end - final_start))),
1854
+ 0, trailing_zeros,
1855
+ absl::string_view(exp_ptr_start,
1856
+ static_cast<size_t>(exp_ptr - exp_ptr_start)));
1857
+ } else {
1858
+ FinalPrint(state,
1859
+ absl::string_view(
1860
+ final_start, static_cast<size_t>((final_end - final_start))),
1861
+ 0, trailing_zeros, "");
1862
+ }
1863
+ }
1864
+
1865
+ template <typename Int>
1866
+ void FormatGNegativeExpSlow(Int mantissa, int exp, bool uppercase,
1867
+ const FormatState& state) {
1868
+ // Most of the code here is to decide whether to use E-style or F-style
1869
+ // formatting, with the actual formatting done in FormatENegativeExpSlow and
1870
+ // FormatFNegativeExpSlow.
1871
+ FractionalDigitGenerator::RunConversion(
1872
+ mantissa, -exp, [&](FractionalDigitGenerator digit_gen) {
1873
+ int first_digit = 0;
1874
+ size_t nines = 0;
1875
+ int num_leading_zeros = 0;
1876
+ size_t num_trailing_zeros = 0;
1877
+ while (digit_gen.HasMoreDigits()) {
1878
+ auto digits = digit_gen.GetDigits();
1879
+ if (digits.digit_before_nine != 0) {
1880
+ first_digit = digits.digit_before_nine;
1881
+ nines = digits.num_nines;
1882
+ break;
1883
+ } else if (digits.num_nines > 0) {
1884
+ // This also means the first digit is 0
1885
+ first_digit = 9;
1886
+ nines = digits.num_nines - 1;
1887
+ num_leading_zeros++;
1888
+ break;
1889
+ }
1890
+ num_leading_zeros++;
1891
+ }
1892
+ if (nines >= state.precision || state.precision == 0) {
1893
+ bool round_up = false;
1894
+ if (nines == state.precision) {
1895
+ round_up = digit_gen.IsGreaterThanHalf();
1896
+ } else {
1897
+ round_up = nines > 0 || digit_gen.IsGreaterThanHalf();
1898
+ }
1899
+ if (round_up) {
1900
+ first_digit = (first_digit == 9 ? 1 : first_digit + 1);
1901
+ num_leading_zeros -= (first_digit == 1);
1902
+ num_trailing_zeros = state.precision;
1903
+ }
1904
+ }
1905
+ int scientific_exp = -(num_leading_zeros + 1);
1906
+ assert(scientific_exp < 0);
1907
+ size_t digits_to_go = state.precision + 1;
1908
+ if (state.conv.has_alt_flag()) {
1909
+ num_trailing_zeros = 0;
1910
+ }
1911
+ if (!state.conv.has_alt_flag() && !num_trailing_zeros) {
1912
+ num_trailing_zeros = (first_digit == 0);
1913
+ digits_to_go -= std::min(digits_to_go, nines + 1);
1914
+ while (digits_to_go > 0 && digit_gen.HasMoreDigits()) {
1915
+ auto digits = digit_gen.GetDigits();
1916
+ if (digits.num_nines + 1 < digits_to_go) {
1917
+ if (digits.digit_before_nine == 0 && digits.num_nines == 0) {
1918
+ ++num_trailing_zeros;
1919
+ } else {
1920
+ num_trailing_zeros = 0;
1921
+ }
1922
+ digits_to_go -= digits.num_nines + 1;
1923
+ } else {
1924
+ bool round_up = false;
1925
+ if (digits.num_nines + 1 > digits_to_go) {
1926
+ round_up = true;
1927
+ } else if (digit_gen.IsGreaterThanHalf()) {
1928
+ round_up = true;
1929
+ } else if (digit_gen.IsExactlyHalf()) {
1930
+ round_up =
1931
+ digits.num_nines != 0 || digits.digit_before_nine % 2 == 1;
1932
+ }
1933
+
1934
+ if (digits_to_go == 1) {
1935
+ if (digits.digit_before_nine + (round_up ? 1 : 0) == 0) {
1936
+ ++num_trailing_zeros;
1937
+ } else {
1938
+ num_trailing_zeros = 0;
1939
+ }
1940
+ } else {
1941
+ num_trailing_zeros = round_up ? digits_to_go - 1 : 0;
1942
+ }
1943
+ digits_to_go = 0;
1944
+ }
1945
+ }
1946
+ }
1947
+ if (!num_trailing_zeros) {
1948
+ num_trailing_zeros = !state.conv.has_alt_flag() * digits_to_go;
1949
+ }
1950
+ if (scientific_exp <= -4) {
1951
+ FormatENegativeExpSlow(static_cast<uint128>(mantissa), exp, uppercase,
1952
+ state, num_trailing_zeros);
1953
+ } else {
1954
+ FormatState f_state = state;
1955
+ f_state.precision = static_cast<size_t>(
1956
+ static_cast<int>(state.precision) - scientific_exp);
1957
+ FormatFNegativeExpSlow(static_cast<uint128>(mantissa), -exp, f_state,
1958
+ num_trailing_zeros);
1959
+ }
1960
+ });
1961
+ }
1962
+ template <typename Int>
1963
+ void FormatGPositiveExpSlow(Int mantissa, int exp, bool uppercase,
1964
+ const FormatState& state) {
1965
+ BinaryToDecimal::RunConversion(mantissa, exp, [&](BinaryToDecimal btd) {
1966
+ int scientific_exp = static_cast<int>(btd.TotalDigits()) - 1;
1967
+ absl::string_view digits = btd.CurrentDigits();
1968
+ size_t digits_to_go = state.precision + 1;
1969
+ auto [first_digit_opt, nines] = GetDigits(btd, digits);
1970
+ int first_digit = first_digit_opt.value_or(9);
1971
+ if (!first_digit_opt) {
1972
+ --nines;
1973
+ }
1974
+ // At this point we are guaranteed to have some sort of first digit
1975
+ bool change_to_zeros = false;
1976
+ size_t num_trailing_zeros = 0;
1977
+ if (nines + 1 >= digits_to_go) {
1978
+ // Everything we need to print is in the first DigitRun
1979
+ auto next_digit_opt = GetDigits(btd, digits).digit;
1980
+ if (nines == state.precision) {
1981
+ change_to_zeros = next_digit_opt.value_or(0) > 4;
1982
+ } else {
1983
+ change_to_zeros = true;
1984
+ }
1985
+ if (change_to_zeros) {
1986
+ if (first_digit != 9) {
1987
+ first_digit = first_digit + 1;
1988
+ } else {
1989
+ first_digit = 1;
1990
+ ++scientific_exp;
1991
+ }
1992
+ num_trailing_zeros = state.precision;
1993
+ }
1994
+ }
1995
+ if (state.conv.has_alt_flag()) {
1996
+ num_trailing_zeros = 0;
1997
+ }
1998
+ // At this point the number of trailing zeros is not covered by the first
1999
+ // DigitRun
2000
+ if (!state.conv.has_alt_flag() && !num_trailing_zeros) {
2001
+ num_trailing_zeros = first_digit == 0;
2002
+ digits_to_go -= std::min(digits_to_go, nines + 1);
2003
+ while (digits_to_go > 0) {
2004
+ auto [digit_opt, curr_nines] = GetDigits(btd, digits);
2005
+ if (!digit_opt.has_value()) {
2006
+ break;
2007
+ }
2008
+ if (curr_nines + 1 < digits_to_go) {
2009
+ int digit = *digit_opt;
2010
+ // If the previous one was a 0 we are too
2011
+ if (digit == 0 && curr_nines == 0) {
2012
+ ++num_trailing_zeros;
2013
+ --digits_to_go;
2014
+ } else {
2015
+ num_trailing_zeros = 0;
2016
+ --digits_to_go;
2017
+ digits_to_go -= std::min(digits_to_go, curr_nines);
2018
+ }
2019
+ } else {
2020
+ auto next_digit_opt = GetDigits(btd, digits).digit;
2021
+ if (digits_to_go == 1) {
2022
+ if (*digit_opt == 0) {
2023
+ if (curr_nines || next_digit_opt > 4) {
2024
+ num_trailing_zeros = 0;
2025
+ } else {
2026
+ ++num_trailing_zeros;
2027
+ }
2028
+ } else {
2029
+ num_trailing_zeros = 0;
2030
+ }
2031
+ } else if (digits_to_go == curr_nines + 1) {
2032
+ num_trailing_zeros = next_digit_opt > 4 ? digits_to_go - 1 : 0;
2033
+ } else {
2034
+ num_trailing_zeros = digits_to_go - 1;
2035
+ }
2036
+ digits_to_go = 0;
2037
+ }
2038
+ }
2039
+ }
2040
+ assert(scientific_exp >= 0);
2041
+ // By this point the exponent is accurate
2042
+ if (static_cast<size_t>(scientific_exp) > state.precision) {
2043
+ FormatEPositiveExpSlow(mantissa, exp, uppercase, state,
2044
+ num_trailing_zeros);
2045
+ } else {
2046
+ FormatFPositiveExpSlow(mantissa, exp, state, !state.conv.has_alt_flag());
2047
+ }
2048
+ });
2049
+ }
2050
+
1827
2051
  template <typename Float>
1828
2052
  bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1829
2053
  FormatSinkImpl *sink) {
@@ -1847,12 +2071,8 @@ bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1847
2071
  size_t precision =
1848
2072
  conv.precision() < 0 ? 6 : static_cast<size_t>(conv.precision());
1849
2073
 
1850
- int exp = 0;
1851
-
1852
2074
  auto decomposed = Decompose(abs_v);
1853
2075
 
1854
- Buffer buffer;
1855
-
1856
2076
  FormatConversionChar c = conv.conversion_char();
1857
2077
 
1858
2078
  if (c == FormatConversionCharInternal::f ||
@@ -1869,35 +2089,26 @@ bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1869
2089
  } else if (c == FormatConversionCharInternal::g ||
1870
2090
  c == FormatConversionCharInternal::G) {
1871
2091
  precision = std::max(precision, size_t{1}) - 1;
1872
- if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer,
1873
- &exp)) {
1874
- return FallbackToSnprintf(v, conv, sink);
1875
- }
1876
- if ((exp < 0 || precision + 1 > static_cast<size_t>(exp)) && exp >= -4) {
1877
- if (exp < 0) {
1878
- // Have 1.23456, needs 0.00123456
1879
- // Move the first digit
1880
- buffer.begin[1] = *buffer.begin;
1881
- // Add some zeros
1882
- for (; exp < -1; ++exp) *buffer.begin-- = '0';
1883
- *buffer.begin-- = '.';
1884
- *buffer.begin = '0';
1885
- } else if (exp > 0) {
1886
- // Have 1.23456, needs 1234.56
1887
- // Move the '.' exp positions to the right.
1888
- std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2);
1889
- }
1890
- exp = 0;
1891
- }
1892
- if (!conv.has_alt_flag()) {
1893
- while (buffer.back() == '0') buffer.pop_back();
1894
- if (buffer.back() == '.') buffer.pop_back();
1895
- }
1896
- if (exp) {
1897
- PrintExponent(
1898
- exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e',
1899
- &buffer);
2092
+ constexpr int input_bits = sizeof(decomposed.mantissa) * 8;
2093
+ const int total_bits =
2094
+ input_bits - LeadingZeros(decomposed.mantissa) + decomposed.exponent;
2095
+ if (decomposed.exponent >= 0 && total_bits > 128) {
2096
+ FormatGPositiveExpSlow(
2097
+ decomposed.mantissa, decomposed.exponent,
2098
+ FormatConversionCharIsUpper(conv.conversion_char()),
2099
+ {sign_char, precision, conv, sink});
2100
+ return true;
2101
+ } else if (decomposed.exponent < -128) {
2102
+ FormatGNegativeExpSlow(
2103
+ decomposed.mantissa, decomposed.exponent,
2104
+ FormatConversionCharIsUpper(conv.conversion_char()),
2105
+ {sign_char, precision, conv, sink});
2106
+ return true;
1900
2107
  }
2108
+ FormatGFast(decomposed.mantissa, decomposed.exponent,
2109
+ FormatConversionCharIsUpper(conv.conversion_char()),
2110
+ {sign_char, precision, conv, sink});
2111
+ return true;
1901
2112
  } else if (c == FormatConversionCharInternal::a ||
1902
2113
  c == FormatConversionCharInternal::A) {
1903
2114
  bool uppercase = (c == FormatConversionCharInternal::A);
@@ -1907,14 +2118,6 @@ bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv,
1907
2118
  } else {
1908
2119
  return false;
1909
2120
  }
1910
-
1911
- WriteBufferToSink(
1912
- sign_char,
1913
- absl::string_view(buffer.begin,
1914
- static_cast<size_t>(buffer.end - buffer.begin)),
1915
- conv, sink);
1916
-
1917
- return true;
1918
2121
  }
1919
2122
 
1920
2123
  } // namespace