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.
- package/LICENSE +15 -20
- package/README.md +63 -4
- package/binding.gyp +1 -2
- package/lib/addon.cc +9 -5
- package/lib/exec.cc +4 -4
- package/lib/match.cc +4 -4
- package/lib/new.cc +6 -6
- package/lib/pattern.cc +148 -1
- package/lib/replace.cc +5 -4
- package/lib/search.cc +1 -1
- package/lib/set.cc +85 -10
- package/lib/test.cc +1 -1
- package/lib/unicode_properties.h +15840 -0
- package/lib/wrapped_re2.h +40 -4
- package/lib/wrapped_re2_set.h +3 -1
- package/llms-full.txt +497 -0
- package/llms.txt +135 -0
- package/package.json +19 -11
- package/re2.d.ts +2 -0
- package/re2.js +1 -0
- package/vendor/abseil-cpp/CMake/AbseilDll.cmake +87 -74
- package/vendor/abseil-cpp/CMakeLists.txt +3 -3
- package/vendor/abseil-cpp/FAQ.md +130 -79
- package/vendor/abseil-cpp/MODULE.bazel +6 -7
- package/vendor/abseil-cpp/absl/BUILD.bazel +6 -0
- package/vendor/abseil-cpp/absl/algorithm/BUILD.bazel +4 -0
- package/vendor/abseil-cpp/absl/algorithm/CMakeLists.txt +4 -0
- package/vendor/abseil-cpp/absl/algorithm/algorithm.h +34 -2
- package/vendor/abseil-cpp/absl/algorithm/container.h +164 -17
- package/vendor/abseil-cpp/absl/algorithm/container_test.cc +390 -13
- package/vendor/abseil-cpp/absl/base/BUILD.bazel +53 -6
- package/vendor/abseil-cpp/absl/base/CMakeLists.txt +28 -4
- package/vendor/abseil-cpp/absl/base/attributes.h +61 -42
- package/vendor/abseil-cpp/absl/base/call_once.h +1 -0
- package/vendor/abseil-cpp/absl/base/casts.h +8 -1
- package/vendor/abseil-cpp/absl/base/casts_test.cc +3 -6
- package/vendor/abseil-cpp/absl/base/config.h +53 -9
- package/vendor/abseil-cpp/absl/base/exception_safety_testing_test.cc +9 -9
- package/vendor/abseil-cpp/absl/base/fast_type_id.h +30 -2
- package/vendor/abseil-cpp/absl/base/fast_type_id_test.cc +3 -0
- package/vendor/abseil-cpp/absl/base/internal/exception_safety_testing.h +15 -12
- package/vendor/abseil-cpp/absl/base/internal/hardening.h +136 -0
- package/vendor/abseil-cpp/absl/base/internal/hardening_test.cc +168 -0
- package/vendor/abseil-cpp/absl/base/internal/iterator_traits.h +2 -2
- package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -0
- package/vendor/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
- package/vendor/abseil-cpp/absl/base/internal/sysinfo.cc +1 -2
- package/vendor/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
- package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
- package/vendor/abseil-cpp/absl/base/macros.h +36 -20
- package/vendor/abseil-cpp/absl/base/nullability.h +4 -3
- package/vendor/abseil-cpp/absl/base/optimization.h +3 -2
- package/vendor/abseil-cpp/absl/base/optimization_test.cc +4 -3
- package/vendor/abseil-cpp/absl/base/options.h +55 -1
- package/vendor/abseil-cpp/absl/base/policy_checks.h +5 -5
- package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
- package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
- package/vendor/abseil-cpp/absl/base/throw_delegate_test.cc +19 -28
- package/vendor/abseil-cpp/absl/cleanup/BUILD.bazel +2 -0
- package/vendor/abseil-cpp/absl/cleanup/CMakeLists.txt +2 -0
- package/vendor/abseil-cpp/absl/cleanup/cleanup.h +3 -2
- package/vendor/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
- package/vendor/abseil-cpp/absl/container/BUILD.bazel +19 -7
- package/vendor/abseil-cpp/absl/container/CMakeLists.txt +6 -5
- package/vendor/abseil-cpp/absl/container/btree_benchmark.cc +3 -5
- package/vendor/abseil-cpp/absl/container/btree_set.h +5 -5
- package/vendor/abseil-cpp/absl/container/btree_test.cc +11 -14
- package/vendor/abseil-cpp/absl/container/chunked_queue.h +8 -6
- package/vendor/abseil-cpp/absl/container/chunked_queue_test.cc +5 -5
- package/vendor/abseil-cpp/absl/container/fixed_array.h +14 -13
- package/vendor/abseil-cpp/absl/container/fixed_array_test.cc +3 -3
- package/vendor/abseil-cpp/absl/container/flat_hash_map.h +18 -6
- package/vendor/abseil-cpp/absl/container/flat_hash_map_test.cc +34 -1
- package/vendor/abseil-cpp/absl/container/flat_hash_set.h +21 -7
- package/vendor/abseil-cpp/absl/container/flat_hash_set_test.cc +39 -7
- package/vendor/abseil-cpp/absl/container/inlined_vector.h +29 -29
- package/vendor/abseil-cpp/absl/container/inlined_vector_test.cc +2 -2
- package/vendor/abseil-cpp/absl/container/internal/btree.h +32 -24
- package/vendor/abseil-cpp/absl/container/internal/btree_container.h +16 -17
- package/vendor/abseil-cpp/absl/container/internal/common.h +6 -5
- package/vendor/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
- package/vendor/abseil-cpp/absl/container/internal/compressed_tuple.h +16 -16
- package/vendor/abseil-cpp/absl/container/internal/compressed_tuple_test.cc +13 -13
- package/vendor/abseil-cpp/absl/container/internal/container_memory.h +41 -31
- package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults.h +2 -2
- package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.h +4 -4
- package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits.h +3 -3
- package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +27 -19
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +2 -2
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.h +0 -17
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +12 -30
- package/vendor/abseil-cpp/absl/container/internal/inlined_vector.h +28 -28
- package/vendor/abseil-cpp/absl/container/internal/layout.h +13 -13
- package/vendor/abseil-cpp/absl/container/internal/layout_test.cc +3 -2
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_map.h +60 -62
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc +59 -39
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.h +619 -326
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc +25 -2
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc +4 -4
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +575 -159
- package/vendor/abseil-cpp/absl/container/linked_hash_map.h +2 -2
- package/vendor/abseil-cpp/absl/container/node_hash_map.h +27 -15
- package/vendor/abseil-cpp/absl/container/node_hash_map_test.cc +34 -0
- package/vendor/abseil-cpp/absl/container/node_hash_set.h +25 -11
- package/vendor/abseil-cpp/absl/container/node_hash_set_test.cc +39 -7
- package/vendor/abseil-cpp/absl/container/sample_element_size_test.cc +7 -4
- package/vendor/abseil-cpp/absl/crc/BUILD.bazel +0 -1
- package/vendor/abseil-cpp/absl/crc/CMakeLists.txt +2 -3
- package/vendor/abseil-cpp/absl/crc/crc32c_benchmark.cc +2 -1
- package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.cc +6 -6
- package/vendor/abseil-cpp/absl/crc/internal/crc.cc +4 -6
- package/vendor/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
- package/vendor/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
- package/vendor/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +143 -81
- package/vendor/abseil-cpp/absl/debugging/BUILD.bazel +9 -31
- package/vendor/abseil-cpp/absl/debugging/CMakeLists.txt +3 -33
- package/vendor/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
- package/vendor/abseil-cpp/absl/debugging/internal/demangle_test.cc +2 -1
- package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc +12 -2
- package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.h +2 -3
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +11 -0
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -4
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +4 -0
- package/vendor/abseil-cpp/absl/debugging/internal/symbolize.h +46 -36
- package/vendor/abseil-cpp/absl/debugging/stacktrace.cc +18 -58
- package/vendor/abseil-cpp/absl/debugging/stacktrace.h +5 -48
- package/vendor/abseil-cpp/absl/debugging/stacktrace_test.cc +10 -124
- package/vendor/abseil-cpp/absl/debugging/symbolize.cc +20 -2
- package/vendor/abseil-cpp/absl/debugging/symbolize_elf.inc +58 -106
- package/vendor/abseil-cpp/absl/debugging/symbolize_test.cc +37 -36
- package/vendor/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
- package/vendor/abseil-cpp/absl/flags/BUILD.bazel +6 -3
- package/vendor/abseil-cpp/absl/flags/CMakeLists.txt +1 -1
- package/vendor/abseil-cpp/absl/flags/commandlineflag.h +8 -6
- package/vendor/abseil-cpp/absl/flags/commandlineflag_test.cc +1 -1
- package/vendor/abseil-cpp/absl/flags/flag_benchmark.cc +5 -5
- package/vendor/abseil-cpp/absl/flags/flag_test.cc +30 -30
- package/vendor/abseil-cpp/absl/flags/internal/flag.cc +4 -4
- package/vendor/abseil-cpp/absl/flags/internal/flag.h +6 -6
- package/vendor/abseil-cpp/absl/flags/marshalling.h +2 -28
- package/vendor/abseil-cpp/absl/flags/marshalling_test.cc +12 -11
- package/vendor/abseil-cpp/absl/flags/reflection_test.cc +1 -1
- package/vendor/abseil-cpp/absl/functional/BUILD.bazel +26 -1
- package/vendor/abseil-cpp/absl/functional/CMakeLists.txt +29 -1
- package/vendor/abseil-cpp/absl/functional/any_invocable.h +13 -14
- package/vendor/abseil-cpp/absl/functional/any_invocable_test.cc +46 -47
- package/vendor/abseil-cpp/absl/functional/bind_back.h +79 -0
- package/vendor/abseil-cpp/absl/functional/bind_back_test.cc +237 -0
- package/vendor/abseil-cpp/absl/functional/bind_front.h +7 -1
- package/vendor/abseil-cpp/absl/functional/bind_front_test.cc +4 -4
- package/vendor/abseil-cpp/absl/functional/function_ref_test.cc +2 -2
- package/vendor/abseil-cpp/absl/functional/internal/any_invocable.h +28 -28
- package/vendor/abseil-cpp/absl/functional/internal/back_binder.h +95 -0
- package/vendor/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
- package/vendor/abseil-cpp/absl/functional/internal/function_ref.h +2 -2
- package/vendor/abseil-cpp/absl/functional/overload_test.cc +13 -13
- package/vendor/abseil-cpp/absl/hash/BUILD.bazel +1 -2
- package/vendor/abseil-cpp/absl/hash/CMakeLists.txt +1 -2
- package/vendor/abseil-cpp/absl/hash/hash.h +1 -1
- package/vendor/abseil-cpp/absl/hash/hash_test.cc +14 -20
- package/vendor/abseil-cpp/absl/hash/hash_testing.h +11 -9
- package/vendor/abseil-cpp/absl/hash/internal/city.cc +39 -51
- package/vendor/abseil-cpp/absl/hash/internal/hash.cc +165 -47
- package/vendor/abseil-cpp/absl/hash/internal/hash.h +86 -27
- package/vendor/abseil-cpp/absl/hash/internal/low_level_hash_test.cc +36 -1
- package/vendor/abseil-cpp/absl/hash/internal/spy_hash_state.h +8 -5
- package/vendor/abseil-cpp/absl/log/BUILD.bazel +5 -2
- package/vendor/abseil-cpp/absl/log/CMakeLists.txt +5 -3
- package/vendor/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
- package/vendor/abseil-cpp/absl/log/internal/BUILD.bazel +15 -1
- package/vendor/abseil-cpp/absl/log/internal/log_message.cc +5 -4
- package/vendor/abseil-cpp/absl/log/internal/log_message.h +14 -0
- package/vendor/abseil-cpp/absl/log/internal/nullstream.h +1 -1
- package/vendor/abseil-cpp/absl/log/internal/proto.cc +13 -0
- package/vendor/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
- package/vendor/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
- package/vendor/abseil-cpp/absl/log/internal/structured_proto_test.cc +3 -3
- package/vendor/abseil-cpp/absl/log/internal/vlog_config.cc +2 -2
- package/vendor/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc +3 -3
- package/vendor/abseil-cpp/absl/log/log_format_test.cc +19 -2
- package/vendor/abseil-cpp/absl/log/log_modifier_methods_test.cc +18 -0
- package/vendor/abseil-cpp/absl/log/log_streamer.h +29 -2
- package/vendor/abseil-cpp/absl/log/log_streamer_test.cc +18 -0
- package/vendor/abseil-cpp/absl/log/scoped_mock_log_test.cc +1 -1
- package/vendor/abseil-cpp/absl/log/vlog_is_on.h +0 -2
- package/vendor/abseil-cpp/absl/log/vlog_is_on_test.cc +6 -5
- package/vendor/abseil-cpp/absl/memory/memory.h +55 -5
- package/vendor/abseil-cpp/absl/memory/memory_test.cc +55 -1
- package/vendor/abseil-cpp/absl/meta/BUILD.bazel +2 -0
- package/vendor/abseil-cpp/absl/meta/internal/requires.h +1 -1
- package/vendor/abseil-cpp/absl/meta/type_traits.h +119 -55
- package/vendor/abseil-cpp/absl/meta/type_traits_test.cc +7 -7
- package/vendor/abseil-cpp/absl/numeric/int128_test.cc +6 -6
- package/vendor/abseil-cpp/absl/profiling/BUILD.bazel +3 -1
- package/vendor/abseil-cpp/absl/profiling/hashtable.cc +0 -4
- package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.cc +32 -33
- package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.h +25 -2
- package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc +8 -5
- package/vendor/abseil-cpp/absl/random/BUILD.bazel +13 -1
- package/vendor/abseil-cpp/absl/random/CMakeLists.txt +23 -2
- package/vendor/abseil-cpp/absl/random/benchmarks.cc +1 -1
- package/vendor/abseil-cpp/absl/random/beta_distribution.h +2 -2
- package/vendor/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
- package/vendor/abseil-cpp/absl/random/bit_gen_ref_test.cc +43 -0
- package/vendor/abseil-cpp/absl/random/discrete_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/random/distributions.h +17 -17
- package/vendor/abseil-cpp/absl/random/distributions_test.cc +4 -4
- package/vendor/abseil-cpp/absl/random/exponential_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/BUILD.bazel +4 -2
- package/vendor/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
- package/vendor/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/generate_real.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/mock_helpers.h +14 -40
- package/vendor/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/nonsecure_base_test.cc +2 -2
- package/vendor/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
- package/vendor/abseil-cpp/absl/random/internal/pcg_engine_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
- package/vendor/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_engine_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
- package/vendor/abseil-cpp/absl/random/internal/seed_material.cc +4 -4
- package/vendor/abseil-cpp/absl/random/internal/seed_material.h +2 -1
- package/vendor/abseil-cpp/absl/random/internal/traits.h +21 -0
- package/vendor/abseil-cpp/absl/random/internal/traits_test.cc +5 -0
- package/vendor/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
- package/vendor/abseil-cpp/absl/random/internal/uniform_helper_test.cc +2 -1
- package/vendor/abseil-cpp/absl/random/mocking_access.h +74 -0
- package/vendor/abseil-cpp/absl/random/mocking_bit_gen.h +9 -19
- package/vendor/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/status/BUILD.bazel +81 -0
- package/vendor/abseil-cpp/absl/status/CMakeLists.txt +91 -0
- package/vendor/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
- package/vendor/abseil-cpp/absl/status/internal/status_internal.h +26 -2
- package/vendor/abseil-cpp/absl/status/internal/status_matchers.h +22 -8
- package/vendor/abseil-cpp/absl/status/internal/statusor_internal.h +43 -43
- package/vendor/abseil-cpp/absl/status/status.cc +62 -70
- package/vendor/abseil-cpp/absl/status/status.h +249 -23
- package/vendor/abseil-cpp/absl/status/status_benchmark.cc +12 -0
- package/vendor/abseil-cpp/absl/status/status_builder.cc +196 -0
- package/vendor/abseil-cpp/absl/status/status_builder.h +978 -0
- package/vendor/abseil-cpp/absl/status/status_builder_test.cc +380 -0
- package/vendor/abseil-cpp/absl/status/status_macros.h +484 -0
- package/vendor/abseil-cpp/absl/status/status_macros_test.cc +634 -0
- package/vendor/abseil-cpp/absl/status/status_matchers.h +2 -1
- package/vendor/abseil-cpp/absl/status/status_matchers_test.cc +3 -4
- package/vendor/abseil-cpp/absl/status/status_payload_printer.h +3 -2
- package/vendor/abseil-cpp/absl/status/status_test.cc +443 -13
- package/vendor/abseil-cpp/absl/status/statusor.h +69 -36
- package/vendor/abseil-cpp/absl/status/statusor_test.cc +132 -35
- package/vendor/abseil-cpp/absl/strings/BUILD.bazel +42 -7
- package/vendor/abseil-cpp/absl/strings/CMakeLists.txt +33 -4
- package/vendor/abseil-cpp/absl/strings/ascii.h +1 -2
- package/vendor/abseil-cpp/absl/strings/atod_manual_test.cc +5 -5
- package/vendor/abseil-cpp/absl/strings/cord.cc +26 -7
- package/vendor/abseil-cpp/absl/strings/cord.h +23 -13
- package/vendor/abseil-cpp/absl/strings/cord_buffer.h +4 -2
- package/vendor/abseil-cpp/absl/strings/cord_test.cc +85 -9
- package/vendor/abseil-cpp/absl/strings/escaping.cc +183 -35
- package/vendor/abseil-cpp/absl/strings/escaping.h +12 -2
- package/vendor/abseil-cpp/absl/strings/escaping_benchmark.cc +1 -3
- package/vendor/abseil-cpp/absl/strings/escaping_test.cc +22 -18
- package/vendor/abseil-cpp/absl/strings/has_absl_stringify_test.cc +2 -2
- package/vendor/abseil-cpp/absl/strings/has_ostream_operator_test.cc +2 -2
- package/vendor/abseil-cpp/absl/strings/internal/append_and_overwrite.h +10 -10
- package/vendor/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc +1 -1
- package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
- package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
- package/vendor/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
- package/vendor/abseil-cpp/absl/strings/internal/escaping.h +2 -26
- package/vendor/abseil-cpp/absl/strings/internal/generic_printer_internal.h +23 -2
- package/vendor/abseil-cpp/absl/strings/internal/generic_printer_test.cc +6 -2
- package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -24
- package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc +16 -41
- package/vendor/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
- package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
- package/vendor/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
- package/vendor/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +12 -20
- package/vendor/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +510 -307
- package/vendor/abseil-cpp/absl/strings/internal/str_join_internal.h +0 -1
- package/vendor/abseil-cpp/absl/strings/internal/str_split_internal.h +9 -10
- package/vendor/abseil-cpp/absl/strings/internal/string_constant_test.cc +6 -5
- package/vendor/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
- package/vendor/abseil-cpp/absl/strings/internal/stringify_stream.h +119 -0
- package/vendor/abseil-cpp/absl/strings/internal/stringify_stream_test.cc +111 -0
- package/vendor/abseil-cpp/absl/strings/numbers.cc +406 -0
- package/vendor/abseil-cpp/absl/strings/numbers.h +4 -0
- package/vendor/abseil-cpp/absl/strings/numbers_test.cc +33 -0
- package/vendor/abseil-cpp/absl/strings/resize_and_overwrite.h +10 -6
- package/vendor/abseil-cpp/absl/strings/str_cat.h +36 -1
- package/vendor/abseil-cpp/absl/strings/str_cat_benchmark.cc +1 -2
- package/vendor/abseil-cpp/absl/strings/str_cat_test.cc +28 -0
- package/vendor/abseil-cpp/absl/strings/str_join_test.cc +4 -4
- package/vendor/abseil-cpp/absl/strings/str_split.h +11 -6
- package/vendor/abseil-cpp/absl/strings/str_split_test.cc +13 -0
- package/vendor/abseil-cpp/absl/strings/substitute.h +2 -2
- package/vendor/abseil-cpp/absl/synchronization/BUILD.bazel +3 -0
- package/vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +21 -0
- package/vendor/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
- package/vendor/abseil-cpp/absl/synchronization/mutex.cc +13 -0
- package/vendor/abseil-cpp/absl/synchronization/mutex.h +32 -2
- package/vendor/abseil-cpp/absl/synchronization/mutex_test.cc +17 -3
- package/vendor/abseil-cpp/absl/time/BUILD.bazel +80 -0
- package/vendor/abseil-cpp/absl/time/CMakeLists.txt +73 -0
- package/vendor/abseil-cpp/absl/time/clock.h +3 -0
- package/vendor/abseil-cpp/absl/time/clock_interface.cc +71 -0
- package/vendor/abseil-cpp/absl/time/clock_interface.h +93 -0
- package/vendor/abseil-cpp/absl/time/clock_interface_test.cc +128 -0
- package/vendor/abseil-cpp/absl/time/format.cc +3 -10
- package/vendor/abseil-cpp/absl/time/format_test.cc +12 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +90 -89
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +80 -5
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +1 -2
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/version +1 -1
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +1 -1
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab +3 -3
- package/vendor/abseil-cpp/absl/time/simulated_clock.cc +225 -0
- package/vendor/abseil-cpp/absl/time/simulated_clock.h +109 -0
- package/vendor/abseil-cpp/absl/time/simulated_clock_test.cc +614 -0
- package/vendor/abseil-cpp/absl/types/BUILD.bazel +116 -0
- package/vendor/abseil-cpp/absl/types/CMakeLists.txt +100 -0
- package/vendor/abseil-cpp/absl/types/any.h +26 -4
- package/vendor/abseil-cpp/absl/types/any_span.h +1067 -0
- package/vendor/abseil-cpp/absl/types/any_span_benchmark.cc +258 -0
- package/vendor/abseil-cpp/absl/types/any_span_test.cc +1210 -0
- package/vendor/abseil-cpp/absl/types/compare.h +4 -4
- package/vendor/abseil-cpp/absl/types/internal/any_span.h +477 -0
- package/vendor/abseil-cpp/absl/types/internal/span.h +5 -6
- package/vendor/abseil-cpp/absl/types/optional.h +30 -3
- package/vendor/abseil-cpp/absl/types/optional_ref.h +295 -0
- package/vendor/abseil-cpp/absl/types/optional_ref_test.cc +370 -0
- package/vendor/abseil-cpp/absl/types/source_location.cc +18 -0
- package/vendor/abseil-cpp/absl/types/source_location.h +172 -0
- package/vendor/abseil-cpp/absl/types/source_location_test.cc +139 -0
- package/vendor/abseil-cpp/absl/types/span.h +19 -23
- package/vendor/abseil-cpp/absl/types/variant.h +75 -18
- package/vendor/abseil-cpp/absl/types/variant_test.cc +23 -23
- package/vendor/abseil-cpp/absl/utility/BUILD.bazel +1 -0
- package/vendor/abseil-cpp/absl/utility/CMakeLists.txt +1 -0
- package/vendor/abseil-cpp/absl/utility/utility.h +99 -16
- package/vendor/abseil-cpp/ci/absl_alternate_options.h +2 -0
- package/vendor/abseil-cpp/ci/linux_arm_clang-latest_libcxx_bazel.sh +10 -4
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_asan_bazel.sh +13 -6
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_bazel.sh +10 -4
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_tsan_bazel.sh +12 -5
- package/vendor/abseil-cpp/ci/linux_clang-latest_libstdcxx_bazel.sh +9 -2
- package/vendor/abseil-cpp/ci/linux_docker_containers.sh +4 -4
- package/vendor/abseil-cpp/ci/linux_gcc-floor_libstdcxx_bazel.sh +10 -3
- package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +8 -2
- package/vendor/abseil-cpp/ci/macos_xcode_bazel.sh +4 -3
- package/vendor/abseil-cpp/ci/macos_xcode_cmake.sh +2 -2
- package/vendor/abseil-cpp/ci/windows_clangcl_bazel.bat +1 -1
- package/vendor/abseil-cpp/ci/windows_msvc_bazel.bat +1 -1
- package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.cc +0 -118
- package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.h +0 -71
- 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 =
|
|
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
|
-
|
|
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
|
-
(
|
|
271
|
+
ChunksNeeded(margin - Limits::min_exponent),
|
|
263
272
|
"");
|
|
264
273
|
StackArray::RunWithCapacity(
|
|
265
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 + (
|
|
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
|
-
|
|
1189
|
-
|
|
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
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
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
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
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
|
-
|
|
1307
|
-
|
|
1308
|
-
if (
|
|
1309
|
-
|
|
1310
|
-
|
|
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
|
-
|
|
1342
|
-
|
|
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
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
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
|
-
|
|
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 >=
|
|
1465
|
+
if (nines >= precision || state.precision == 0) {
|
|
1603
1466
|
bool round_up = false;
|
|
1604
|
-
if (nines ==
|
|
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
|
|
1628
|
-
+
|
|
1629
|
-
|
|
1630
|
-
|
|
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.
|
|
1507
|
+
if (precision > 0 || state.conv.has_alt_flag()) {
|
|
1643
1508
|
state.sink->Append(1, '.');
|
|
1644
1509
|
}
|
|
1645
|
-
size_t digits_to_go =
|
|
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
|
|
1768
|
-
|
|
1769
|
-
|
|
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 (
|
|
1610
|
+
if (print_dot) {
|
|
1781
1611
|
state.sink->Append(1, '.');
|
|
1782
1612
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
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
|
-
|
|
1792
|
-
|
|
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
|
-
|
|
1807
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
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
|